From: Zebediah Figura Subject: [PATCH vkd3d 4/5] vkd3d-shader: Return the register space of each used UAV and UAV counter in vkd3d_shader_scan_info. Message-Id: <20200604014915.986832-4-zfigura@codeweavers.com> Date: Wed, 3 Jun 2020 20:49:14 -0500 In-Reply-To: <20200604014915.986832-1-zfigura@codeweavers.com> References: <20200604014915.986832-1-zfigura@codeweavers.com> Signed-off-by: Zebediah Figura --- include/vkd3d_shader.h | 10 ++++- libs/vkd3d-shader/spirv.c | 24 +++++++--- libs/vkd3d-shader/vkd3d_shader_main.c | 65 ++++++++++++++++++++++++--- libs/vkd3d/state.c | 26 +++++++---- 4 files changed, 102 insertions(+), 23 deletions(-) diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h index 67d4562..23c2cb7 100644 --- a/include/vkd3d_shader.h +++ b/include/vkd3d_shader.h @@ -539,13 +539,19 @@ struct vkd3d_versioned_root_signature_desc /* FIXME: Add support for 64 UAV bind slots. */ #define VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS 8 +struct vkd3d_uav_scan_info +{ + unsigned int register_space, register_index, id; + bool counter, read; +}; + struct vkd3d_shader_scan_info { enum vkd3d_shader_structure_type type; void *next; - unsigned int uav_read_mask; /* VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS */ - unsigned int uav_counter_mask; /* VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS */ + struct vkd3d_uav_scan_info uavs[VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS]; + unsigned int uav_count; unsigned int sampler_comparison_mode_mask; /* 16 */ bool use_vocp; }; diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 5a37b8f..ecca74c 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -5106,6 +5106,19 @@ static const struct vkd3d_spirv_resource_type *vkd3d_dxbc_compiler_enable_resour return resource_type_info; } +static const struct vkd3d_uav_scan_info *find_uav_scan_info( + const struct vkd3d_shader_scan_info *scan_info, unsigned int id) +{ + unsigned int i; + + for (i = 0; i < scan_info->uav_count; ++i) + { + if (scan_info->uavs[i].id == id) + return &scan_info->uavs[i]; + } + return NULL; +} + static SpvImageFormat image_format_for_image_read(enum vkd3d_component_type data_type) { /* The following formats are supported by Direct3D 11 hardware for UAV @@ -5130,14 +5143,13 @@ static uint32_t vkd3d_dxbc_compiler_get_image_type_id(struct vkd3d_dxbc_compiler const struct vkd3d_shader_register *reg, const struct vkd3d_spirv_resource_type *resource_type_info, enum vkd3d_component_type data_type, bool raw_structured, uint32_t depth) { - const struct vkd3d_shader_scan_info *scan_info = compiler->scan_info; + const struct vkd3d_uav_scan_info *uav_info = find_uav_scan_info(compiler->scan_info, reg->idx[0].offset); struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t sampled_type_id; SpvImageFormat format; format = SpvImageFormatUnknown; - if (reg->type == VKD3DSPR_UAV - && (raw_structured || (scan_info->uav_read_mask & (1u << reg->idx[0].offset)))) + if (reg->type == VKD3DSPR_UAV && (raw_structured || uav_info->read)) format = image_format_for_image_read(data_type); sampled_type_id = vkd3d_spirv_get_type_id(builder, data_type, 1); @@ -5214,8 +5226,8 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp enum vkd3d_shader_resource_type resource_type, enum vkd3d_data_type resource_data_type, unsigned int structure_stride, bool raw) { + const struct vkd3d_uav_scan_info *uav_info = find_uav_scan_info(compiler->scan_info, reg->idx[0].offset); uint32_t counter_type_id, type_id, ptr_type_id, var_id, counter_var_id = 0; - const struct vkd3d_shader_scan_info *scan_info = compiler->scan_info; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; SpvStorageClass storage_class = SpvStorageClassUniformConstant; const struct vkd3d_spirv_resource_type *resource_type_info; @@ -5251,10 +5263,10 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp vkd3d_dxbc_compiler_emit_register_debug_name(builder, var_id, reg); - if (is_uav && !(scan_info->uav_read_mask & (1u << reg->idx[0].offset))) + if (is_uav && !uav_info->read) vkd3d_spirv_build_op_decorate(builder, var_id, SpvDecorationNonReadable, NULL, 0); - if (is_uav && (scan_info->uav_counter_mask & (1u << reg->idx[0].offset))) + if (is_uav && uav_info->counter) { assert(structure_stride); /* counters are valid only for structured buffers */ diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index aa486cc..9ef84d4 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -22,9 +22,6 @@ VKD3D_DEBUG_ENV_NAME("VKD3D_SHADER_DEBUG"); -STATIC_ASSERT(MEMBER_SIZE(struct vkd3d_shader_scan_info, uav_counter_mask) * CHAR_BIT >= VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS); -STATIC_ASSERT(MEMBER_SIZE(struct vkd3d_shader_scan_info, uav_read_mask) * CHAR_BIT >= VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS); - static void vkd3d_shader_dump_blob(const char *path, const char *prefix, const void *data, size_t size) { static int shader_id = 0; @@ -205,11 +202,25 @@ static bool vkd3d_shader_instruction_is_uav_read(const struct vkd3d_shader_instr || (handler_idx == VKD3DSIH_LD_STRUCTURED && instruction->src[2].reg.type == VKD3DSPR_UAV); } +static struct vkd3d_uav_scan_info *find_uav_scan_info(struct vkd3d_shader_scan_info *scan_info, unsigned int id) +{ + unsigned int i; + + for (i = 0; i < scan_info->uav_count; ++i) + { + if (scan_info->uavs[i].id == id) + return &scan_info->uavs[i]; + } + return NULL; +} + static void vkd3d_shader_scan_record_uav_read(struct vkd3d_shader_scan_info *scan_info, const struct vkd3d_shader_register *reg) { - assert(reg->idx[0].offset < VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS); - scan_info->uav_read_mask |= 1u << reg->idx[0].offset; + struct vkd3d_uav_scan_info *uav_info = find_uav_scan_info(scan_info, reg->idx[0].offset); + + assert(uav_info); + uav_info->read = true; } static bool vkd3d_shader_instruction_is_uav_counter(const struct vkd3d_shader_instruction *instruction) @@ -222,8 +233,10 @@ static bool vkd3d_shader_instruction_is_uav_counter(const struct vkd3d_shader_in static void vkd3d_shader_scan_record_uav_counter(struct vkd3d_shader_scan_info *scan_info, const struct vkd3d_shader_register *reg) { - assert(reg->idx[0].offset < VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS); - scan_info->uav_counter_mask |= 1u << reg->idx[0].offset; + struct vkd3d_uav_scan_info *uav_info = find_uav_scan_info(scan_info, reg->idx[0].offset); + + assert(uav_info); + uav_info->counter = true; } static void vkd3d_shader_scan_input_declaration(struct vkd3d_shader_scan_info *scan_info, @@ -246,6 +259,39 @@ static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_info } } +static void vkd3d_shader_scan_uav_declaration(struct vkd3d_shader_scan_info *scan_info, + const struct vkd3d_shader_instruction *instruction) +{ + unsigned int register_space, register_index, id; + struct vkd3d_uav_scan_info *uav_info; + + assert(scan_info->uav_count < VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS); + + if (instruction->handler_idx == VKD3DSIH_DCL_UAV_RAW) + { + register_space = instruction->declaration.raw_resource.register_space; + register_index = instruction->declaration.raw_resource.register_index; + id = instruction->declaration.raw_resource.dst.reg.idx[0].offset; + } + else if (instruction->handler_idx == VKD3DSIH_DCL_UAV_STRUCTURED) + { + register_space = instruction->declaration.structured_resource.register_space; + register_index = instruction->declaration.structured_resource.register_index; + id = instruction->declaration.structured_resource.reg.reg.idx[0].offset; + } + else /* VKD3DSIH_DCL_UAV_TYPED */ + { + register_space = instruction->declaration.semantic.register_space; + register_index = instruction->declaration.semantic.register_index; + id = instruction->declaration.semantic.reg.reg.idx[0].offset; + } + + uav_info = &scan_info->uavs[scan_info->uav_count++]; + uav_info->register_space = register_space; + uav_info->register_index = register_index; + uav_info->id = id; +} + static void vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_info *scan_info, const struct vkd3d_shader_instruction *instruction) { @@ -259,6 +305,11 @@ static void vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_info *scan_in case VKD3DSIH_DCL_SAMPLER: vkd3d_shader_scan_sampler_declaration(scan_info, instruction); break; + case VKD3DSIH_DCL_UAV_RAW: + case VKD3DSIH_DCL_UAV_STRUCTURED: + case VKD3DSIH_DCL_UAV_TYPED: + vkd3d_shader_scan_uav_declaration(scan_info, instruction); + break; default: break; } diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index 11db8b5..4bd4ef7 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -1405,11 +1405,17 @@ static HRESULT d3d12_pipeline_state_init_compute_uav_counters(struct d3d12_pipel struct vkd3d_descriptor_set_context context; VkDescriptorSetLayoutBinding *binding_desc; VkDescriptorSetLayout set_layouts[3]; - unsigned int uav_counter_count; + unsigned int uav_counter_count = 0; unsigned int i, j; HRESULT hr; - if (!(uav_counter_count = vkd3d_popcount(shader_info->uav_counter_mask))) + for (i = 0; i < shader_info->uav_count; ++i) + { + if (shader_info->uavs[i].counter) + ++uav_counter_count; + } + + if (!uav_counter_count) return S_OK; if (!(binding_desc = vkd3d_calloc(uav_counter_count, sizeof(*binding_desc)))) @@ -1427,13 +1433,13 @@ static HRESULT d3d12_pipeline_state_init_compute_uav_counters(struct d3d12_pipel if (root_signature->vk_set_layout) set_layouts[context.set_index++] = root_signature->vk_set_layout; - for (i = 0, j = 0; i < VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS; ++i) + for (i = 0, j = 0; i < shader_info->uav_count; ++i) { - if (!(shader_info->uav_counter_mask & (1u << i))) + if (!shader_info->uavs[i].counter) continue; - state->uav_counters[j].register_space = 0; - state->uav_counters[j].register_index = i; + state->uav_counters[j].register_space = shader_info->uavs[i].register_space; + state->uav_counters[j].register_index = shader_info->uavs[i].register_index; state->uav_counters[j].shader_visibility = VKD3D_SHADER_VISIBILITY_COMPUTE; state->uav_counters[j].binding.set = context.set_index; state->uav_counters[j].binding.binding = context.descriptor_binding; @@ -2256,8 +2262,12 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s hr = hresult_from_vkd3d_result(ret); goto fail; } - if (shader_info.uav_counter_mask) - FIXME("UAV counters not implemented for graphics pipelines.\n"); + + for (j = 0; j < shader_info.uav_count; ++j) + { + if (shader_info.uavs[j].counter) + FIXME("UAV counters not implemented for graphics pipelines.\n"); + } compile_args = NULL; switch (shader_stages[i].stage) -- 2.26.2