Skip to content

Commit 92d2e9e

Browse files
committed
nv2a: Implement SET_LINE_WIDTH
1 parent a242964 commit 92d2e9e

File tree

8 files changed

+68
-16
lines changed

8 files changed

+68
-16
lines changed

hw/xbox/nv2a/nv2a_regs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,7 @@
503503
# define NV_PGRAPH_SETUPRASTER_POINTSMOOTHENABLE (1 << 9)
504504
# define NV_PGRAPH_SETUPRASTER_LINESMOOTHENABLE (1 << 10)
505505
# define NV_PGRAPH_SETUPRASTER_POLYSMOOTHENABLE (1 << 11)
506+
# define NV_PGRAPH_SETUPRASTER_LINEWIDTH 0x001ff000
506507
# define NV_PGRAPH_SETUPRASTER_CULLCTRL 0x00600000
507508
# define NV_PGRAPH_SETUPRASTER_CULLCTRL_FRONT 1
508509
# define NV_PGRAPH_SETUPRASTER_CULLCTRL_BACK 2
@@ -1009,6 +1010,7 @@
10091010
# define NV097_SET_SHADE_MODE 0x0000037C
10101011
# define NV097_SET_SHADE_MODE_V_FLAT 0x1D00
10111012
# define NV097_SET_SHADE_MODE_V_SMOOTH 0x1D01
1013+
# define NV097_SET_LINE_WIDTH 0x00000380
10121014
# define NV097_SET_POLYGON_OFFSET_SCALE_FACTOR 0x00000384
10131015
# define NV097_SET_POLYGON_OFFSET_BIAS 0x00000388
10141016
# define NV097_SET_FRONT_POLYGON_MODE 0x0000038C

hw/xbox/nv2a/pgraph/gl/draw.c

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "hw/xbox/nv2a/nv2a_int.h"
2424
#include "debug.h"
2525
#include "renderer.h"
26+
#include <math.h>
2627

2728
void pgraph_gl_clear_surface(NV2AState *d, uint32_t parameter)
2829
{
@@ -131,6 +132,32 @@ void pgraph_gl_clear_surface(NV2AState *d, uint32_t parameter)
131132
pg->clearing = false;
132133
}
133134

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+
134161
void pgraph_gl_draw_begin(NV2AState *d)
135162
{
136163
PGRAPHState *pg = &d->pgraph;
@@ -310,13 +337,14 @@ void pgraph_gl_draw_begin(NV2AState *d)
310337
bool anti_aliasing = GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_ANTIALIASING), NV_PGRAPH_ANTIALIASING_ENABLE);
311338

312339
/* Edge Antialiasing */
340+
float line_width = pgraph_get_line_width(pg) * pg->surface_scale_factor;
313341
if (!anti_aliasing && pgraph_reg_r(pg, NV_PGRAPH_SETUPRASTER) &
314342
NV_PGRAPH_SETUPRASTER_LINESMOOTHENABLE) {
315343
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));
317345
} else {
318346
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));
320348
}
321349
if (!anti_aliasing && pgraph_reg_r(pg, NV_PGRAPH_SETUPRASTER) &
322350
NV_PGRAPH_SETUPRASTER_POLYSMOOTHENABLE) {

hw/xbox/nv2a/pgraph/gl/renderer.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,12 @@ static void pgraph_gl_init(NV2AState *d, Error **errp)
5252
/* Internal RGB565 texture format */
5353
assert(glo_check_extension("GL_ARB_ES2_compatibility"));
5454

55-
glGetFloatv(GL_SMOOTH_LINE_WIDTH_RANGE, r->supported_smooth_line_width_range);
56-
glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, r->supported_aliased_line_width_range);
55+
glGetFloatv(GL_SMOOTH_LINE_WIDTH_RANGE, r->limits.smooth_line_width.range);
56+
glGetFloatv(GL_SMOOTH_LINE_WIDTH_GRANULARITY,
57+
&r->limits.smooth_line_width.granularity);
58+
glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE,
59+
r->limits.aliased_line_width.range);
60+
r->limits.aliased_line_width.granularity = 1.0;
5761

5862
pgraph_gl_init_surfaces(pg);
5963
pgraph_gl_init_reports(d);

hw/xbox/nv2a/pgraph/gl/renderer.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,8 +234,12 @@ typedef struct PGRAPHGLState {
234234
GLint palette_loc[256];
235235
} disp_rndr;
236236

237-
GLfloat supported_aliased_line_width_range[2];
238-
GLfloat supported_smooth_line_width_range[2];
237+
struct {
238+
struct {
239+
float range[2];
240+
float granularity;
241+
} smooth_line_width, aliased_line_width;
242+
} limits;
239243
} PGRAPHGLState;
240244

