From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- include/vkd3d_shader.h | 1 + libs/vkd3d-shader/spirv.c | 72 ++++++++++++++++++++------- libs/vkd3d-shader/vkd3d_shader_main.c | 22 +++++++- 3 files changed, 75 insertions(+), 20 deletions(-)
diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h index fe6f6e9c43c2..e803237c1f29 100644 --- a/include/vkd3d_shader.h +++ b/include/vkd3d_shader.h @@ -404,6 +404,7 @@ struct vkd3d_shader_scan_info unsigned int uav_read_mask; /* VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS */ unsigned int uav_counter_mask; /* VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS */ unsigned int sampler_comparison_mode_mask; /* 16 */ + bool use_vocp; };
int vkd3d_shader_scan_dxbc(const struct vkd3d_shader_code *dxbc, diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index d6d487b51ecf..3a80925a0e8b 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -4853,10 +4853,52 @@ static int vkd3d_dxbc_compiler_emit_shader_phase_instance_count(struct vkd3d_dxb return VKD3D_OK; }
+static const struct vkd3d_shader_phase *vkd3d_dxbc_compiler_get_control_point_phase( + struct vkd3d_dxbc_compiler *compiler) +{ + const struct vkd3d_shader_phase *phase; + + if (compiler->shader_phase_count < 1) + return NULL; + + phase = &compiler->shader_phases[0]; + if (phase->type == VKD3DSIH_HS_CONTROL_POINT_PHASE) + return phase; + + return NULL; +} + +static void vkd3d_dxbc_compiler_emit_barrier(struct vkd3d_dxbc_compiler *compiler, + SpvScope execution_scope, SpvScope memory_scope, SpvMemorySemanticsMask semantics) +{ + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + uint32_t execution_id, memory_id, semantics_id; + + memory_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, memory_scope); + semantics_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, semantics); + + if (execution_scope != SpvScopeMax) + { + execution_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, execution_scope); + vkd3d_spirv_build_op_control_barrier(builder, execution_id, memory_id, semantics_id); + } + else + { + vkd3d_spirv_build_op_memory_barrier(builder, memory_id, semantics_id); + } +} + +static void vkd3d_dxbc_compiler_emit_hull_shader_barrier(struct vkd3d_dxbc_compiler *compiler) +{ + vkd3d_dxbc_compiler_emit_barrier(compiler, + SpvScopeWorkgroup, SpvScopeInvocation, SpvMemorySemanticsMaskNone); +} + static void vkd3d_dxbc_compiler_emit_hull_shader_main(struct vkd3d_dxbc_compiler *compiler) { + const struct vkd3d_shader_scan_info *scan_info = compiler->scan_info; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - const struct vkd3d_shader_phase *phase; + const struct vkd3d_shader_phase *control_point_phase, *phase; uint32_t phase_instance_id; unsigned int i, j; uint32_t void_id; @@ -4864,9 +4906,18 @@ static void vkd3d_dxbc_compiler_emit_hull_shader_main(struct vkd3d_dxbc_compiler vkd3d_spirv_builder_begin_main_function(builder);
void_id = vkd3d_spirv_get_op_type_void(builder); + + if ((control_point_phase = vkd3d_dxbc_compiler_get_control_point_phase(compiler))) + vkd3d_spirv_build_op_function_call(builder, void_id, control_point_phase->function_id, NULL, 0); + + if (scan_info->use_vocp) + vkd3d_dxbc_compiler_emit_hull_shader_barrier(compiler); + for (i = 0; i < compiler->shader_phase_count; ++i) { phase = &compiler->shader_phases[i]; + if (phase->type == VKD3DSIH_HS_CONTROL_POINT_PHASE) + continue;
if (phase->instance_count) { @@ -6968,14 +7019,10 @@ static void vkd3d_dxbc_compiler_emit_sample_info(struct vkd3d_dxbc_compiler *com static void vkd3d_dxbc_compiler_emit_sync(struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - uint32_t execution_id, memory_id, semantics_id; + unsigned int memory_semantics = SpvMemorySemanticsAcquireReleaseMask; unsigned int flags = instruction->flags; SpvScope execution_scope = SpvScopeMax; SpvScope memory_scope = SpvScopeDevice; - unsigned int memory_semantics; - - memory_semantics = SpvMemorySemanticsAcquireReleaseMask;
if (flags & VKD3DSSF_GROUP_SHARED_MEMORY) { @@ -7003,18 +7050,7 @@ static void vkd3d_dxbc_compiler_emit_sync(struct vkd3d_dxbc_compiler *compiler, | SpvMemorySemanticsImageMemoryMask; }
- memory_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, memory_scope); - semantics_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, memory_semantics); - if (execution_scope != SpvScopeMax) - { - execution_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, execution_scope); - vkd3d_spirv_build_op_control_barrier(builder, - execution_id, memory_id, semantics_id); - } - else - { - vkd3d_spirv_build_op_memory_barrier(builder, memory_id, semantics_id); - } + vkd3d_dxbc_compiler_emit_barrier(compiler, execution_scope, memory_scope, memory_semantics); }
static void vkd3d_dxbc_compiler_emit_emit_stream(struct vkd3d_dxbc_compiler *compiler, diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index 2bfdad0641cc..770281ca5ae8 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -226,6 +226,15 @@ static void vkd3d_shader_scan_record_uav_counter(struct vkd3d_shader_scan_info * scan_info->uav_counter_mask |= 1u << reg->idx[0].offset; }
+static void vkd3d_shader_scan_input_declaration(struct vkd3d_shader_scan_info *scan_info, + const struct vkd3d_shader_instruction *instruction) +{ + const struct vkd3d_shader_dst_param *dst = &instruction->declaration.dst; + + if (dst->reg.type == VKD3DSPR_OUTCONTROLPOINT) + scan_info->use_vocp = true; +} + static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_info *scan_info, const struct vkd3d_shader_instruction *instruction) { @@ -242,8 +251,17 @@ static void vkd3d_shader_scan_handle_instruction(struct vkd3d_shader_scan_info * { unsigned int i;
- if (instruction->handler_idx == VKD3DSIH_DCL_SAMPLER) - vkd3d_shader_scan_sampler_declaration(scan_info, instruction); + switch (instruction->handler_idx) + { + case VKD3DSIH_DCL_INPUT: + vkd3d_shader_scan_input_declaration(scan_info, instruction); + break; + case VKD3DSIH_DCL_SAMPLER: + vkd3d_shader_scan_sampler_declaration(scan_info, instruction); + break; + default: + break; + }
if (vkd3d_shader_instruction_is_uav_read(instruction)) {