vkd3d-shader: Add INVARIANT_POSITION quirk.

Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
This commit is contained in:
Hans-Kristian Arntzen 2021-10-12 15:19:25 +02:00
parent 2152500014
commit 32c5abf496
3 changed files with 34 additions and 9 deletions

View File

@ -307,6 +307,10 @@ enum vkd3d_shader_quirk
/* After every write to group shared memory, force a memory barrier.
* This works around buggy games which forget to use barrier(). */
VKD3D_SHADER_QUIRK_FORCE_TGSM_BARRIERS = (1 << 1),
/* For Position builtins in Output storage class, emit Invariant decoration.
* Normally, games have to emit Precise math for position, but if they forget ... */
VKD3D_SHADER_QUIRK_INVARIANT_POSITION = (1 << 2),
};
struct vkd3d_shader_quirk_hash

View File

@ -490,6 +490,7 @@ int vkd3d_shader_compile_dxil(const struct vkd3d_shader_code *dxbc,
unsigned int i, max_size;
vkd3d_shader_hash_t hash;
int ret = VKD3D_OK;
uint32_t quirks;
void *code;
dxil_spv_set_thread_log_callback(vkd3d_dxil_log_callback, NULL);
@ -502,6 +503,7 @@ int vkd3d_shader_compile_dxil(const struct vkd3d_shader_code *dxbc,
spirv->meta.replaced = true;
return ret;
}
quirks = vkd3d_shader_compile_arguments_select_quirks(compiler_args, hash);
dxil_spv_begin_thread_allocator_context();
@ -760,6 +762,18 @@ int vkd3d_shader_compile_dxil(const struct vkd3d_shader_code *dxbc,
}
}
if (quirks & VKD3D_SHADER_QUIRK_INVARIANT_POSITION)
{
const dxil_spv_option_invariant_position helper =
{ { DXIL_SPV_OPTION_INVARIANT_POSITION }, DXIL_SPV_TRUE };
if (dxil_spv_converter_add_option(converter, &helper.base) != DXIL_SPV_SUCCESS)
{
ERR("dxil-spirv does not support INVARIANT_POSITION.\n");
ret = VKD3D_ERROR_NOT_IMPLEMENTED;
goto end;
}
}
remap_userdata.shader_interface_info = shader_interface_info;
remap_userdata.shader_interface_local_info = NULL;
remap_userdata.num_root_descriptors = num_root_descriptors;

View File

@ -3845,8 +3845,14 @@ static void vkd3d_dxbc_compiler_emit_store_dst_scalar(struct vkd3d_dxbc_compiler
vkd3d_dxbc_compiler_emit_store_dst_components(compiler, dst, component_type, component_ids);
}
static bool vkd3d_dxbc_compiler_has_quirk(struct vkd3d_dxbc_compiler *compiler,
enum vkd3d_shader_quirk quirk)
{
return !!(compiler->quirks & quirk);
}
static void vkd3d_dxbc_compiler_decorate_builtin(struct vkd3d_dxbc_compiler *compiler,
uint32_t target_id, SpvBuiltIn builtin)
uint32_t target_id, SpvBuiltIn builtin, SpvStorageClass storage_class)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
@ -3883,6 +3889,13 @@ static void vkd3d_dxbc_compiler_decorate_builtin(struct vkd3d_dxbc_compiler *com
case SpvBuiltInCullDistance:
vkd3d_spirv_enable_capability(builder, SpvCapabilityCullDistance);
break;
case SpvBuiltInPosition:
if (storage_class == SpvStorageClassOutput &&
vkd3d_dxbc_compiler_has_quirk(compiler, VKD3D_SHADER_QUIRK_INVARIANT_POSITION))
{
vkd3d_spirv_build_op_decorate(builder, target_id, SpvDecorationInvariant, NULL, 0);
}
break;
default:
break;
}
@ -3961,7 +3974,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_draw_parameter_fixup(struct vkd3d_dxbc_
base_var_id = vkd3d_dxbc_compiler_emit_variable(compiler, &builder->global_stream,
SpvStorageClassInput, VKD3D_TYPE_INT, 1);
vkd3d_spirv_add_iface_variable(builder, base_var_id);
vkd3d_dxbc_compiler_decorate_builtin(compiler, base_var_id, base);
vkd3d_dxbc_compiler_decorate_builtin(compiler, base_var_id, base, SpvStorageClassInput);
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_INT, 1);
base_id = vkd3d_spirv_build_op_load(builder,
@ -4364,7 +4377,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_builtin_variable(struct vkd3d_dxbc_comp
&builder->global_stream, storage_class,
builtin->component_type, builtin->component_count, array_size);
vkd3d_spirv_add_iface_variable(builder, id);
vkd3d_dxbc_compiler_decorate_builtin(compiler, id, builtin->spirv_builtin);
vkd3d_dxbc_compiler_decorate_builtin(compiler, id, builtin->spirv_builtin, storage_class);
if (compiler->shader_type == VKD3D_SHADER_TYPE_PIXEL && storage_class == SpvStorageClassInput
&& builtin->component_type != VKD3D_TYPE_FLOAT && builtin->component_type != VKD3D_TYPE_BOOL)
@ -9065,12 +9078,6 @@ static void vkd3d_dxbc_compiler_emit_lod(struct vkd3d_dxbc_compiler *compiler,
dst, val_id, image.sampled_type, resource->swizzle);
}
static bool vkd3d_dxbc_compiler_has_quirk(struct vkd3d_dxbc_compiler *compiler,
enum vkd3d_shader_quirk quirk)
{
return !!(compiler->quirks & quirk);
}
static void vkd3d_dxbc_compiler_emit_sample(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_instruction *instruction)
{