mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-06 17:30:20 +01:00
ilo: map SO registers at shader compile time
The unmodified pipe_stream_output_info describes its outputs as if they are in TGSI_FILE_OUTPUT. Remap the register indices to where they appear in the VUE. TGSI_SEMANTIC_PSIZE needs a little care because it is at the W channel.
This commit is contained in:
parent
68522bf36c
commit
91cf6c1e92
6 changed files with 72 additions and 37 deletions
|
|
@ -378,20 +378,20 @@ gen7_pipeline_sol(struct ilo_3d_pipeline *p,
|
|||
struct gen6_pipeline_session *session)
|
||||
{
|
||||
const struct pipe_stream_output_info *so_info;
|
||||
const struct ilo_shader *sh;
|
||||
const struct ilo_shader_state *shader;
|
||||
bool dirty_sh = false;
|
||||
|
||||
if (ilo->gs) {
|
||||
so_info = &ilo->gs->info.stream_output;
|
||||
sh = ilo->gs->shader;
|
||||
shader = ilo->gs;
|
||||
dirty_sh = DIRTY(GS);
|
||||
}
|
||||
else {
|
||||
so_info = &ilo->vs->info.stream_output;
|
||||
sh = ilo->vs->shader;
|
||||
shader = ilo->vs;
|
||||
dirty_sh = DIRTY(VS);
|
||||
}
|
||||
|
||||
so_info = ilo_shader_get_kernel_so_info(shader);
|
||||
|
||||
gen6_pipeline_update_max_svbi(p, ilo, session);
|
||||
|
||||
/* 3DSTATE_SO_BUFFER */
|
||||
|
|
@ -419,13 +419,15 @@ gen7_pipeline_sol(struct ilo_3d_pipeline *p,
|
|||
|
||||
/* 3DSTATE_SO_DECL_LIST */
|
||||
if (dirty_sh && ilo->so.enabled)
|
||||
p->gen7_3DSTATE_SO_DECL_LIST(p->dev, so_info, sh, p->cp);
|
||||
p->gen7_3DSTATE_SO_DECL_LIST(p->dev, so_info, p->cp);
|
||||
|
||||
/* 3DSTATE_STREAMOUT */
|
||||
if (DIRTY(STREAM_OUTPUT_TARGETS) || DIRTY(RASTERIZER) || dirty_sh) {
|
||||
const unsigned buffer_mask = (1 << ilo->so.count) - 1;
|
||||
const int output_count = ilo_shader_get_kernel_param(shader,
|
||||
ILO_KERNEL_OUTPUT_COUNT);
|
||||
|
||||
p->gen7_3DSTATE_STREAMOUT(p->dev, buffer_mask, sh->out.count,
|
||||
p->gen7_3DSTATE_STREAMOUT(p->dev, buffer_mask, output_count,
|
||||
ilo->rasterizer->state.rasterizer_discard, p->cp);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1102,7 +1102,6 @@ gen7_emit_3DSTATE_PUSH_CONSTANT_ALLOC_PS(const struct ilo_dev_info *dev,
|
|||
static void
|
||||
gen7_emit_3DSTATE_SO_DECL_LIST(const struct ilo_dev_info *dev,
|
||||
const struct pipe_stream_output_info *so_info,
|
||||
const struct ilo_shader *sh,
|
||||
struct ilo_cp *cp)
|
||||
{
|
||||
const uint32_t cmd = ILO_GPE_CMD(0x3, 0x1, 0x17);
|
||||
|
|
@ -1121,7 +1120,7 @@ gen7_emit_3DSTATE_SO_DECL_LIST(const struct ilo_dev_info *dev,
|
|||
memset(buffer_offsets, 0, sizeof(buffer_offsets));
|
||||
|
||||
for (i = 0; i < so_info->num_outputs; i++) {
|
||||
unsigned decl, buf, attr, mask;
|
||||
unsigned decl, buf, reg, mask;
|
||||
|
||||
buf = so_info->output[i].output_buffer;
|
||||
|
||||
|
|
@ -1142,34 +1141,13 @@ gen7_emit_3DSTATE_SO_DECL_LIST(const struct ilo_dev_info *dev,
|
|||
buffer_offsets[buf] += num_dwords;
|
||||
}
|
||||
|
||||
/* figure out which attribute is sourced */
|
||||
for (attr = 0; attr < sh->out.count; attr++) {
|
||||
const int idx = sh->out.register_indices[attr];
|
||||
if (idx == so_info->output[i].register_index)
|
||||
break;
|
||||
}
|
||||
reg = so_info->output[i].register_index;
|
||||
mask = ((1 << so_info->output[i].num_components) - 1) <<
|
||||
so_info->output[i].start_component;
|
||||
|
||||
decl = buf << SO_DECL_OUTPUT_BUFFER_SLOT_SHIFT;
|
||||
|
||||
if (attr < sh->out.count) {
|
||||
mask = ((1 << so_info->output[i].num_components) - 1) <<
|
||||
so_info->output[i].start_component;
|
||||
|
||||
/* PSIZE is at W channel */
|
||||
if (sh->out.semantic_names[attr] == TGSI_SEMANTIC_PSIZE) {
|
||||
assert(mask == 0x1);
|
||||
mask = (mask << 3) & 0xf;
|
||||
}
|
||||
|
||||
decl |= attr << SO_DECL_REGISTER_INDEX_SHIFT |
|
||||
mask << SO_DECL_COMPONENT_MASK_SHIFT;
|
||||
}
|
||||
else {
|
||||
assert(!"stream output an undefined register");
|
||||
mask = (1 << so_info->output[i].num_components) - 1;
|
||||
decl |= SO_DECL_HOLE_FLAG |
|
||||
mask << SO_DECL_COMPONENT_MASK_SHIFT;
|
||||
}
|
||||
decl = buf << SO_DECL_OUTPUT_BUFFER_SLOT_SHIFT |
|
||||
reg << SO_DECL_REGISTER_INDEX_SHIFT |
|
||||
mask << SO_DECL_COMPONENT_MASK_SHIFT;
|
||||
|
||||
so_decls[num_entries++] = decl;
|
||||
buffer_selects |= 1 << buf;
|
||||
|
|
|
|||
|
|
@ -360,7 +360,6 @@ typedef void
|
|||
typedef void
|
||||
(*ilo_gpe_gen7_3DSTATE_SO_DECL_LIST)(const struct ilo_dev_info *dev,
|
||||
const struct pipe_stream_output_info *so_info,
|
||||
const struct ilo_shader *sh,
|
||||
struct ilo_cp *cp);
|
||||
|
||||
typedef void
|
||||
|
|
|
|||
|
|
@ -610,6 +610,42 @@ ilo_shader_state_search_variant(struct ilo_shader_state *state,
|
|||
return sh;
|
||||
}
|
||||
|
||||
static void
|
||||
copy_so_info(struct ilo_shader *sh,
|
||||
const struct pipe_stream_output_info *so_info)
|
||||
{
|
||||
unsigned i, attr;
|
||||
|
||||
if (!so_info->num_outputs)
|
||||
return;
|
||||
|
||||
sh->so_info = *so_info;
|
||||
|
||||
for (i = 0; i < so_info->num_outputs; i++) {
|
||||
/* figure out which attribute is sourced */
|
||||
for (attr = 0; attr < sh->out.count; attr++) {
|
||||
const int reg_idx = sh->out.register_indices[attr];
|
||||
if (reg_idx == so_info->output[i].register_index)
|
||||
break;
|
||||
}
|
||||
|
||||
if (attr < sh->out.count) {
|
||||
sh->so_info.output[i].register_index = attr;
|
||||
}
|
||||
else {
|
||||
assert(!"stream output an undefined register");
|
||||
sh->so_info.output[i].register_index = 0;
|
||||
}
|
||||
|
||||
/* PSIZE is at W channel */
|
||||
if (sh->out.semantic_names[attr] == TGSI_SEMANTIC_PSIZE) {
|
||||
assert(so_info->output[i].start_component == 0);
|
||||
assert(so_info->output[i].num_components == 1);
|
||||
sh->so_info.output[i].start_component = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a shader variant to the shader state.
|
||||
*/
|
||||
|
|
@ -643,6 +679,8 @@ ilo_shader_state_add_variant(struct ilo_shader_state *state,
|
|||
|
||||
sh->variant = *variant;
|
||||
|
||||
copy_so_info(sh, &state->info.stream_output);
|
||||
|
||||
ilo_shader_state_add_shader(state, sh);
|
||||
|
||||
return sh;
|
||||
|
|
@ -927,3 +965,16 @@ ilo_shader_get_kernel_cso(const struct ilo_shader_state *shader)
|
|||
|
||||
return &kernel->cso;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the SO info of the selected kernel.
|
||||
*/
|
||||
const struct pipe_stream_output_info *
|
||||
ilo_shader_get_kernel_so_info(const struct ilo_shader_state *shader)
|
||||
{
|
||||
const struct ilo_shader *kernel = shader->shader;
|
||||
|
||||
assert(kernel);
|
||||
|
||||
return &kernel->so_info;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,4 +124,7 @@ ilo_shader_get_kernel_param(const struct ilo_shader_state *shader,
|
|||
const struct ilo_shader_cso *
|
||||
ilo_shader_get_kernel_cso(const struct ilo_shader_state *shader);
|
||||
|
||||
const struct pipe_stream_output_info *
|
||||
ilo_shader_get_kernel_so_info(const struct ilo_shader_state *shader);
|
||||
|
||||
#endif /* ILO_SHADER_H */
|
||||
|
|
|
|||
|
|
@ -105,6 +105,8 @@ struct ilo_shader {
|
|||
|
||||
bool stream_output;
|
||||
int svbi_post_inc;
|
||||
struct pipe_stream_output_info so_info;
|
||||
|
||||
/* for VS stream output / rasterizer discard */
|
||||
int gs_offsets[3];
|
||||
int gs_start_grf;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue