From 98a51b77944a3a0ca1a3ac07e4c9339218ce4bb6 Mon Sep 17 00:00:00 2001 From: Axel Davy Date: Thu, 21 Jul 2022 18:45:25 +0200 Subject: [PATCH] frontend/nine: Implement backup support for pointsize Improve support for drivers that don't support the pointsize states. Acked-by: Mike Blumenkrantz Signed-off-by: Axel Davy Part-of: --- src/gallium/frontends/nine/device9.c | 12 +++++++++++- src/gallium/frontends/nine/device9.h | 1 + src/gallium/frontends/nine/nine_ff.c | 6 +++--- src/gallium/frontends/nine/nine_shader.c | 16 ++++++++++++---- src/gallium/frontends/nine/nine_state.c | 20 ++++++++++++++++++++ src/gallium/frontends/nine/nine_state.h | 5 ++++- 6 files changed, 51 insertions(+), 9 deletions(-) diff --git a/src/gallium/frontends/nine/device9.c b/src/gallium/frontends/nine/device9.c index cdc12c84226..f615e938ae7 100644 --- a/src/gallium/frontends/nine/device9.c +++ b/src/gallium/frontends/nine/device9.c @@ -451,7 +451,10 @@ NineDevice9_ctor( struct NineDevice9 *This, /* ps 3.0: 224 float constants. All cards supported support at least * 256 constants for ps */ - This->max_vs_const_f = max_const_vs - + if (max_const_vs == NINE_MAX_CONST_ALL_VS) + This->max_vs_const_f = NINE_MAX_CONST_F; + else /* Do not count SPE constants as we won't use them */ + This->max_vs_const_f = max_const_vs - (NINE_MAX_CONST_I + NINE_MAX_CONST_B / 4); This->vs_const_size = max_const_vs * sizeof(float[4]); @@ -556,6 +559,13 @@ NineDevice9_ctor( struct NineDevice9 *This, This->driver_caps.ps_integer = pScreen->get_shader_param(pScreen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_INTEGERS); This->driver_caps.offset_units_unscaled = GET_PCAP(POLYGON_OFFSET_UNITS_UNSCALED); This->driver_caps.alpha_test_emulation = !GET_PCAP(ALPHA_TEST); + /* Always write pointsize output when the driver doesn't support point_size_per_vertex = 0. + * TODO: Only generate pointsize for draw calls that need it */ + This->driver_caps.always_output_pointsize = !GET_PCAP(POINT_SIZE_FIXED); + + /* Disable SPE constants if there is no room for them */ + if (This->max_vs_const_f != NINE_MAX_CONST_F) + This->driver_caps.always_output_pointsize = false; This->context.inline_constants = pCTX->shader_inline_constants; /* Code would be needed when integers are not available to correctly diff --git a/src/gallium/frontends/nine/device9.h b/src/gallium/frontends/nine/device9.h index 326119eff1f..2ddeff78547 100644 --- a/src/gallium/frontends/nine/device9.h +++ b/src/gallium/frontends/nine/device9.h @@ -133,6 +133,7 @@ struct NineDevice9 boolean ps_integer; boolean offset_units_unscaled; boolean alpha_test_emulation; + boolean always_output_pointsize; } driver_caps; struct { diff --git a/src/gallium/frontends/nine/nine_ff.c b/src/gallium/frontends/nine/nine_ff.c index 52f5a24e9f3..682c1e7fd9d 100644 --- a/src/gallium/frontends/nine/nine_ff.c +++ b/src/gallium/frontends/nine/nine_ff.c @@ -427,7 +427,7 @@ nine_ff_build_vs(struct NineDevice9 *device, struct vs_build_ctx *vs) oFog = ureg_writemask(oFog, TGSI_WRITEMASK_X); } - if (key->vertexpointsize || key->pointscale) { + if (key->vertexpointsize || key->pointscale || device->driver_caps.always_output_pointsize) { oPsz = ureg_DECL_output_masked(ureg, TGSI_SEMANTIC_PSIZE, 0, TGSI_WRITEMASK_X, 0, 1); oPsz = ureg_writemask(oPsz, TGSI_WRITEMASK_X); @@ -588,7 +588,7 @@ nine_ff_build_vs(struct NineDevice9 *device, struct vs_build_ctx *vs) /* === Process point size: */ - if (key->vertexpointsize || key->pointscale) { + if (key->vertexpointsize || key->pointscale || device->driver_caps.always_output_pointsize) { struct ureg_dst tmp = ureg_DECL_temporary(ureg); struct ureg_dst tmp_x = ureg_writemask(tmp, TGSI_WRITEMASK_X); struct ureg_dst tmp_y = ureg_writemask(tmp, TGSI_WRITEMASK_Y); @@ -1720,7 +1720,7 @@ nine_ff_get_vs(struct NineDevice9 *device) vs->input_map[n].ndecl = bld.input[n]; vs->position_t = key.position_t; - vs->point_size = key.vertexpointsize | key.pointscale; + vs->point_size = key.vertexpointsize | key.pointscale | device->driver_caps.always_output_pointsize; } return vs; } diff --git a/src/gallium/frontends/nine/nine_shader.c b/src/gallium/frontends/nine/nine_shader.c index e3b5e6069c9..508007caf53 100644 --- a/src/gallium/frontends/nine/nine_shader.c +++ b/src/gallium/frontends/nine/nine_shader.c @@ -456,6 +456,7 @@ struct shader_translator boolean wpos_is_sysval; boolean face_is_sysval_integer; boolean mul_zero_wins; + boolean always_output_pointsize; unsigned texcoord_sn; struct sm1_instruction insn; /* current instruction */ @@ -644,15 +645,16 @@ static struct ureg_src nine_special_constant_src(struct shader_translator *tx, i { struct ureg_src src; - unsigned slot_idx = idx + NINE_MAX_CONST_PS_SPE_OFFSET; + unsigned slot_idx = idx + (IS_PS ? NINE_MAX_CONST_PS_SPE_OFFSET : + (tx->info->swvp_on ? NINE_MAX_CONST_SWVP_SPE_OFFSET : NINE_MAX_CONST_VS_SPE_OFFSET)); - assert(!tx->info->swvp_on); /* Only used for ps currently */ - if (tx->slot_map) + if (!tx->info->swvp_on && tx->slot_map) slot_idx = tx->slot_map[slot_idx]; src = ureg_src_register(TGSI_FILE_CONSTANT, slot_idx); src = ureg_src_dimension(src, 0); - tx->slots_used[slot_idx] = TRUE; + if (!tx->info->swvp_on) + tx->slots_used[slot_idx] = TRUE; if (tx->num_slots < (slot_idx + 1)) tx->num_slots = slot_idx + 1; @@ -3878,6 +3880,10 @@ static void parse_shader(struct shader_translator *tx) ureg_MAX(tx->ureg, ureg_writemask(tx->regs.oPts, TGSI_WRITEMASK_X), ureg_src(tx->regs.oPts), ureg_imm1f(tx->ureg, info->point_size_min)); ureg_MIN(tx->ureg, ureg_writemask(oPts, TGSI_WRITEMASK_X), ureg_src(tx->regs.oPts), ureg_imm1f(tx->ureg, info->point_size_max)); info->point_size = TRUE; + } else if (IS_VS && tx->always_output_pointsize) { + struct ureg_dst oPts = ureg_DECL_output(tx->ureg, TGSI_SEMANTIC_PSIZE, 0); + ureg_MOV(tx->ureg, ureg_writemask(oPts, TGSI_WRITEMASK_X), nine_special_constant_src(tx, 0)); + info->point_size = TRUE; } if (info->process_vertices) @@ -4022,6 +4028,7 @@ nine_translate_shader(struct NineDevice9 *device, struct nine_shader_info *info, hr = E_OUTOFMEMORY; goto out; } + tx->always_output_pointsize = device->driver_caps.always_output_pointsize; assert(IS_VS || !info->swvp_on); @@ -4100,6 +4107,7 @@ nine_translate_shader(struct NineDevice9 *device, struct nine_shader_info *info, hr = E_OUTOFMEMORY; goto out; } + tx->always_output_pointsize = device->driver_caps.always_output_pointsize; tx->slot_map = slot_map; parse_shader(tx); assert(!tx->failure); diff --git a/src/gallium/frontends/nine/nine_state.c b/src/gallium/frontends/nine/nine_state.c index 9dccad435d8..369da96947d 100644 --- a/src/gallium/frontends/nine/nine_state.c +++ b/src/gallium/frontends/nine/nine_state.c @@ -389,6 +389,14 @@ prepare_vs_constants_userbuf_swvp(struct NineDevice9 *device) { struct nine_context *context = &device->context; + if (device->driver_caps.always_output_pointsize) { + context->vs_const_f[4 * NINE_MAX_CONST_SWVP_SPE_OFFSET] = + CLAMP(asfloat(context->rs[D3DRS_POINTSIZE]), + asfloat(context->rs[D3DRS_POINTSIZE_MIN]), + asfloat(context->rs[D3DRS_POINTSIZE_MAX])); + context->changed.vs_const_f = 1; /* TODO optimize */ + } + if (context->changed.vs_const_f || context->changed.group & NINE_STATE_SWVP) { struct pipe_constant_buffer cb; @@ -471,6 +479,13 @@ prepare_vs_constants_userbuf(struct NineDevice9 *device) return; } + if (device->driver_caps.always_output_pointsize) { + context->vs_const_f[4 * NINE_MAX_CONST_VS_SPE_OFFSET] = + CLAMP(asfloat(context->rs[D3DRS_POINTSIZE]), + asfloat(context->rs[D3DRS_POINTSIZE_MIN]), + asfloat(context->rs[D3DRS_POINTSIZE_MAX])); + } + if (context->changed.vs_const_i || context->changed.group & NINE_STATE_SWVP) { int *idst = (int *)&context->vs_const_f[4 * device->max_vs_const_f]; memcpy(idst, context->vs_const_i, NINE_MAX_CONST_I * sizeof(int[4])); @@ -1448,6 +1463,11 @@ CSMT_ITEM_NO_WAIT(nine_context_set_render_state, if (State == D3DRS_ALPHAREF) context->changed.group |= NINE_STATE_PS_CONST | NINE_STATE_FF_PS_CONSTS; } + + if (device->driver_caps.always_output_pointsize) { + if (State == D3DRS_POINTSIZE || State == D3DRS_POINTSIZE_MIN || State == D3DRS_POINTSIZE_MAX) + context->changed.group |= NINE_STATE_VS_CONST; + } } CSMT_ITEM_NO_WAIT(nine_context_set_texture_apply, diff --git a/src/gallium/frontends/nine/nine_state.h b/src/gallium/frontends/nine/nine_state.h index fd8bf4e8df2..cfaae430ec2 100644 --- a/src/gallium/frontends/nine/nine_state.h +++ b/src/gallium/frontends/nine/nine_state.h @@ -112,7 +112,10 @@ #define NINE_MAX_CONST_F_SWVP 8192 #define NINE_MAX_CONST_I_SWVP 2048 #define NINE_MAX_CONST_B_SWVP 2048 -#define NINE_MAX_CONST_ALL_VS 276 /* B consts count only 1/4 th */ +#define NINE_MAX_CONST_VS_SPE_OFFSET (NINE_MAX_CONST_F + (NINE_MAX_CONST_I + NINE_MAX_CONST_B / 4)) /* B consts count only 1/4 th */ +#define NINE_MAX_CONST_SWVP_SPE_OFFSET 3564 /* No app will read that far */ +#define NINE_MAX_CONST_VS_SPE 1 +#define NINE_MAX_CONST_ALL_VS (NINE_MAX_CONST_VS_SPE_OFFSET + NINE_MAX_CONST_VS_SPE) #define NINE_MAX_CONST_PS_SPE_OFFSET (NINE_MAX_CONST_F_PS3 + (NINE_MAX_CONST_I + NINE_MAX_CONST_B / 4)) /* bumpmap_vars (12), fog (2), D3DRS_ALPHAREF (1) */ #define NINE_MAX_CONST_PS_SPE 15