|
23 | 23 | #include "hw/xbox/nv2a/nv2a_int.h"
|
24 | 24 | #include "debug.h"
|
25 | 25 | #include "renderer.h"
|
| 26 | +#include <math.h> |
26 | 27 |
|
27 | 28 | void pgraph_gl_clear_surface(NV2AState *d, uint32_t parameter)
|
28 | 29 | {
|
@@ -131,6 +132,32 @@ void pgraph_gl_clear_surface(NV2AState *d, uint32_t parameter)
|
131 | 132 | pg->clearing = false;
|
132 | 133 | }
|
133 | 134 |
|
| 135 | +static float clamp_line_width_to_device_limits(PGRAPHState *pg, float width, |
| 136 | + bool smooth) |
| 137 | +{ |
| 138 | + PGRAPHGLState *r = pg->gl_renderer_state; |
| 139 | + float min_width; |
| 140 | + float max_width; |
| 141 | + float granularity; |
| 142 | + |
| 143 | + if (smooth) { |
| 144 | + min_width = r->limits.smooth_line_width.range[0]; |
| 145 | + max_width = r->limits.smooth_line_width.range[1]; |
| 146 | + granularity = r->limits.smooth_line_width.granularity; |
| 147 | + } else { |
| 148 | + min_width = r->limits.aliased_line_width.range[0]; |
| 149 | + max_width = r->limits.aliased_line_width.range[1]; |
| 150 | + granularity = r->limits.aliased_line_width.granularity; |
| 151 | + } |
| 152 | + |
| 153 | + if (granularity != 0.0f) { |
| 154 | + float steps = roundf((width - min_width) / granularity); |
| 155 | + width = min_width + steps * granularity; |
| 156 | + } |
| 157 | + |
| 158 | + return fminf(fmaxf(min_width, width), max_width); |
| 159 | +} |
| 160 | + |
134 | 161 | void pgraph_gl_draw_begin(NV2AState *d)
|
135 | 162 | {
|
136 | 163 | PGRAPHState *pg = &d->pgraph;
|
@@ -310,13 +337,14 @@ void pgraph_gl_draw_begin(NV2AState *d)
|
310 | 337 | bool anti_aliasing = GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_ANTIALIASING), NV_PGRAPH_ANTIALIASING_ENABLE);
|
311 | 338 |
|
312 | 339 | /* Edge Antialiasing */
|
| 340 | + float line_width = pgraph_get_line_width(pg) * pg->surface_scale_factor; |
313 | 341 | if (!anti_aliasing && pgraph_reg_r(pg, NV_PGRAPH_SETUPRASTER) &
|
314 | 342 | NV_PGRAPH_SETUPRASTER_LINESMOOTHENABLE) {
|
315 | 343 | glEnable(GL_LINE_SMOOTH);
|
316 |
| - glLineWidth(MIN(r->supported_smooth_line_width_range[1], pg->surface_scale_factor)); |
| 344 | + glLineWidth(clamp_line_width_to_device_limits(pg, line_width, true)); |
317 | 345 | } else {
|
318 | 346 | glDisable(GL_LINE_SMOOTH);
|
319 |
| - glLineWidth(MIN(r->supported_aliased_line_width_range[1], pg->surface_scale_factor)); |
| 347 | + glLineWidth(clamp_line_width_to_device_limits(pg, line_width, false)); |
320 | 348 | }
|
321 | 349 | if (!anti_aliasing && pgraph_reg_r(pg, NV_PGRAPH_SETUPRASTER) &
|
322 | 350 | NV_PGRAPH_SETUPRASTER_POLYSMOOTHENABLE) {
|
|
0 commit comments