From d209da5e338ee1f437cbce21e9cba667d60ee557 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 20 Jun 2013 16:34:25 +0800 Subject: [PATCH] ilo: introduce ilo_shader_cso for VS When a new VS kernel is generated, a newly added function, ilo_gpe_init_vs_cso(), is called to construct 3DSTATE_VS command in ilo_shader_cso. When the command needs to be emitted later, we copy the command from the CSO instead of constructing it dynamically. --- .../drivers/ilo/ilo_3d_pipeline_gen6.c | 3 +- src/gallium/drivers/ilo/ilo_gpe.h | 10 +++ src/gallium/drivers/ilo/ilo_gpe_gen6.c | 74 ++++++++++++------- src/gallium/drivers/ilo/ilo_gpe_gen6.h | 2 +- src/gallium/drivers/ilo/ilo_shader.c | 45 ++++++++--- src/gallium/drivers/ilo/ilo_shader.h | 4 + .../drivers/ilo/shader/ilo_shader_internal.h | 6 +- 7 files changed, 102 insertions(+), 42 deletions(-) diff --git a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c index 228131c2612..e51d7942ab3 100644 --- a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c +++ b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c @@ -480,10 +480,9 @@ gen6_pipeline_vs(struct ilo_3d_pipeline *p, /* 3DSTATE_VS */ if (emit_3dstate_vs) { - const struct ilo_shader *vs = (ilo->vs)? ilo->vs->shader : NULL; const int num_samplers = ilo->sampler[PIPE_SHADER_VERTEX].count; - p->gen6_3DSTATE_VS(p->dev, vs, num_samplers, p->cp); + p->gen6_3DSTATE_VS(p->dev, ilo->vs, num_samplers, p->cp); } if (emit_3dstate_constant_vs && p->dev->gen == ILO_GEN(6)) diff --git a/src/gallium/drivers/ilo/ilo_gpe.h b/src/gallium/drivers/ilo/ilo_gpe.h index fcbd5b888b6..b5d0163f909 100644 --- a/src/gallium/drivers/ilo/ilo_gpe.h +++ b/src/gallium/drivers/ilo/ilo_gpe.h @@ -55,6 +55,7 @@ struct ilo_buffer; struct ilo_texture; +struct ilo_shader_state; struct ilo_vb_state { struct pipe_vertex_buffer states[PIPE_MAX_ATTRIBS]; @@ -254,6 +255,10 @@ struct ilo_global_binding { unsigned count; }; +struct ilo_shader_cso { + uint32_t payload[5]; +}; + void ilo_gpe_init_ve(const struct ilo_dev_info *dev, unsigned num_states, @@ -428,4 +433,9 @@ ilo_gpe_init_zs_surface(const struct ilo_dev_info *dev, unsigned first_layer, unsigned num_layers, struct ilo_zs_surface *zs); +void +ilo_gpe_init_vs_cso(const struct ilo_dev_info *dev, + const struct ilo_shader_state *vs, + struct ilo_shader_cso *cso); + #endif /* ILO_GPE_H */ diff --git a/src/gallium/drivers/ilo/ilo_gpe_gen6.c b/src/gallium/drivers/ilo/ilo_gpe_gen6.c index 5a18fead0f3..e57609bcfa4 100644 --- a/src/gallium/drivers/ilo/ilo_gpe_gen6.c +++ b/src/gallium/drivers/ilo/ilo_gpe_gen6.c @@ -1127,30 +1127,18 @@ gen6_emit_3DSTATE_SCISSOR_STATE_POINTERS(const struct ilo_dev_info *dev, ilo_cp_end(cp); } -static void -gen6_emit_3DSTATE_VS(const struct ilo_dev_info *dev, - const struct ilo_shader *vs, - int num_samplers, - struct ilo_cp *cp) +void +ilo_gpe_init_vs_cso(const struct ilo_dev_info *dev, + const struct ilo_shader_state *vs, + struct ilo_shader_cso *cso) { - const uint32_t cmd = ILO_GPE_CMD(0x3, 0x0, 0x10); - const uint8_t cmd_len = 6; + int start_grf, vue_read_len, max_threads; uint32_t dw2, dw4, dw5; - int vue_read_len, max_threads; ILO_GPE_VALID_GEN(dev, 6, 7); - if (!vs) { - ilo_cp_begin(cp, cmd_len); - ilo_cp_write(cp, cmd | (cmd_len - 2)); - ilo_cp_write(cp, 0); - ilo_cp_write(cp, 0); - ilo_cp_write(cp, 0); - ilo_cp_write(cp, 0); - ilo_cp_write(cp, 0); - ilo_cp_end(cp); - return; - } + start_grf = ilo_shader_get_kernel_param(vs, ILO_KERNEL_URB_DATA_START_REG); + vue_read_len = ilo_shader_get_kernel_param(vs, ILO_KERNEL_INPUT_COUNT); /* * From the Sandy Bridge PRM, volume 2 part 1, page 135: @@ -1162,7 +1150,7 @@ gen6_emit_3DSTATE_VS(const struct ilo_dev_info *dev, * "It is UNDEFINED to set this field to 0 indicating no Vertex URB * data to be read and passed to the thread." */ - vue_read_len = (vs->in.count + 1) / 2; + vue_read_len = (vue_read_len + 1) / 2; if (!vue_read_len) vue_read_len = 1; @@ -1196,11 +1184,9 @@ gen6_emit_3DSTATE_VS(const struct ilo_dev_info *dev, break; } - dw2 = ((num_samplers + 3) / 4) << GEN6_VS_SAMPLER_COUNT_SHIFT; - if (false) - dw2 |= GEN6_VS_FLOATING_POINT_MODE_ALT; + dw2 = (true) ? 0 : GEN6_VS_FLOATING_POINT_MODE_ALT; - dw4 = vs->in.start_grf << GEN6_VS_DISPATCH_START_GRF_SHIFT | + dw4 = start_grf << GEN6_VS_DISPATCH_START_GRF_SHIFT | vue_read_len << GEN6_VS_URB_READ_LENGTH_SHIFT | 0 << GEN6_VS_URB_ENTRY_READ_OFFSET_SHIFT; @@ -1212,9 +1198,47 @@ gen6_emit_3DSTATE_VS(const struct ilo_dev_info *dev, else dw5 |= (max_threads - 1) << GEN6_VS_MAX_THREADS_SHIFT; + STATIC_ASSERT(Elements(cso->payload) >= 3); + cso->payload[0] = dw2; + cso->payload[1] = dw4; + cso->payload[2] = dw5; +} + +static void +gen6_emit_3DSTATE_VS(const struct ilo_dev_info *dev, + const struct ilo_shader_state *vs, + int num_samplers, + struct ilo_cp *cp) +{ + const uint32_t cmd = ILO_GPE_CMD(0x3, 0x0, 0x10); + const uint8_t cmd_len = 6; + const struct ilo_shader_cso *cso; + uint32_t dw2, dw4, dw5; + + ILO_GPE_VALID_GEN(dev, 6, 7); + + if (!vs) { + ilo_cp_begin(cp, cmd_len); + ilo_cp_write(cp, cmd | (cmd_len - 2)); + ilo_cp_write(cp, 0); + ilo_cp_write(cp, 0); + ilo_cp_write(cp, 0); + ilo_cp_write(cp, 0); + ilo_cp_write(cp, 0); + ilo_cp_end(cp); + return; + } + + cso = ilo_shader_get_kernel_cso(vs); + dw2 = cso->payload[0]; + dw4 = cso->payload[1]; + dw5 = cso->payload[2]; + + dw2 |= ((num_samplers + 3) / 4) << GEN6_VS_SAMPLER_COUNT_SHIFT; + ilo_cp_begin(cp, cmd_len); ilo_cp_write(cp, cmd | (cmd_len - 2)); - ilo_cp_write(cp, vs->cache_offset); + ilo_cp_write(cp, ilo_shader_get_kernel_offset(vs)); ilo_cp_write(cp, dw2); ilo_cp_write(cp, 0); /* scratch */ ilo_cp_write(cp, dw4); diff --git a/src/gallium/drivers/ilo/ilo_gpe_gen6.h b/src/gallium/drivers/ilo/ilo_gpe_gen6.h index 5f2b85aebb3..07e6050500b 100644 --- a/src/gallium/drivers/ilo/ilo_gpe_gen6.h +++ b/src/gallium/drivers/ilo/ilo_gpe_gen6.h @@ -235,7 +235,7 @@ typedef void typedef void (*ilo_gpe_gen6_3DSTATE_VS)(const struct ilo_dev_info *dev, - const struct ilo_shader *vs, + const struct ilo_shader_state *vs, int num_samplers, struct ilo_cp *cp); diff --git a/src/gallium/drivers/ilo/ilo_shader.c b/src/gallium/drivers/ilo/ilo_shader.c index 21faf773e59..983cfffc851 100644 --- a/src/gallium/drivers/ilo/ilo_shader.c +++ b/src/gallium/drivers/ilo/ilo_shader.c @@ -613,18 +613,12 @@ ilo_shader_state_search_variant(struct ilo_shader_state *state, /** * Add a shader variant to the shader state. */ -struct ilo_shader * +static struct ilo_shader * ilo_shader_state_add_variant(struct ilo_shader_state *state, const struct ilo_shader_variant *variant) { struct ilo_shader *sh; - sh = ilo_shader_state_search_variant(state, variant); - if (sh) - return sh; - - ilo_shader_state_gc(state); - switch (state->info.type) { case PIPE_SHADER_VERTEX: sh = ilo_shader_compile_vs(state, variant); @@ -663,10 +657,18 @@ ilo_shader_state_use_variant(struct ilo_shader_state *state, const struct ilo_shader_variant *variant) { struct ilo_shader *sh; + bool construct_cso = false; - sh = ilo_shader_state_add_variant(state, variant); - if (!sh) - return false; + sh = ilo_shader_state_search_variant(state, variant); + if (!sh) { + ilo_shader_state_gc(state); + + sh = ilo_shader_state_add_variant(state, variant); + if (!sh) + return false; + + construct_cso = true; + } /* move to head */ if (state->variants.next != &sh->list) { @@ -676,6 +678,16 @@ ilo_shader_state_use_variant(struct ilo_shader_state *state, state->shader = sh; + if (construct_cso) { + switch (state->info.type) { + case PIPE_SHADER_VERTEX: + ilo_gpe_init_vs_cso(state->info.dev, state, &sh->cso); + break; + default: + break; + } + } + return true; } @@ -896,3 +908,16 @@ ilo_shader_get_kernel_param(const struct ilo_shader_state *shader, return val; } + +/** + * Return the CSO of the selected kernel. + */ +const struct ilo_shader_cso * +ilo_shader_get_kernel_cso(const struct ilo_shader_state *shader) +{ + const struct ilo_shader *kernel = shader->shader; + + assert(kernel); + + return &kernel->cso; +} diff --git a/src/gallium/drivers/ilo/ilo_shader.h b/src/gallium/drivers/ilo/ilo_shader.h index fa5a556539b..92ad7f6656f 100644 --- a/src/gallium/drivers/ilo/ilo_shader.h +++ b/src/gallium/drivers/ilo/ilo_shader.h @@ -62,6 +62,7 @@ struct intel_bo; struct ilo_context; struct ilo_shader_cache; struct ilo_shader_state; +struct ilo_shader_cso; struct ilo_shader_cache * ilo_shader_cache_create(void); @@ -120,4 +121,7 @@ int ilo_shader_get_kernel_param(const struct ilo_shader_state *shader, enum ilo_kernel_param param); +const struct ilo_shader_cso * +ilo_shader_get_kernel_cso(const struct ilo_shader_state *shader); + #endif /* ILO_SHADER_H */ diff --git a/src/gallium/drivers/ilo/shader/ilo_shader_internal.h b/src/gallium/drivers/ilo/shader/ilo_shader_internal.h index 1723bd19ded..c999d8abdb5 100644 --- a/src/gallium/drivers/ilo/shader/ilo_shader_internal.h +++ b/src/gallium/drivers/ilo/shader/ilo_shader_internal.h @@ -75,6 +75,8 @@ struct ilo_shader_variant { struct ilo_shader { struct ilo_shader_variant variant; + struct ilo_shader_cso cso; + struct { int semantic_names[PIPE_MAX_SHADER_INPUTS]; int semantic_indices[PIPE_MAX_SHADER_INPUTS]; @@ -174,10 +176,6 @@ ilo_shader_variant_init(struct ilo_shader_variant *variant, const struct ilo_shader_info *info, const struct ilo_context *ilo); -struct ilo_shader * -ilo_shader_state_add_variant(struct ilo_shader_state *state, - const struct ilo_shader_variant *variant); - bool ilo_shader_state_use_variant(struct ilo_shader_state *state, const struct ilo_shader_variant *variant); -- 2.30.2