diff options
Diffstat (limited to 'src/gallium/drivers/iris/iris_program.c')
-rw-r--r-- | src/gallium/drivers/iris/iris_program.c | 79 |
1 files changed, 71 insertions, 8 deletions
diff --git a/src/gallium/drivers/iris/iris_program.c b/src/gallium/drivers/iris/iris_program.c index b8929be9b72..47a4b635f99 100644 --- a/src/gallium/drivers/iris/iris_program.c +++ b/src/gallium/drivers/iris/iris_program.c @@ -152,7 +152,9 @@ iris_lower_storage_image_derefs(nir_shader *nir) case nir_intrinsic_image_deref_atomic_exchange: case nir_intrinsic_image_deref_atomic_comp_swap: case nir_intrinsic_image_deref_size: - case nir_intrinsic_image_deref_samples: { + case nir_intrinsic_image_deref_samples: + case nir_intrinsic_image_deref_load_raw_intel: + case nir_intrinsic_image_deref_store_raw_intel: { nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]); nir_variable *var = nir_deref_instr_get_variable(deref); @@ -569,6 +571,19 @@ assign_common_binding_table_offsets(const struct gen_device_info *devinfo, return next_binding_table_offset; } +static void +setup_vec4_image_sysval(uint32_t *sysvals, uint32_t idx, + unsigned offset, unsigned n) +{ + assert(offset % sizeof(uint32_t) == 0); + + for (unsigned i = 0; i < n; ++i) + sysvals[i] = BRW_PARAM_IMAGE(idx, offset / sizeof(uint32_t) + i); + + for (unsigned i = n; i < 4; ++i) + sysvals[i] = BRW_PARAM_BUILTIN_ZERO; +} + /** * Associate NIR uniform variables with the prog_data->param[] mechanism * used by the backend. Also, decide which UBOs we'd like to push in an @@ -582,12 +597,7 @@ iris_setup_uniforms(const struct brw_compiler *compiler, enum brw_param_builtin **out_system_values, unsigned *out_num_system_values) { - /* We don't use params[], but fs_visitor::nir_setup_uniforms() asserts - * about it for compute shaders, so go ahead and make some fake ones - * which the backend will dead code eliminate. - */ - prog_data->nr_params = nir->num_uniforms; - prog_data->param = rzalloc_array(mem_ctx, uint32_t, prog_data->nr_params); + const struct gen_device_info *devinfo = compiler->devinfo; /* The intel compiler assumes that num_uniforms is in bytes. For * scalar that means 4 bytes per uniform slot. @@ -596,14 +606,17 @@ iris_setup_uniforms(const struct brw_compiler *compiler, */ nir->num_uniforms *= 4; - const unsigned IRIS_MAX_SYSTEM_VALUES = 32; + const unsigned IRIS_MAX_SYSTEM_VALUES = + PIPE_MAX_SHADER_IMAGES * BRW_IMAGE_PARAM_SIZE; enum brw_param_builtin *system_values = rzalloc_array(mem_ctx, enum brw_param_builtin, IRIS_MAX_SYSTEM_VALUES); unsigned num_system_values = 0; unsigned patch_vert_idx = -1; unsigned ucp_idx[IRIS_MAX_CLIP_PLANES]; + unsigned img_idx[PIPE_MAX_SHADER_IMAGES]; memset(ucp_idx, -1, sizeof(ucp_idx)); + memset(img_idx, -1, sizeof(img_idx)); nir_function_impl *impl = nir_shader_get_entrypoint(nir); @@ -650,6 +663,49 @@ iris_setup_uniforms(const struct brw_compiler *compiler, b.cursor = nir_before_instr(instr); offset = nir_imm_int(&b, patch_vert_idx * sizeof(uint32_t)); break; + case nir_intrinsic_image_deref_load_param_intel: { + assert(devinfo->gen < 9); + nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]); + nir_variable *var = nir_deref_instr_get_variable(deref); + + if (img_idx[var->data.binding] == -1) { + /* GL only allows arrays of arrays of images. */ + assert(glsl_type_is_image(glsl_without_array(var->type))); + unsigned num_images = MAX2(1, glsl_get_aoa_size(var->type)); + + for (int i = 0; i < num_images; i++) { + const unsigned img = var->data.binding + i; + + img_idx[img] = num_system_values; + num_system_values += BRW_IMAGE_PARAM_SIZE; + + uint32_t *img_sv = &system_values[img_idx[img]]; + + setup_vec4_image_sysval( + img_sv + BRW_IMAGE_PARAM_OFFSET_OFFSET, img, + offsetof(struct brw_image_param, offset), 2); + setup_vec4_image_sysval( + img_sv + BRW_IMAGE_PARAM_SIZE_OFFSET, img, + offsetof(struct brw_image_param, size), 3); + setup_vec4_image_sysval( + img_sv + BRW_IMAGE_PARAM_STRIDE_OFFSET, img, + offsetof(struct brw_image_param, stride), 4); + setup_vec4_image_sysval( + img_sv + BRW_IMAGE_PARAM_TILING_OFFSET, img, + offsetof(struct brw_image_param, tiling), 3); + setup_vec4_image_sysval( + img_sv + BRW_IMAGE_PARAM_SWIZZLING_OFFSET, img, + offsetof(struct brw_image_param, swizzling), 2); + } + } + + b.cursor = nir_before_instr(instr); + offset = nir_iadd(&b, + get_aoa_deref_offset(&b, deref, BRW_IMAGE_PARAM_SIZE * 4), + nir_imm_int(&b, img_idx[var->data.binding] * 4 + + nir_intrinsic_base(intrin) * 16)); + break; + } default: continue; } @@ -717,6 +773,13 @@ iris_setup_uniforms(const struct brw_compiler *compiler, if (nir->info.stage != MESA_SHADER_COMPUTE) brw_nir_analyze_ubo_ranges(compiler, nir, NULL, prog_data->ubo_ranges); + /* We don't use params[], but fs_visitor::nir_setup_uniforms() asserts + * about it for compute shaders, so go ahead and make some fake ones + * which the backend will dead code eliminate. + */ + prog_data->nr_params = nir->num_uniforms / 4; + prog_data->param = rzalloc_array(mem_ctx, uint32_t, prog_data->nr_params); + *out_system_values = system_values; *out_num_system_values = num_system_values; } |