From ea4dd223090f53865bb62086902606160b5e5877 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Thu, 7 Feb 2019 09:59:15 +0100 Subject: [PATCH] vkd3d-shader: Add support for instanced fork phases. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Józef Kucia Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- libs/vkd3d-shader/spirv.c | 62 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 4 deletions(-) diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index e1ea2361..f14306e6 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -1910,6 +1910,7 @@ struct vkd3d_shader_phase unsigned int idx; unsigned int instance_count; uint32_t function_id; + uint32_t instance_id; size_t function_location; }; @@ -3836,16 +3837,31 @@ static void vkd3d_dxbc_compiler_begin_shader_phase(struct vkd3d_dxbc_compiler *c { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t void_id, function_type_id; + unsigned int param_count; + uint32_t param_type_id; const char *name; + if (phase->instance_count) + { + param_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_UINT, 1); + param_count = 1; + } + else + { + param_count = 0; + } + phase->function_id = vkd3d_spirv_alloc_id(builder); void_id = vkd3d_spirv_get_op_type_void(builder); - function_type_id = vkd3d_spirv_get_op_type_function(builder, void_id, NULL, 0); + function_type_id = vkd3d_spirv_get_op_type_function(builder, void_id, ¶m_type_id, param_count); vkd3d_spirv_build_op_function(builder, void_id, phase->function_id, SpvFunctionControlMaskNone, function_type_id); - vkd3d_spirv_build_op_label(builder, vkd3d_spirv_alloc_id(builder)); + if (phase->instance_count) + phase->instance_id = vkd3d_spirv_build_op_function_parameter(builder, param_type_id); + + vkd3d_spirv_build_op_label(builder, vkd3d_spirv_alloc_id(builder)); phase->function_location = vkd3d_spirv_stream_current_location(&builder->function_stream); switch (phase->type) @@ -4765,15 +4781,37 @@ static void vkd3d_dxbc_compiler_enter_shader_phase(struct vkd3d_dxbc_compiler *c phase->idx = idx; phase->instance_count = 0; phase->function_id = 0; + phase->instance_id = 0; phase->function_location = 0; } +static int vkd3d_dxbc_compiler_emit_hs_fork_phase_instance_count(struct vkd3d_dxbc_compiler *compiler, + const struct vkd3d_shader_instruction *instruction) +{ + struct vkd3d_shader_phase *phase = &compiler->shader_phases[compiler->shader_phase_count - 1]; + + if (!compiler->shader_phase_count + || phase->type != VKD3DSIH_HS_FORK_PHASE + || phase->function_id) + { + WARN("Unexpected dcl_hs_fork_phase_instance_count instruction.\n"); + return VKD3D_ERROR_INVALID_SHADER; + } + + phase->instance_count = instruction->declaration.count; + + vkd3d_dxbc_compiler_begin_shader_phase(compiler, phase); + + return VKD3D_OK; +} + static void vkd3d_dxbc_compiler_emit_hull_shader_main(struct vkd3d_dxbc_compiler *compiler) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; const struct vkd3d_shader_phase *phase; + uint32_t phase_instance_id; + unsigned int i, j; uint32_t void_id; - unsigned int i; vkd3d_spirv_builder_begin_main_function(builder); @@ -4781,7 +4819,20 @@ static void vkd3d_dxbc_compiler_emit_hull_shader_main(struct vkd3d_dxbc_compiler for (i = 0; i < compiler->shader_phase_count; ++i) { phase = &compiler->shader_phases[i]; - vkd3d_spirv_build_op_function_call(builder, void_id, phase->function_id, NULL, 0); + + if (phase->instance_count) + { + for (j = 0; j < phase->instance_count; ++j) + { + phase_instance_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, j); + vkd3d_spirv_build_op_function_call(builder, + void_id, phase->function_id, &phase_instance_id, 1); + } + } + else + { + vkd3d_spirv_build_op_function_call(builder, void_id, phase->function_id, NULL, 0); + } } vkd3d_spirv_build_op_return(builder); @@ -7074,6 +7125,9 @@ int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler, case VKD3DSIH_DCL_THREAD_GROUP: vkd3d_dxbc_compiler_emit_dcl_thread_group(compiler, instruction); break; + case VKD3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT: + ret = vkd3d_dxbc_compiler_emit_hs_fork_phase_instance_count(compiler, instruction); + break; case VKD3DSIH_HS_CONTROL_POINT_PHASE: case VKD3DSIH_HS_FORK_PHASE: case VKD3DSIH_HS_JOIN_PHASE: