Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ValveSoftware/vkd3d.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Rebohle <philip.rebohle@tu-dortmund.de>2019-10-24 20:28:14 +0300
committerAlexandre Julliard <julliard@winehq.org>2019-10-27 21:17:26 +0300
commita08ee1e2dfd60f519275ef41600dbb5d78970f82 (patch)
tree31469ebc476c50006bceec7e6d3f4417def83e16
parent3fe9997010ddff1b491b85614b2c7cd955d0a096 (diff)
vkd3d-shader: Use private array variable for patch constant outputs.
Fork and join phases in hull shaders allow dynamic indexing for all output registers, not just the tessellation factor built-ins. Moreover, the patch constant output register space is shared with join phases, which can read back the outputs computed in the fork phases, also allowing dynamic indexing. In order to support this in a not overly complex way, use a private array representing the entire patch constant space, and use epilogue functions to assign them to the actual output variables. Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
-rw-r--r--libs/vkd3d-shader/spirv.c38
1 files changed, 35 insertions, 3 deletions
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 261a1453..6a3eb10c 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -2029,6 +2029,7 @@ struct vkd3d_hull_shader_variables
{
uint32_t tess_level_outer_id;
uint32_t tess_level_inner_id;
+ uint32_t patch_constants_id;
};
struct vkd3d_dxbc_compiler
@@ -4322,7 +4323,8 @@ static void vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *compiler
write_mask = dst->write_mask;
else if (get_shader_output_swizzle(compiler, signature_element->register_index) != VKD3D_NO_SWIZZLE
|| needs_private_io_variable(shader_signature, signature_element->register_index,
- builtin, &output_component_count, &write_mask))
+ builtin, &output_component_count, &write_mask)
+ || is_patch_constant)
{
use_private_variable = true;
write_mask = VKD3DSP_WRITEMASK_ALL;
@@ -4393,6 +4395,8 @@ static void vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *compiler
var_id = RB_ENTRY_VALUE(entry, const struct vkd3d_symbol, entry)->id;
else if (!use_private_variable)
var_id = id;
+ else if (is_patch_constant)
+ var_id = compiler->hs.patch_constants_id;
else
var_id = vkd3d_dxbc_compiler_emit_variable(compiler, &builder->global_stream,
storage_class, VKD3D_TYPE_FLOAT, VKD3D_VEC4_SIZE);
@@ -4400,15 +4404,21 @@ static void vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *compiler
{
vkd3d_symbol_set_register_info(&reg_symbol, var_id, storage_class,
use_private_variable ? VKD3D_TYPE_FLOAT : component_type, write_mask);
- reg_symbol.info.reg.is_aggregate = use_private_variable ? false : array_size;
+ reg_symbol.info.reg.is_aggregate = use_private_variable ? is_patch_constant : array_size;
if (!use_private_variable && is_control_point_phase(phase))
{
reg_symbol.info.reg.member_idx = vkd3d_dxbc_compiler_get_invocation_id(compiler);
reg_symbol.info.reg.is_dynamically_indexed = true;
}
+ else if (is_patch_constant)
+ {
+ reg_symbol.info.reg.member_idx = reg->idx[0].offset;
+ }
+
vkd3d_dxbc_compiler_put_symbol(compiler, &reg_symbol);
- vkd3d_dxbc_compiler_emit_register_debug_name(builder, var_id, reg);
+ if (!is_patch_constant)
+ vkd3d_dxbc_compiler_emit_register_debug_name(builder, var_id, reg);
}
if (use_private_variable)
@@ -4416,6 +4426,9 @@ static void vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *compiler
unsigned int idx = vkd3d_dxbc_compiler_get_output_variable_index(compiler, reg->idx[0].offset);
compiler->private_output_variable[idx] = var_id;
compiler->private_output_variable_write_mask[idx] |= dst->write_mask;
+ if (is_patch_constant)
+ compiler->private_output_variable_array_idx[idx] = vkd3d_dxbc_compiler_get_constant_uint(
+ compiler, reg->idx[0].offset);
if (!compiler->epilogue_function_id)
compiler->epilogue_function_id = vkd3d_spirv_alloc_id(builder);
}
@@ -4626,6 +4639,24 @@ static void vkd3d_dxbc_compiler_emit_hull_shader_builtins(struct vkd3d_dxbc_comp
vkd3d_dxbc_compiler_emit_input_register(compiler, &dst);
}
+static void vkd3d_dxbc_compiler_emit_hull_shader_patch_constants(struct vkd3d_dxbc_compiler *compiler)
+{
+ const struct vkd3d_shader_signature *signature = compiler->patch_constant_signature;
+ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
+ uint32_t register_count = 0;
+ unsigned int signature_idx;
+
+ for (signature_idx = 0; signature_idx < signature->element_count; ++signature_idx)
+ register_count = max(register_count, signature->elements[signature_idx].register_index + 1);
+
+ if (!register_count)
+ return;
+
+ compiler->hs.patch_constants_id = vkd3d_dxbc_compiler_emit_array_variable(compiler, &builder->global_stream,
+ SpvStorageClassPrivate, VKD3D_TYPE_FLOAT, VKD3D_VEC4_SIZE, register_count);
+ vkd3d_spirv_build_op_name(builder, compiler->hs.patch_constants_id, "opc");
+}
+
static void vkd3d_dxbc_compiler_emit_initial_declarations(struct vkd3d_dxbc_compiler *compiler)
{
const struct vkd3d_shader_transform_feedback_info *xfb_info = compiler->xfb_info;
@@ -4639,6 +4670,7 @@ static void vkd3d_dxbc_compiler_emit_initial_declarations(struct vkd3d_dxbc_comp
case VKD3D_SHADER_TYPE_HULL:
vkd3d_spirv_set_execution_model(builder, SpvExecutionModelTessellationControl);
vkd3d_dxbc_compiler_emit_hull_shader_builtins(compiler);
+ vkd3d_dxbc_compiler_emit_hull_shader_patch_constants(compiler);
break;
case VKD3D_SHADER_TYPE_DOMAIN:
vkd3d_spirv_set_execution_model(builder, SpvExecutionModelTessellationEvaluation);