diff --git a/src/gallium/drivers/radeonsi/si_nir_lower_abi.c b/src/gallium/drivers/radeonsi/si_nir_lower_abi.c index bc180e4f40b..4e2ad8ed059 100644 --- a/src/gallium/drivers/radeonsi/si_nir_lower_abi.c +++ b/src/gallium/drivers/radeonsi/si_nir_lower_abi.c @@ -466,11 +466,16 @@ static bool lower_intrinsic(nir_builder *b, nir_instr *instr, struct lower_abi_s } break; case nir_intrinsic_load_sample_positions_amd: { - /* offset = sample_id * 8 (8 = 2 floats containing samplepos.xy) */ - nir_def *buf = si_nir_load_internal_binding(b, args, SI_PS_CONST_SAMPLE_POSITIONS, 4); + /* Sample locations are packed in 2 user SGPRs, 4 bits per component. */ nir_def *sample_id = intrin->src[0].ssa; - nir_def *offset = nir_ishl_imm(b, sample_id, 3); - replacement = nir_load_ubo(b, 2, 32, buf, offset, .range = ~0); + nir_def *sample_locs = + nir_pack_64_2x32_split(b, ac_nir_load_arg(b, &s->args->ac, s->args->sample_locs[0]), + ac_nir_load_arg(b, &s->args->ac, s->args->sample_locs[1])); + sample_locs = nir_ushr(b, sample_locs, nir_imul_imm(b, sample_id, 8)); + sample_locs = nir_u2u32(b, sample_locs); + nir_def *sample_pos = nir_vec2(b, nir_iand_imm(b, sample_locs, 0xf), + nir_ubfe_imm(b, sample_locs, 4, 4)); + replacement = nir_fmul_imm(b, nir_u2f32(b, sample_pos), 1.0 / 16); break; } case nir_intrinsic_load_ring_tess_factors_amd: { diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index 38b45e5d356..fe8bfa869f3 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -215,7 +215,6 @@ static void si_destroy_context(struct pipe_context *context) pipe_resource_reference(&sctx->esgs_ring, NULL); pipe_resource_reference(&sctx->gsvs_ring, NULL); pipe_resource_reference(&sctx->null_const_buf.buffer, NULL); - pipe_resource_reference(&sctx->sample_pos_buffer, NULL); si_resource_reference(&sctx->border_color_buffer, NULL); free(sctx->border_color_table); si_resource_reference(&sctx->scratch_buffer, NULL); @@ -779,7 +778,6 @@ static struct pipe_context *si_create_context(struct pipe_screen *screen, unsign si_set_internal_const_buffer(sctx, SI_VS_CONST_INSTANCE_DIVISORS, &sctx->null_const_buf); si_set_internal_const_buffer(sctx, SI_VS_CONST_CLIP_PLANES, &sctx->null_const_buf); si_set_internal_const_buffer(sctx, SI_PS_CONST_POLY_STIPPLE, &sctx->null_const_buf); - si_set_internal_const_buffer(sctx, SI_PS_CONST_SAMPLE_POSITIONS, &sctx->null_const_buf); } /* Bindless handles. */ diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 22064a99bc5..ee8c7aa1234 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -1270,18 +1270,6 @@ struct si_context { bool uses_bindless_samplers; bool uses_bindless_images; - /* MSAA sample locations. - * The first index is the sample index. - * The second index is the coordinate: X, Y. */ - struct { - float x1[1][2]; - float x2[2][2]; - float x4[4][2]; - float x8[8][2]; - float x16[16][2]; - } sample_positions; - struct pipe_resource *sample_pos_buffer; - /* Misc stats. */ unsigned num_draw_calls; unsigned num_decompress_calls; diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index 856e3141338..c0b19daa8d5 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -611,6 +611,10 @@ static void si_init_shader_args(struct si_shader *shader, struct si_shader_args case MESA_SHADER_FRAGMENT: declare_global_desc_pointers(args); declare_per_stage_desc_pointers(args, shader, info, true); + si_add_arg_checked(&args->ac, AC_ARG_SGPR, 1, AC_ARG_INT, &args->sample_locs[0], + SI_PARAM_SAMPLE_LOCS0); + si_add_arg_checked(&args->ac, AC_ARG_SGPR, 1, AC_ARG_INT, &args->sample_locs[1], + SI_PARAM_SAMPLE_LOCS1); si_add_arg_checked(&args->ac, AC_ARG_SGPR, 1, AC_ARG_INT, &args->alpha_reference, SI_PARAM_ALPHA_REF); si_add_arg_checked(&args->ac, AC_ARG_SGPR, 1, AC_ARG_INT, &args->ac.prim_mask, @@ -3803,6 +3807,8 @@ void si_get_ps_epilog_args(struct si_shader_args *args, ac_add_arg(&args->ac, AC_ARG_SGPR, 1, AC_ARG_INT, NULL); ac_add_arg(&args->ac, AC_ARG_SGPR, 1, AC_ARG_INT, NULL); ac_add_arg(&args->ac, AC_ARG_SGPR, 1, AC_ARG_INT, NULL); + ac_add_arg(&args->ac, AC_ARG_SGPR, 1, AC_ARG_INT, NULL); + ac_add_arg(&args->ac, AC_ARG_SGPR, 1, AC_ARG_INT, NULL); ac_add_arg(&args->ac, AC_ARG_SGPR, 1, AC_ARG_FLOAT, &args->alpha_reference); u_foreach_bit (i, key->ps_epilog.colors_written) { diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h index a652e481ce4..b6937729365 100644 --- a/src/gallium/drivers/radeonsi/si_shader.h +++ b/src/gallium/drivers/radeonsi/si_shader.h @@ -185,7 +185,9 @@ enum GFX9_GS_NUM_USER_SGPR, /* PS only */ - SI_SGPR_ALPHA_REF = SI_NUM_RESOURCE_SGPRS, + SI_SGPR_SAMPLE_LOCS0 = SI_NUM_RESOURCE_SGPRS, + SI_SGPR_SAMPLE_LOCS1, + SI_SGPR_ALPHA_REF, SI_PS_NUM_USER_SGPR, /* The value has to be 12, because the hw requires that descriptors @@ -200,7 +202,9 @@ enum SI_NUM_RESOURCE_PARAMS = 4, /* PS only parameters */ - SI_PARAM_ALPHA_REF = SI_NUM_RESOURCE_PARAMS, + SI_PARAM_SAMPLE_LOCS0 = SI_NUM_RESOURCE_PARAMS, + SI_PARAM_SAMPLE_LOCS1, + SI_PARAM_ALPHA_REF, SI_PARAM_PRIM_MASK, SI_PARAM_PERSP_SAMPLE, SI_PARAM_PERSP_CENTER, diff --git a/src/gallium/drivers/radeonsi/si_shader_internal.h b/src/gallium/drivers/radeonsi/si_shader_internal.h index 7986731c598..588eb1c8331 100644 --- a/src/gallium/drivers/radeonsi/si_shader_internal.h +++ b/src/gallium/drivers/radeonsi/si_shader_internal.h @@ -71,6 +71,7 @@ struct si_shader_args { /* API TCS & TES */ struct ac_arg tes_offchip_addr; /* PS */ + struct ac_arg sample_locs[2]; struct ac_arg alpha_reference; struct ac_arg color_start; /* CS */ diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index 702eadc8927..1dff3117db4 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -2740,46 +2740,8 @@ static void si_set_framebuffer_state(struct pipe_context *ctx, si_mark_atom_dirty(sctx, &sctx->atoms.s.msaa_config); if (sctx->framebuffer.nr_samples != old_nr_samples) { - struct pipe_constant_buffer constbuf = {0}; - si_mark_atom_dirty(sctx, &sctx->atoms.s.msaa_config); si_mark_atom_dirty(sctx, &sctx->atoms.s.db_render_state); - - if (!sctx->sample_pos_buffer) { - sctx->sample_pos_buffer = pipe_buffer_create_with_data(&sctx->b, 0, PIPE_USAGE_DEFAULT, - sizeof(sctx->sample_positions), - &sctx->sample_positions); - } - constbuf.buffer = sctx->sample_pos_buffer; - - /* Set sample locations as fragment shader constants. */ - switch (sctx->framebuffer.nr_samples) { - case 1: - constbuf.buffer_offset = 0; - break; - case 2: - constbuf.buffer_offset = - (uint8_t *)sctx->sample_positions.x2 - (uint8_t *)sctx->sample_positions.x1; - break; - case 4: - constbuf.buffer_offset = - (uint8_t *)sctx->sample_positions.x4 - (uint8_t *)sctx->sample_positions.x1; - break; - case 8: - constbuf.buffer_offset = - (uint8_t *)sctx->sample_positions.x8 - (uint8_t *)sctx->sample_positions.x1; - break; - case 16: - constbuf.buffer_offset = - (uint8_t *)sctx->sample_positions.x16 - (uint8_t *)sctx->sample_positions.x1; - break; - default: - PRINT_ERR("Requested an invalid number of samples %i.\n", sctx->framebuffer.nr_samples); - assert(0); - } - constbuf.buffer_size = sctx->framebuffer.nr_samples * 2 * 4; - si_set_internal_const_buffer(sctx, SI_PS_CONST_SAMPLE_POSITIONS, &constbuf); - si_mark_atom_dirty(sctx, &sctx->atoms.s.sample_locations); } diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h index ea5e9e1fb59..a83b6cc079b 100644 --- a/src/gallium/drivers/radeonsi/si_state.h +++ b/src/gallium/drivers/radeonsi/si_state.h @@ -465,7 +465,6 @@ enum SI_VS_CONST_INSTANCE_DIVISORS, SI_VS_CONST_CLIP_PLANES, SI_PS_CONST_POLY_STIPPLE, - SI_PS_CONST_SAMPLE_POSITIONS, SI_RING_ESGS, /* gfx6-8 */ SI_RING_GSVS, /* gfx6-10 */ diff --git a/src/gallium/drivers/radeonsi/si_state_msaa.c b/src/gallium/drivers/radeonsi/si_state_msaa.c index b847848bb2b..728d707930c 100644 --- a/src/gallium/drivers/radeonsi/si_state_msaa.c +++ b/src/gallium/drivers/radeonsi/si_state_msaa.c @@ -142,6 +142,17 @@ static void si_get_sample_position(struct pipe_context *ctx, unsigned sample_cou out_value[1] = (GET_SY(sample_locs, sample_index) + 8) / 16.0f; } +static uint32_t convert_locs_to_unsigned(uint32_t locs) +{ + uint32_t result = 0; + + /* GET_SFIELD extracts int from 4 bits. Add 8 to convert it from -8..7 to 0..15. */ + for (unsigned i = 0; i < 8; i++) + result |= (uint32_t)((GET_SFIELD(locs, i) + 8) & 0xf) << (i * 4); + + return result; +} + static void si_emit_max_4_sample_locs(struct si_context *sctx, uint64_t centroid_priority, uint32_t sample_locs, uint32_t max_sample_dist) { @@ -180,6 +191,19 @@ static void si_emit_max_4_sample_locs(struct si_context *sctx, uint64_t centroid radeon_set_context_reg(R_028C28_PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_0, sample_locs); radeon_end(); } + + if (sctx->gfx_level >= GFX12) { + gfx12_push_gfx_sh_reg(R_00B030_SPI_SHADER_USER_DATA_PS_0 + SI_SGPR_SAMPLE_LOCS0 * 4, + convert_locs_to_unsigned(sample_locs)); + } else if (sctx->screen->info.has_set_sh_pairs_packed) { + gfx11_push_gfx_sh_reg(R_00B030_SPI_SHADER_USER_DATA_PS_0 + SI_SGPR_SAMPLE_LOCS0 * 4, + convert_locs_to_unsigned(sample_locs)); + } else { + radeon_begin(&sctx->gfx_cs); + radeon_set_sh_reg(R_00B030_SPI_SHADER_USER_DATA_PS_0 + SI_SGPR_SAMPLE_LOCS0 * 4, + convert_locs_to_unsigned(sample_locs)); + radeon_end(); + } } static void si_emit_max_16_sample_locs(struct si_context *sctx, uint64_t centroid_priority, @@ -207,6 +231,22 @@ static void si_emit_max_16_sample_locs(struct si_context *sctx, uint64_t centroi radeon_emit_array(sample_locs, 4); radeon_emit_array(sample_locs, 4); radeon_emit_array(sample_locs, num_samples == 8 ? 2 : 4); + + if (sctx->gfx_level >= GFX12) { + gfx12_push_gfx_sh_reg(R_00B030_SPI_SHADER_USER_DATA_PS_0 + SI_SGPR_SAMPLE_LOCS0 * 4, + convert_locs_to_unsigned(sample_locs[0])); + gfx12_push_gfx_sh_reg(R_00B030_SPI_SHADER_USER_DATA_PS_0 + SI_SGPR_SAMPLE_LOCS1 * 4, + convert_locs_to_unsigned(sample_locs[1])); + } else if (sctx->screen->info.has_set_sh_pairs_packed) { + gfx11_push_gfx_sh_reg(R_00B030_SPI_SHADER_USER_DATA_PS_0 + SI_SGPR_SAMPLE_LOCS0 * 4, + convert_locs_to_unsigned(sample_locs[0])); + gfx11_push_gfx_sh_reg(R_00B030_SPI_SHADER_USER_DATA_PS_0 + SI_SGPR_SAMPLE_LOCS1 * 4, + convert_locs_to_unsigned(sample_locs[1])); + } else { + radeon_set_sh_reg_seq(R_00B030_SPI_SHADER_USER_DATA_PS_0 + SI_SGPR_SAMPLE_LOCS0 * 4, 2); + radeon_emit(convert_locs_to_unsigned(sample_locs[0])); + radeon_emit(convert_locs_to_unsigned(sample_locs[1])); + } radeon_end(); } @@ -280,19 +320,6 @@ static void si_emit_sample_locations(struct si_context *sctx, unsigned index) void si_init_msaa_functions(struct si_context *sctx) { - int i; - sctx->atoms.s.sample_locations.emit = si_emit_sample_locations; sctx->b.get_sample_position = si_get_sample_position; - - si_get_sample_position(&sctx->b, 1, 0, sctx->sample_positions.x1[0]); - - for (i = 0; i < 2; i++) - si_get_sample_position(&sctx->b, 2, i, sctx->sample_positions.x2[i]); - for (i = 0; i < 4; i++) - si_get_sample_position(&sctx->b, 4, i, sctx->sample_positions.x4[i]); - for (i = 0; i < 8; i++) - si_get_sample_position(&sctx->b, 8, i, sctx->sample_positions.x8[i]); - for (i = 0; i < 16; i++) - si_get_sample_position(&sctx->b, 16, i, sctx->sample_positions.x16[i]); }