mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-06 15:58:05 +02:00
r600: cypress resinfo buffer size workaround
Reading the buffer size (GET_BUFFER_RESINFO) does not work on cypress. This issue is the main difference on a test basis between cypress and other gpus like palm and cayman. This change adds a dedicated function which extends the previous workaround algorithm for cubearray to this end. This change assumes that all the gpus between cedar and hemlock have the same issue. Signed-off-by: Patrick Lerda <patrick9876@free.fr> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39650>
This commit is contained in:
parent
34336c7f16
commit
c54f134f60
6 changed files with 130 additions and 8 deletions
|
|
@ -4551,6 +4551,7 @@ static void evergreen_set_shader_buffers(struct pipe_context *ctx,
|
|||
}
|
||||
|
||||
istate->atom.num_dw = util_bitcount(istate->enabled_mask) * 46;
|
||||
istate->dirty_buffer_constants = true;
|
||||
|
||||
if (old_mask != istate->enabled_mask)
|
||||
r600_mark_atom_dirty(rctx, &rctx->cb_state.atom);
|
||||
|
|
|
|||
|
|
@ -202,7 +202,9 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen,
|
|||
|
||||
rctx->append_fence = pipe_buffer_create(rctx->b.b.screen, PIPE_BIND_CUSTOM,
|
||||
PIPE_USAGE_DEFAULT, 32);
|
||||
rctx->setup_buffer_constants = r600_palm_to_aruba_setup_buffer_constants;
|
||||
rctx->setup_buffer_constants = rctx->b.family >= CHIP_PALM ?
|
||||
r600_palm_to_aruba_setup_buffer_constants :
|
||||
r600_cedar_to_hemlock_setup_buffer_constants;
|
||||
break;
|
||||
default:
|
||||
R600_ERR("Unsupported gfx level %d.\n", rctx->b.gfx_level);
|
||||
|
|
|
|||
|
|
@ -1124,6 +1124,7 @@ void evergreen_emit_atomic_buffer_save(struct r600_context *rctx,
|
|||
void r600_update_compressed_resource_state(struct r600_context *rctx, bool compute_only);
|
||||
|
||||
void r600_palm_to_aruba_setup_buffer_constants(struct r600_context *rctx, int shader_type);
|
||||
void r600_cedar_to_hemlock_setup_buffer_constants(struct r600_context *rctx, int shader_type);
|
||||
void r600_setup_buffer_constants(struct r600_context *rctx, int shader_type);
|
||||
void r600_update_driver_const_buffers(struct r600_context *rctx, bool compute_only);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1477,7 +1477,7 @@ void r600_setup_buffer_constants(struct r600_context *rctx, int shader_type)
|
|||
|
||||
}
|
||||
|
||||
/* On evergreen we store one value
|
||||
/* On palm to aruba we store one value
|
||||
* 1. number of cube layers in a cube map array.
|
||||
*/
|
||||
void r600_palm_to_aruba_setup_buffer_constants(struct r600_context *rctx, int shader_type)
|
||||
|
|
@ -1532,6 +1532,84 @@ void r600_palm_to_aruba_setup_buffer_constants(struct r600_context *rctx, int sh
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* On cedar to hemlock we store two values using the same location
|
||||
* 1. number of cube layers in a cube map array.
|
||||
* 2. buffer size
|
||||
*/
|
||||
void r600_cedar_to_hemlock_setup_buffer_constants(struct r600_context *rctx, int shader_type)
|
||||
{
|
||||
struct r600_textures_info *const samplers = &rctx->samplers[shader_type];
|
||||
struct r600_image_state *images = NULL;
|
||||
struct r600_image_state *buffers = NULL;
|
||||
|
||||
if (shader_type == MESA_SHADER_FRAGMENT) {
|
||||
images = &rctx->fragment_images;
|
||||
buffers = &rctx->fragment_buffers;
|
||||
} else if (shader_type == MESA_SHADER_COMPUTE) {
|
||||
images = &rctx->compute_images;
|
||||
buffers = &rctx->compute_buffers;
|
||||
}
|
||||
|
||||
if (!samplers->views.dirty_buffer_constants &&
|
||||
!(images && images->dirty_buffer_constants) &&
|
||||
!(buffers && buffers->dirty_buffer_constants))
|
||||
return;
|
||||
|
||||
if (images)
|
||||
images->dirty_buffer_constants = false;
|
||||
if (buffers)
|
||||
buffers->dirty_buffer_constants = false;
|
||||
samplers->views.dirty_buffer_constants = false;
|
||||
|
||||
const unsigned sview_bits = util_last_bit(samplers->views.enabled_mask);
|
||||
unsigned bits = sview_bits;
|
||||
if (images)
|
||||
bits += util_last_bit(images->enabled_mask);
|
||||
const unsigned img_bits = bits;
|
||||
if (buffers)
|
||||
bits += util_last_bit(buffers->enabled_mask);
|
||||
|
||||
const uint32_t array_size = bits * sizeof(uint32_t);
|
||||
uint32_t base_offset;
|
||||
uint32_t *const constants = r600_alloc_buf_consts(rctx, shader_type, array_size,
|
||||
&base_offset);
|
||||
|
||||
for (unsigned i = 0; i < sview_bits; i++) {
|
||||
if (samplers->views.enabled_mask & (1 << i)) {
|
||||
uint32_t offset = (base_offset / 4) + i;
|
||||
if (samplers->views.views[i]->tex_resource->b.b.target == PIPE_BUFFER) {
|
||||
constants[offset] = samplers->views.views[i]->tex_resource_words[4];
|
||||
} else {
|
||||
constants[offset] = samplers->views.views[i]->base.texture->array_size / 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (images) {
|
||||
for (unsigned i = sview_bits; i < img_bits; i++) {
|
||||
int idx = i - sview_bits;
|
||||
if (images->enabled_mask & (1 << idx)) {
|
||||
uint32_t offset = (base_offset / 4) + i;
|
||||
if (images->views[idx].base.resource->target == PIPE_BUFFER) {
|
||||
constants[offset] = images->views[idx].resource_words[4];
|
||||
} else {
|
||||
constants[offset] = (G_038014_LAST_ARRAY(images->views[idx].resource_words[5]) -
|
||||
G_038014_BASE_ARRAY(images->views[idx].resource_words[5]) + 1) / 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (buffers) {
|
||||
for (unsigned i = img_bits; i < bits; i++) {
|
||||
int idx = i - img_bits;
|
||||
if (buffers->enabled_mask & (1 << idx)) {
|
||||
uint32_t offset = (base_offset / 4) + i;
|
||||
constants[offset] = buffers->views[idx].resource_words[4];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* set sample xy locations as array of fragment shader constants */
|
||||
void r600_set_sample_locations_constant_buffer(struct r600_context *rctx)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -797,7 +797,19 @@ RatInstr::emit_ssbo_size(nir_intrinsic_instr *intr, Shader& shader)
|
|||
else
|
||||
assert(0 && "dynamic buffer offset not supported in buffer_size");
|
||||
|
||||
shader.emit_instruction(new QueryBufferSizeInstr(dest, {0, 1, 2, 3}, res_id));
|
||||
if (shader.chip_family() >= CHIP_PALM) {
|
||||
shader.emit_instruction(new QueryBufferSizeInstr(dest, {0, 1, 2, 3}, res_id));
|
||||
} else {
|
||||
const unsigned index = res_id - R600_IMAGE_REAL_RESOURCE_OFFSET;
|
||||
shader.set_flag(Shader::sh_resinfo_via_uniform);
|
||||
shader.emit_instruction(new AluInstr(op1_mov,
|
||||
dest[0],
|
||||
vf.uniform(index / 4 +
|
||||
R600_SHADER_BUFFER_INFO_SEL,
|
||||
index % 4,
|
||||
R600_BUFFER_INFO_CONST_BUFFER),
|
||||
AluInstr::write));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -957,7 +969,24 @@ RatInstr::emit_image_size(nir_intrinsic_instr *intrin, Shader& shader)
|
|||
|
||||
if (nir_intrinsic_image_dim(intrin) == GLSL_SAMPLER_DIM_BUF) {
|
||||
auto dest = vf.dest_vec4(intrin->def, pin_group);
|
||||
shader.emit_instruction(new QueryBufferSizeInstr(dest, {0, 1, 2, 3}, res_id));
|
||||
if (shader.chip_family() >= CHIP_PALM) {
|
||||
shader.emit_instruction(new QueryBufferSizeInstr(dest, {0, 1, 2, 3}, res_id));
|
||||
} else {
|
||||
if (const_offset) {
|
||||
shader.set_flag(Shader::sh_resinfo_via_uniform);
|
||||
unsigned lookup_resid = (res_id - R600_IMAGE_REAL_RESOURCE_OFFSET) +
|
||||
shader.image_size_const_offset();
|
||||
shader.emit_instruction(
|
||||
new AluInstr(op1_mov,
|
||||
dest[0],
|
||||
vf.uniform(lookup_resid / 4 + R600_SHADER_BUFFER_INFO_SEL,
|
||||
lookup_resid % 4,
|
||||
R600_BUFFER_INFO_CONST_BUFFER),
|
||||
AluInstr::write));
|
||||
} else {
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
|
||||
|
|
|
|||
|
|
@ -654,14 +654,25 @@ TexInstr::emit_tex_txs(nir_tex_instr *tex,
|
|||
auto dest = vf.dest_vec4(tex->def, pin_group);
|
||||
|
||||
if (tex->sampler_dim == GLSL_SAMPLER_DIM_BUF) {
|
||||
if (shader.chip_class() >= ISA_CC_EVERGREEN) {
|
||||
shader.emit_instruction(new QueryBufferSizeInstr(
|
||||
dest, {0, 7, 7, 7}, tex->texture_index + R600_MAX_CONST_BUFFERS));
|
||||
} else {
|
||||
if (shader.chip_family() >= CHIP_PALM) {
|
||||
shader.emit_instruction(new QueryBufferSizeInstr(dest,
|
||||
{0, 7, 7, 7},
|
||||
tex->texture_index +
|
||||
R600_MAX_CONST_BUFFERS));
|
||||
} else if (shader.chip_family() < CHIP_CEDAR) {
|
||||
int id = 2 * tex->texture_index + R600_SHADER_BUFFER_INFO_SEL + 1;
|
||||
auto src = vf.uniform(id, 1, R600_BUFFER_INFO_CONST_BUFFER);
|
||||
shader.emit_instruction(new AluInstr(op1_mov, dest[0], src, AluInstr::write));
|
||||
shader.set_flag(Shader::sh_uses_tex_buffer);
|
||||
} else {
|
||||
shader.set_flag(Shader::sh_resinfo_via_uniform);
|
||||
shader.emit_instruction(new AluInstr(op1_mov,
|
||||
dest[0],
|
||||
vf.uniform(tex->texture_index / 4 +
|
||||
R600_SHADER_BUFFER_INFO_SEL,
|
||||
tex->texture_index % 4,
|
||||
R600_BUFFER_INFO_CONST_BUFFER),
|
||||
AluInstr::write));
|
||||
}
|
||||
} else {
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue