From a50a3a8edfddbabf6ed6b3fd55e7b6bc97fb225e Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Fri, 9 Feb 2018 14:21:54 -0800 Subject: [PATCH] iris: uniform bits...badly --- src/gallium/drivers/iris/iris_context.h | 32 ++++++++++++++++++++++ src/gallium/drivers/iris/iris_program.c | 34 +++++++++++++++++++++++- src/gallium/drivers/iris/iris_state.c | 35 ++++++++++++++++++++++--- 3 files changed, 96 insertions(+), 5 deletions(-) diff --git a/src/gallium/drivers/iris/iris_context.h b/src/gallium/drivers/iris/iris_context.h index 0c67535df82..e70e6db4713 100644 --- a/src/gallium/drivers/iris/iris_context.h +++ b/src/gallium/drivers/iris/iris_context.h @@ -80,6 +80,29 @@ struct iris_batch; #define IRIS_DIRTY_CONSTANTS_GS (1ull << 38) #define IRIS_DIRTY_CONSTANTS_FS (1ull << 39) +enum brw_param_domain { + BRW_PARAM_DOMAIN_BUILTIN = 0, + BRW_PARAM_DOMAIN_PARAMETER, + BRW_PARAM_DOMAIN_UNIFORM, + BRW_PARAM_DOMAIN_IMAGE, +}; + +#define BRW_PARAM(domain, val) (BRW_PARAM_DOMAIN_##domain << 24 | (val)) +#define BRW_PARAM_DOMAIN(param) ((uint32_t)(param) >> 24) +#define BRW_PARAM_VALUE(param) ((uint32_t)(param) & 0x00ffffff) + +#define BRW_PARAM_PARAMETER(idx, comp) \ + BRW_PARAM(PARAMETER, ((idx) << 2) | (comp)) +#define BRW_PARAM_PARAMETER_IDX(param) (BRW_PARAM_VALUE(param) >> 2) +#define BRW_PARAM_PARAMETER_COMP(param) (BRW_PARAM_VALUE(param) & 0x3) + +#define BRW_PARAM_UNIFORM(idx) BRW_PARAM(UNIFORM, (idx)) +#define BRW_PARAM_UNIFORM_IDX(param) BRW_PARAM_VALUE(param) + +#define BRW_PARAM_IMAGE(idx, offset) BRW_PARAM(IMAGE, ((idx) << 8) | (offset)) +#define BRW_PARAM_IMAGE_IDX(value) (BRW_PARAM_VALUE(value) >> 8) +#define BRW_PARAM_IMAGE_OFFSET(value) (BRW_PARAM_VALUE(value) & 0xf) + struct iris_depth_stencil_alpha_state; enum iris_program_cache_id { @@ -112,6 +135,13 @@ struct iris_compiled_shader { uint8_t derived_data[0]; }; +struct iris_shader_state { + struct pipe_constant_buffer constbuf[PIPE_MAX_CONSTANT_BUFFERS]; + struct pipe_resource *push_resource; + unsigned const_offset; + unsigned const_size; +}; + struct iris_context { struct pipe_context ctx; @@ -122,6 +152,8 @@ struct iris_context { struct iris_compiled_shader *prog[MESA_SHADER_STAGES]; struct brw_vue_map *last_vue_map; + struct iris_shader_state state[MESA_SHADER_STAGES]; + struct u_upload_mgr *uploader; struct hash_table *cache; diff --git a/src/gallium/drivers/iris/iris_program.c b/src/gallium/drivers/iris/iris_program.c index e2e92b839ae..4a866b9ddb9 100644 --- a/src/gallium/drivers/iris/iris_program.c +++ b/src/gallium/drivers/iris/iris_program.c @@ -64,10 +64,15 @@ iris_create_shader_state(struct pipe_context *ctx, nir = brw_preprocess_nir(screen->compiler, nir); +#if 0 + /* Reassign uniform locations using type_size_scalar_bytes instead of + * the slot based calculation that st_nir uses. + */ nir_assign_var_locations(&nir->uniforms, &nir->num_uniforms, type_size_scalar_bytes); nir_lower_io(nir, nir_var_uniform, type_size_scalar_bytes, 0); - //NIR_PASS_V(nir, brw_nir_lower_uniforms, true); +#endif + nir_lower_io(nir, nir_var_uniform, type_size_vec4_bytes, 0); ish->program_id = get_new_program_id(screen); ish->base.type = PIPE_SHADER_IR_NIR; @@ -199,6 +204,31 @@ assign_common_binding_table_offsets(const struct gen_device_info *devinfo, return next_binding_table_offset; } +static void +iris_setup_uniforms(void *mem_ctx, + nir_shader *nir, + struct brw_stage_prog_data *prog_data) +{ + prog_data->nr_params = nir->num_uniforms * 4; + prog_data->param = rzalloc_array(mem_ctx, uint32_t, prog_data->nr_params); + + nir->num_uniforms *= 16; + + nir_foreach_variable(var, &nir->uniforms) { + /* UBO's, atomics and samplers don't take up space */ + //if (var->interface_type != NULL || var->type->contains_atomic()) + //continue; + + const unsigned components = glsl_get_components(var->type); + + for (unsigned i = 0; i < 4; i++) { + prog_data->param[var->data.driver_location] = + i < components ? BRW_PARAM_PARAMETER(var->data.driver_location, i) + : BRW_PARAM_BUILTIN_ZERO; + } + } +} + static bool iris_compile_vs(struct iris_context *ice, struct iris_uncompiled_shader *ish, @@ -292,6 +322,8 @@ iris_compile_fs(struct iris_context *ice, assign_common_binding_table_offsets(devinfo, &nir->info, prog_data, MAX2(key->nr_color_regions, 1)); + iris_setup_uniforms(mem_ctx, nir, prog_data); + char *error_str = NULL; const unsigned *program = brw_compile_fs(compiler, &ice->dbg, mem_ctx, key, fs_prog_data, diff --git a/src/gallium/drivers/iris/iris_state.c b/src/gallium/drivers/iris/iris_state.c index 5d63c21b0bc..73fcabb25c9 100644 --- a/src/gallium/drivers/iris/iris_state.c +++ b/src/gallium/drivers/iris/iris_state.c @@ -38,6 +38,7 @@ #include "pipe/p_screen.h" #include "util/u_inlines.h" #include "util/u_transfer.h" +#include "util/u_upload_mgr.h" #include "i915_drm.h" #include "intel/compiler/brw_compiler.h" #include "intel/common/gen_l3_config.h" @@ -1190,11 +1191,14 @@ iris_set_framebuffer_state(struct pipe_context *ctx, static void iris_set_constant_buffer(struct pipe_context *ctx, - enum pipe_shader_type shader, uint index, + enum pipe_shader_type p_stage, unsigned index, const struct pipe_constant_buffer *cb) { -} + struct iris_context *ice = (struct iris_context *) ctx; + gl_shader_stage stage = stage_from_pipe(p_stage); + util_copy_constant_buffer(&ice->shaders.state[stage].constbuf[index], cb); +} static void iris_sampler_view_destroy(struct pipe_context *ctx, @@ -1910,13 +1914,36 @@ iris_upload_render_state(struct iris_context *ice, } for (int stage = 0; stage <= MESA_SHADER_FRAGMENT; stage++) { + // XXX: wrong dirty tracking... + if (!(dirty & (IRIS_DIRTY_CONSTANTS_VS << stage))) + continue; + + struct pipe_constant_buffer *cbuf0 = + &ice->shaders.state[stage].constbuf[0]; + + if (!ice->shaders.prog[stage] || cbuf0->buffer || !cbuf0->buffer_size) + continue; + + struct iris_shader_state *shs = &ice->shaders.state[stage]; + shs->const_size = cbuf0->buffer_size; + u_upload_data(ice->ctx.const_uploader, 0, shs->const_size, 32, + cbuf0->user_buffer, &shs->const_offset, + &shs->push_resource); + } + + for (int stage = 0; stage <= MESA_SHADER_FRAGMENT; stage++) { + // XXX: wrong dirty tracking... if (!(dirty & (IRIS_DIRTY_CONSTANTS_VS << stage))) continue; + struct iris_shader_state *shs = &ice->shaders.state[stage]; + struct iris_resource *res = (void *) shs->push_resource; + iris_emit_cmd(batch, GENX(3DSTATE_CONSTANT_VS), pkt) { pkt._3DCommandSubOpcode = push_constant_opcodes[stage]; - if (ice->shaders.prog[stage]) { - // XXX: 3DSTATE_CONSTANT_XS + if (res) { + pkt.ConstantBody.ReadLength[3] = shs->const_size; + pkt.ConstantBody.Buffer[3] = ro_bo(res->bo, shs->const_offset); } } } -- 2.30.2