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.
This commit is contained in:
Chia-I Wu 2013-06-20 16:34:25 +08:00
parent 5c8db569ab
commit d209da5e33
7 changed files with 102 additions and 42 deletions

View file

@ -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))

View file

@ -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 */

View file

@ -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);

View file

@ -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);

View file

@ -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;
}

View file

@ -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 */

View file

@ -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);