diff options
author | Samuel Pitoiset <[email protected]> | 2018-03-13 14:49:11 +0100 |
---|---|---|
committer | Samuel Pitoiset <[email protected]> | 2018-03-13 16:54:21 +0100 |
commit | 237229430f303dc2395a85bc811adc6e25cc39d7 (patch) | |
tree | 49084a8befd75d59f39ca58700bc2c14e20d6386 /src/amd/vulkan | |
parent | 2cfba40eea4c3b5529ad14d4786c96013a416f30 (diff) |
ac: move ac_shader_info to radv folder
This is RADV specific code.
Signed-off-by: Samuel Pitoiset <[email protected]>
Reviewed-by: Bas Nieuwenhuizen <[email protected]>
Diffstat (limited to 'src/amd/vulkan')
-rw-r--r-- | src/amd/vulkan/Makefile.sources | 1 | ||||
-rw-r--r-- | src/amd/vulkan/meson.build | 1 | ||||
-rw-r--r-- | src/amd/vulkan/radv_nir_to_llvm.c | 2 | ||||
-rw-r--r-- | src/amd/vulkan/radv_private.h | 7 | ||||
-rw-r--r-- | src/amd/vulkan/radv_shader.c | 4 | ||||
-rw-r--r-- | src/amd/vulkan/radv_shader.h | 38 | ||||
-rw-r--r-- | src/amd/vulkan/radv_shader_info.c | 309 |
7 files changed, 358 insertions, 4 deletions
diff --git a/src/amd/vulkan/Makefile.sources b/src/amd/vulkan/Makefile.sources index 47ff580e883..b0a8f8b97d8 100644 --- a/src/amd/vulkan/Makefile.sources +++ b/src/amd/vulkan/Makefile.sources @@ -60,6 +60,7 @@ VULKAN_FILES := \ radv_private.h \ radv_radeon_winsys.h \ radv_shader.c \ + radv_shader_info.c \ radv_shader.h \ radv_query.c \ radv_util.c \ diff --git a/src/amd/vulkan/meson.build b/src/amd/vulkan/meson.build index 1fd6b755505..c3a6a8182b8 100644 --- a/src/amd/vulkan/meson.build +++ b/src/amd/vulkan/meson.build @@ -88,6 +88,7 @@ libradv_files = files( 'radv_radeon_winsys.h', 'radv_shader.c', 'radv_shader.h', + 'radv_shader_info.c', 'radv_query.c', 'radv_util.c', 'radv_util.h', diff --git a/src/amd/vulkan/radv_nir_to_llvm.c b/src/amd/vulkan/radv_nir_to_llvm.c index 9551def55e0..25ee3b91fc6 100644 --- a/src/amd/vulkan/radv_nir_to_llvm.c +++ b/src/amd/vulkan/radv_nir_to_llvm.c @@ -3007,7 +3007,7 @@ LLVMModuleRef ac_translate_nir_to_llvm(LLVMTargetMachineRef tm, memset(shader_info, 0, sizeof(*shader_info)); for(int i = 0; i < shader_count; ++i) - ac_nir_shader_info_pass(shaders[i], options, &shader_info->info); + radv_nir_shader_info_pass(shaders[i], options, &shader_info->info); for (i = 0; i < RADV_UD_MAX_SETS; i++) shader_info->user_sgprs_locs.descriptor_sets[i].sgpr_idx = -1; diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index 23815b9ccdf..913fbe7f934 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -1697,6 +1697,13 @@ void radv_compile_nir_shader(LLVMTargetMachineRef tm, const struct ac_nir_compiler_options *options, bool dump_shader); +/* radv_shader_info.h */ +struct radv_shader_info; + +void radv_nir_shader_info_pass(const struct nir_shader *nir, + const struct ac_nir_compiler_options *options, + struct radv_shader_info *info); + struct radeon_winsys_sem; #define RADV_DEFINE_HANDLE_CASTS(__radv_type, __VkType) \ diff --git a/src/amd/vulkan/radv_shader.c b/src/amd/vulkan/radv_shader.c index 1a5e76b8cfb..e11f19323f7 100644 --- a/src/amd/vulkan/radv_shader.c +++ b/src/amd/vulkan/radv_shader.c @@ -383,7 +383,7 @@ radv_fill_shader_variant(struct radv_device *device, case MESA_SHADER_FRAGMENT: break; case MESA_SHADER_COMPUTE: { - struct ac_shader_info *info = &variant->info.info; + struct radv_shader_info *info = &variant->info.info; variant->rsrc2 |= S_00B84C_TGID_X_EN(info->cs.uses_block_id[0]) | S_00B84C_TGID_Y_EN(info->cs.uses_block_id[1]) | @@ -401,7 +401,7 @@ radv_fill_shader_variant(struct radv_device *device, if (device->physical_device->rad_info.chip_class >= GFX9 && stage == MESA_SHADER_GEOMETRY) { - struct ac_shader_info *info = &variant->info.info; + struct radv_shader_info *info = &variant->info.info; unsigned es_type = variant->info.gs.es_type; unsigned gs_vgpr_comp_cnt, es_vgpr_comp_cnt; diff --git a/src/amd/vulkan/radv_shader.h b/src/amd/vulkan/radv_shader.h index b0517b73a42..a9b465cd80c 100644 --- a/src/amd/vulkan/radv_shader.h +++ b/src/amd/vulkan/radv_shader.h @@ -53,6 +53,42 @@ struct radv_shader_module { char data[0]; }; +struct radv_shader_info { + bool loads_push_constants; + uint32_t desc_set_used_mask; + bool needs_multiview_view_index; + bool uses_invocation_id; + bool uses_prim_id; + struct { + uint8_t input_usage_mask[VERT_ATTRIB_MAX]; + uint8_t output_usage_mask[VARYING_SLOT_VAR31 + 1]; + bool has_vertex_buffers; /* needs vertex buffers and base/start */ + bool needs_draw_id; + bool needs_instance_id; + } vs; + struct { + uint8_t output_usage_mask[VARYING_SLOT_VAR31 + 1]; + } tes; + struct { + bool force_persample; + bool needs_sample_positions; + bool uses_input_attachments; + bool writes_memory; + bool writes_z; + bool writes_stencil; + bool writes_sample_mask; + bool has_pcoord; + bool prim_id_input; + bool layer_input; + } ps; + struct { + bool uses_grid_size; + bool uses_block_id[3]; + bool uses_thread_id[3]; + bool uses_local_invocation_idx; + } cs; +}; + struct radv_userdata_info { int8_t sgpr_idx; uint8_t num_sgprs; @@ -83,7 +119,7 @@ struct radv_es_output_info { struct radv_shader_variant_info { struct radv_userdata_locations user_sgprs_locs; - struct ac_shader_info info; + struct radv_shader_info info; unsigned num_user_sgprs; unsigned num_input_sgprs; unsigned num_input_vgprs; diff --git a/src/amd/vulkan/radv_shader_info.c b/src/amd/vulkan/radv_shader_info.c new file mode 100644 index 00000000000..a6d8033bcb1 --- /dev/null +++ b/src/amd/vulkan/radv_shader_info.c @@ -0,0 +1,309 @@ +/* + * Copyright © 2017 Red Hat + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#include "radv_private.h" +#include "radv_shader.h" +#include "nir/nir.h" + +static void mark_sampler_desc(const nir_variable *var, + struct radv_shader_info *info) +{ + info->desc_set_used_mask |= (1 << var->data.descriptor_set); +} + +static void +gather_intrinsic_info(const nir_shader *nir, const nir_intrinsic_instr *instr, + struct radv_shader_info *info) +{ + switch (instr->intrinsic) { + case nir_intrinsic_interp_var_at_sample: + info->ps.needs_sample_positions = true; + break; + case nir_intrinsic_load_draw_id: + info->vs.needs_draw_id = true; + break; + case nir_intrinsic_load_instance_id: + info->vs.needs_instance_id = true; + break; + case nir_intrinsic_load_num_work_groups: + info->cs.uses_grid_size = true; + break; + case nir_intrinsic_load_local_invocation_id: + case nir_intrinsic_load_work_group_id: { + unsigned mask = nir_ssa_def_components_read(&instr->dest.ssa); + while (mask) { + unsigned i = u_bit_scan(&mask); + + if (instr->intrinsic == nir_intrinsic_load_work_group_id) + info->cs.uses_block_id[i] = true; + else + info->cs.uses_thread_id[i] = true; + } + break; + } + case nir_intrinsic_load_local_invocation_index: + case nir_intrinsic_load_subgroup_id: + case nir_intrinsic_load_num_subgroups: + info->cs.uses_local_invocation_idx = true; + break; + case nir_intrinsic_load_sample_id: + info->ps.force_persample = true; + break; + case nir_intrinsic_load_sample_pos: + info->ps.force_persample = true; + break; + case nir_intrinsic_load_view_index: + info->needs_multiview_view_index = true; + break; + case nir_intrinsic_load_invocation_id: + info->uses_invocation_id = true; + break; + case nir_intrinsic_load_primitive_id: + info->uses_prim_id = true; + break; + case nir_intrinsic_load_push_constant: + info->loads_push_constants = true; + break; + case nir_intrinsic_vulkan_resource_index: + info->desc_set_used_mask |= (1 << nir_intrinsic_desc_set(instr)); + break; + case nir_intrinsic_image_load: + case nir_intrinsic_image_store: + case nir_intrinsic_image_atomic_add: + case nir_intrinsic_image_atomic_min: + case nir_intrinsic_image_atomic_max: + case nir_intrinsic_image_atomic_and: + case nir_intrinsic_image_atomic_or: + case nir_intrinsic_image_atomic_xor: + case nir_intrinsic_image_atomic_exchange: + case nir_intrinsic_image_atomic_comp_swap: + case nir_intrinsic_image_size: { + const struct glsl_type *type = instr->variables[0]->var->type; + if(instr->variables[0]->deref.child) + type = instr->variables[0]->deref.child->type; + + enum glsl_sampler_dim dim = glsl_get_sampler_dim(type); + if (dim == GLSL_SAMPLER_DIM_SUBPASS || + dim == GLSL_SAMPLER_DIM_SUBPASS_MS) + info->ps.uses_input_attachments = true; + mark_sampler_desc(instr->variables[0]->var, info); + + if (nir_intrinsic_image_store || + nir_intrinsic_image_atomic_add || + nir_intrinsic_image_atomic_min || + nir_intrinsic_image_atomic_max || + nir_intrinsic_image_atomic_and || + nir_intrinsic_image_atomic_or || + nir_intrinsic_image_atomic_xor || + nir_intrinsic_image_atomic_exchange || + nir_intrinsic_image_atomic_comp_swap) { + if (nir->info.stage == MESA_SHADER_FRAGMENT) + info->ps.writes_memory = true; + } + break; + } + case nir_intrinsic_store_ssbo: + case nir_intrinsic_ssbo_atomic_add: + case nir_intrinsic_ssbo_atomic_imin: + case nir_intrinsic_ssbo_atomic_umin: + case nir_intrinsic_ssbo_atomic_imax: + case nir_intrinsic_ssbo_atomic_umax: + case nir_intrinsic_ssbo_atomic_and: + case nir_intrinsic_ssbo_atomic_or: + case nir_intrinsic_ssbo_atomic_xor: + case nir_intrinsic_ssbo_atomic_exchange: + case nir_intrinsic_ssbo_atomic_comp_swap: + if (nir->info.stage == MESA_SHADER_FRAGMENT) + info->ps.writes_memory = true; + break; + case nir_intrinsic_load_var: + if (nir->info.stage == MESA_SHADER_VERTEX) { + nir_deref_var *dvar = instr->variables[0]; + nir_variable *var = dvar->var; + + if (var->data.mode == nir_var_shader_in) { + unsigned idx = var->data.location; + uint8_t mask = + nir_ssa_def_components_read(&instr->dest.ssa) << var->data.location_frac; + info->vs.input_usage_mask[idx] |= mask; + } + } + break; + case nir_intrinsic_store_var: { + nir_deref_var *dvar = instr->variables[0]; + nir_variable *var = dvar->var; + + if (var->data.mode == nir_var_shader_out) { + unsigned idx = var->data.location; + unsigned comp = var->data.location_frac; + + if (nir->info.stage == MESA_SHADER_VERTEX) { + info->vs.output_usage_mask[idx] |= + instr->const_index[0] << comp; + } else if (nir->info.stage == MESA_SHADER_TESS_EVAL) { + info->tes.output_usage_mask[idx] |= + instr->const_index[0] << comp; + } + } + break; + } + default: + break; + } +} + +static void +gather_tex_info(const nir_shader *nir, const nir_tex_instr *instr, + struct radv_shader_info *info) +{ + if (instr->sampler) + mark_sampler_desc(instr->sampler->var, info); + if (instr->texture) + mark_sampler_desc(instr->texture->var, info); +} + +static void +gather_info_block(const nir_shader *nir, const nir_block *block, + struct radv_shader_info *info) +{ + nir_foreach_instr(instr, block) { + switch (instr->type) { + case nir_instr_type_intrinsic: + gather_intrinsic_info(nir, nir_instr_as_intrinsic(instr), info); + break; + case nir_instr_type_tex: + gather_tex_info(nir, nir_instr_as_tex(instr), info); + break; + default: + break; + } + } +} + +static void +gather_info_input_decl_vs(const nir_shader *nir, const nir_variable *var, + struct radv_shader_info *info) +{ + int idx = var->data.location; + + if (idx >= VERT_ATTRIB_GENERIC0 && idx <= VERT_ATTRIB_GENERIC15) + info->vs.has_vertex_buffers = true; +} + +static void +gather_info_input_decl_ps(const nir_shader *nir, const nir_variable *var, + struct radv_shader_info *info) +{ + const struct glsl_type *type = glsl_without_array(var->type); + int idx = var->data.location; + + switch (idx) { + case VARYING_SLOT_PNTC: + info->ps.has_pcoord = true; + break; + case VARYING_SLOT_PRIMITIVE_ID: + info->ps.prim_id_input = true; + break; + case VARYING_SLOT_LAYER: + info->ps.layer_input = true; + break; + default: + break; + } + + if (glsl_get_base_type(type) == GLSL_TYPE_FLOAT) { + if (var->data.sample) + info->ps.force_persample = true; + } +} + +static void +gather_info_input_decl(const nir_shader *nir, const nir_variable *var, + struct radv_shader_info *info) +{ + switch (nir->info.stage) { + case MESA_SHADER_VERTEX: + gather_info_input_decl_vs(nir, var, info); + break; + case MESA_SHADER_FRAGMENT: + gather_info_input_decl_ps(nir, var, info); + break; + default: + break; + } +} + +static void +gather_info_output_decl_ps(const nir_shader *nir, const nir_variable *var, + struct radv_shader_info *info) +{ + int idx = var->data.location; + + switch (idx) { + case FRAG_RESULT_DEPTH: + info->ps.writes_z = true; + break; + case FRAG_RESULT_STENCIL: + info->ps.writes_stencil = true; + break; + case FRAG_RESULT_SAMPLE_MASK: + info->ps.writes_sample_mask = true; + break; + default: + break; + } +} + +static void +gather_info_output_decl(const nir_shader *nir, const nir_variable *var, + struct radv_shader_info *info) +{ + switch (nir->info.stage) { + case MESA_SHADER_FRAGMENT: + gather_info_output_decl_ps(nir, var, info); + break; + default: + break; + } +} + +void +radv_nir_shader_info_pass(const struct nir_shader *nir, + const struct ac_nir_compiler_options *options, + struct radv_shader_info *info) +{ + struct nir_function *func = + (struct nir_function *)exec_list_get_head_const(&nir->functions); + + if (options->layout->dynamic_offset_count) + info->loads_push_constants = true; + + nir_foreach_variable(variable, &nir->inputs) + gather_info_input_decl(nir, variable, info); + + nir_foreach_block(block, func->impl) { + gather_info_block(nir, block, info); + } + + nir_foreach_variable(variable, &nir->outputs) + gather_info_output_decl(nir, variable, info); +} |