241245
extern GloContext *g_nv2a_context_render;

hw/xbox/nv2a/pgraph/methods.h.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ DEF_METHOD(NV097, SET_STENCIL_OP_FAIL)
6868
DEF_METHOD(NV097, SET_STENCIL_OP_ZFAIL)
6969
DEF_METHOD(NV097, SET_STENCIL_OP_ZPASS)
7070
DEF_METHOD(NV097, SET_SHADE_MODE)
71+
DEF_METHOD(NV097, SET_LINE_WIDTH)
7172
DEF_METHOD(NV097, SET_POLYGON_OFFSET_SCALE_FACTOR)
7273
DEF_METHOD(NV097, SET_POLYGON_OFFSET_BIAS)
7374
DEF_METHOD(NV097, SET_FRONT_POLYGON_MODE)

hw/xbox/nv2a/pgraph/pgraph.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,6 @@
2828
#include "swizzle.h"
2929
#include "nv2a_vsh_emulator.h"
3030

31-
#define PG_GET_MASK(reg, mask) GET_MASK(pgraph_reg_r(pg, reg), mask)
32-
#define PG_SET_MASK(reg, mask, value) \
33-
do { \
34-
uint32_t rv = pgraph_reg_r(pg, reg); \
35-
SET_MASK(rv, mask, value); \
36-
pgraph_reg_w(pg, reg, rv); \
37-
} while (0)
38-
39-
4031
NV2AState *g_nv2a;
4132

4233
uint64_t pgraph_read(void *opaque, hwaddr addr, unsigned int size)
@@ -1532,6 +1523,12 @@ DEF_METHOD(NV097, SET_SHADE_MODE)
15321523
}
15331524
}
15341525

1526+
DEF_METHOD(NV097, SET_LINE_WIDTH)
1527+
{
1528+
PG_SET_MASK(NV_PGRAPH_SETUPRASTER, NV_PGRAPH_SETUPRASTER_LINEWIDTH,
1529+
parameter);
1530+
}
1531+
15351532
DEF_METHOD(NV097, SET_POLYGON_OFFSET_SCALE_FACTOR)
15361533
{
15371534
pgraph_reg_w(pg, NV_PGRAPH_ZOFFSETFACTOR, parameter);

hw/xbox/nv2a/pgraph/pgraph.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,14 @@ static inline void pgraph_reg_w(PGRAPHState *pg, unsigned int r, uint32_t v)
297297
pg->regs_[r] = v;
298298
}
299299

300+
#define PG_GET_MASK(reg, mask) GET_MASK(pgraph_reg_r(pg, reg), mask)
301+
#define PG_SET_MASK(reg, mask, value) \
302+
do { \
303+
uint32_t rv = pgraph_reg_r(pg, reg); \
304+
SET_MASK(rv, mask, value); \
305+
pgraph_reg_w(pg, reg, rv); \
306+
} while (0)
307+
300308
void pgraph_clear_dirty_reg_map(PGRAPHState *pg);
301309

302310
static inline bool pgraph_is_reg_dirty(PGRAPHState *pg, unsigned int reg)
@@ -369,6 +377,13 @@ static inline void pgraph_apply_scaling_factor(PGRAPHState *pg,
369377
*height *= pg->surface_scale_factor;
370378
}
371379

380+
static inline float pgraph_get_line_width(PGRAPHState *pg)
381+
{
382+
uint32_t line_width =
383+
PG_GET_MASK(NV_PGRAPH_SETUPRASTER, NV_PGRAPH_SETUPRASTER_LINEWIDTH);
384+
return line_width / 8.0f; /* 6.3 format */
385+
}
386+
372387
void pgraph_get_clear_color(PGRAPHState *pg, float rgba[4]);
373388
void pgraph_get_clear_depth_stencil_value(PGRAPHState *pg, float *depth, int *stencil);
374389

hw/xbox/nv2a/pgraph/vk/draw.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1521,7 +1521,8 @@ static void begin_draw(PGRAPHState *pg)
15211521

15221522
if (r->pipeline_binding->has_dynamic_line_width) {
15231523
float line_width =
1524-
clamp_line_width_to_device_limits(pg, pg->surface_scale_factor);
1524+
pgraph_get_line_width(pg) * pg->surface_scale_factor;
1525+
line_width = clamp_line_width_to_device_limits(pg, line_width);
15251526
vkCmdSetLineWidth(r->command_buffer, line_width);
15261527
}
15271528
}

0 commit comments

Comments
 (0)