vkd3d-shader: Add support for SPV_EXT_demote_to_helper_invocation.

Requires SPIRV-Headers commit dcce859e34cf0c23625ec75ac44df750aa2f4d70.

Signed-off-by: Józef Kucia <jkucia@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Józef Kucia 2019-07-06 07:36:29 +02:00 committed by Alexandre Julliard
parent 46ff2c2764
commit 077e8b1459
3 changed files with 54 additions and 2 deletions

View File

@ -224,6 +224,13 @@ enum vkd3d_shader_target
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_TARGET), VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_TARGET),
}; };
enum vkd3d_shader_target_extension
{
VKD3D_SHADER_TARGET_EXTENSION_NONE,
VKD3D_SHADER_TARGET_EXTENSION_SPV_EXT_DEMOTE_TO_HELPER_INVOCATION,
};
struct vkd3d_shader_compile_arguments struct vkd3d_shader_compile_arguments
{ {
enum vkd3d_shader_structure_type type; enum vkd3d_shader_structure_type type;
@ -231,8 +238,11 @@ struct vkd3d_shader_compile_arguments
enum vkd3d_shader_target target; enum vkd3d_shader_target target;
unsigned int target_extension_count;
const enum vkd3d_shader_target_extension *target_extensions;
unsigned int parameter_count; unsigned int parameter_count;
struct vkd3d_shader_parameter *parameters; const struct vkd3d_shader_parameter *parameters;
bool dual_source_blending; bool dual_source_blending;
const unsigned int *output_swizzles; const unsigned int *output_swizzles;

View File

@ -266,6 +266,7 @@ struct vkd3d_spirv_builder
{ {
uint64_t capability_mask; uint64_t capability_mask;
uint64_t capability_draw_parameters : 1; uint64_t capability_draw_parameters : 1;
uint64_t capability_demote_to_helper_invocation : 1;
uint32_t ext_instr_set_glsl_450; uint32_t ext_instr_set_glsl_450;
SpvExecutionModel execution_model; SpvExecutionModel execution_model;
@ -311,6 +312,10 @@ static void vkd3d_spirv_enable_capability(struct vkd3d_spirv_builder *builder,
{ {
builder->capability_draw_parameters = 1; builder->capability_draw_parameters = 1;
} }
else if (cap == SpvCapabilityDemoteToHelperInvocationEXT)
{
builder->capability_demote_to_helper_invocation = 1;
}
else else
{ {
FIXME("Unhandled capability %#x.\n", cap); FIXME("Unhandled capability %#x.\n", cap);
@ -1222,6 +1227,11 @@ static void vkd3d_spirv_build_op_kill(struct vkd3d_spirv_builder *builder)
vkd3d_spirv_build_op(&builder->function_stream, SpvOpKill); vkd3d_spirv_build_op(&builder->function_stream, SpvOpKill);
} }
static void vkd3d_spirv_build_op_demote_to_helper_invocation(struct vkd3d_spirv_builder *builder)
{
vkd3d_spirv_build_op(&builder->function_stream, SpvOpDemoteToHelperInvocationEXT);
}
static void vkd3d_spirv_build_op_return(struct vkd3d_spirv_builder *builder) static void vkd3d_spirv_build_op_return(struct vkd3d_spirv_builder *builder)
{ {
vkd3d_spirv_build_op(&builder->function_stream, SpvOpReturn); vkd3d_spirv_build_op(&builder->function_stream, SpvOpReturn);
@ -1703,10 +1713,14 @@ static bool vkd3d_spirv_compile_module(struct vkd3d_spirv_builder *builder,
} }
if (builder->capability_draw_parameters) if (builder->capability_draw_parameters)
vkd3d_spirv_build_op_capability(&stream, SpvCapabilityDrawParameters); vkd3d_spirv_build_op_capability(&stream, SpvCapabilityDrawParameters);
if (builder->capability_demote_to_helper_invocation)
vkd3d_spirv_build_op_capability(&stream, SpvCapabilityDemoteToHelperInvocationEXT);
/* extensions */ /* extensions */
if (builder->capability_draw_parameters) if (builder->capability_draw_parameters)
vkd3d_spirv_build_op_extension(&stream, "SPV_KHR_shader_draw_parameters"); vkd3d_spirv_build_op_extension(&stream, "SPV_KHR_shader_draw_parameters");
if (builder->capability_demote_to_helper_invocation)
vkd3d_spirv_build_op_extension(&stream, "SPV_EXT_demote_to_helper_invocation");
if (builder->ext_instr_set_glsl_450) if (builder->ext_instr_set_glsl_450)
vkd3d_spirv_build_op_ext_inst_import(&stream, builder->ext_instr_set_glsl_450, "GLSL.std.450"); vkd3d_spirv_build_op_ext_inst_import(&stream, builder->ext_instr_set_glsl_450, "GLSL.std.450");
@ -2148,6 +2162,21 @@ static bool vkd3d_dxbc_compiler_is_opengl_target(const struct vkd3d_dxbc_compile
return vkd3d_dxbc_compiler_get_target(compiler) == VKD3D_SHADER_TARGET_SPIRV_OPENGL_4_5; return vkd3d_dxbc_compiler_get_target(compiler) == VKD3D_SHADER_TARGET_SPIRV_OPENGL_4_5;
} }
static bool vkd3d_dxbc_compiler_is_target_extension_supported(const struct vkd3d_dxbc_compiler *compiler,
enum vkd3d_shader_target_extension extension)
{
const struct vkd3d_shader_compile_arguments *args = compiler->compile_args;
unsigned int i;
for (i = 0; args && i < args->target_extension_count; ++i)
{
if (args->target_extensions[i] == extension)
return true;
}
return false;
}
static bool vkd3d_dxbc_compiler_check_shader_visibility(const struct vkd3d_dxbc_compiler *compiler, static bool vkd3d_dxbc_compiler_check_shader_visibility(const struct vkd3d_dxbc_compiler *compiler,
enum vkd3d_shader_visibility visibility) enum vkd3d_shader_visibility visibility)
{ {
@ -6477,7 +6506,18 @@ static void vkd3d_dxbc_compiler_emit_kill(struct vkd3d_dxbc_compiler *compiler,
merge_block_id = vkd3d_dxbc_compiler_emit_conditional_branch(compiler, instruction, target_id); merge_block_id = vkd3d_dxbc_compiler_emit_conditional_branch(compiler, instruction, target_id);
vkd3d_spirv_build_op_label(builder, target_id); vkd3d_spirv_build_op_label(builder, target_id);
vkd3d_spirv_build_op_kill(builder);
if (vkd3d_dxbc_compiler_is_target_extension_supported(compiler,
VKD3D_SHADER_TARGET_EXTENSION_SPV_EXT_DEMOTE_TO_HELPER_INVOCATION))
{
vkd3d_spirv_build_op_demote_to_helper_invocation(builder);
vkd3d_spirv_build_op_branch(builder, merge_block_id);
}
else
{
vkd3d_spirv_build_op_kill(builder);
}
vkd3d_spirv_build_op_label(builder, merge_block_id); vkd3d_spirv_build_op_label(builder, merge_block_id);
} }

View File

@ -2254,6 +2254,8 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
ps_compile_args.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_ARGUMENTS; ps_compile_args.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_ARGUMENTS;
ps_compile_args.next = NULL; ps_compile_args.next = NULL;
ps_compile_args.target = VKD3D_SHADER_TARGET_SPIRV_VULKAN_1_0; ps_compile_args.target = VKD3D_SHADER_TARGET_SPIRV_VULKAN_1_0;
ps_compile_args.target_extension_count = 0;
ps_compile_args.target_extensions = NULL;
ps_compile_args.parameter_count = ARRAY_SIZE(ps_shader_parameters); ps_compile_args.parameter_count = ARRAY_SIZE(ps_shader_parameters);
ps_compile_args.parameters = ps_shader_parameters; ps_compile_args.parameters = ps_shader_parameters;
ps_compile_args.dual_source_blending = is_dual_source_blending(&desc->BlendState.RenderTarget[0]); ps_compile_args.dual_source_blending = is_dual_source_blending(&desc->BlendState.RenderTarget[0]);