mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-09-13 09:16:14 -07:00
vkd3d-shader: Introduce struct vkd3d_shader_parameter_info and struct vkd3d_shader_parameter1.
As the newly added documentation describes, this reroll serves two purposes: * to allow shader parameters to be used for any target type (which allows using parameters for things like Direct3D 8-9 alpha test), * to allow the union in struct vkd3d_shader_parameter to contain types larger than 32 bits (by specifying them indirectly through a pointer).
This commit is contained in:
parent
bec4f413dc
commit
98def3214b
Notes:
Henri Verbeet
2024-07-11 17:16:48 +02:00
Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/870
@ -105,6 +105,11 @@ enum vkd3d_shader_structure_type
|
||||
* \since 1.10
|
||||
*/
|
||||
VKD3D_SHADER_STRUCTURE_TYPE_SCAN_COMBINED_RESOURCE_SAMPLER_INFO,
|
||||
/**
|
||||
* The structure is a vkd3d_shader_parameter_info structure.
|
||||
* \since 1.13
|
||||
*/
|
||||
VKD3D_SHADER_STRUCTURE_TYPE_PARAMETER_INFO,
|
||||
|
||||
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_STRUCTURE_TYPE),
|
||||
};
|
||||
@ -503,6 +508,20 @@ struct vkd3d_shader_parameter
|
||||
} u;
|
||||
};
|
||||
|
||||
struct vkd3d_shader_parameter1
|
||||
{
|
||||
enum vkd3d_shader_parameter_name name;
|
||||
enum vkd3d_shader_parameter_type type;
|
||||
enum vkd3d_shader_parameter_data_type data_type;
|
||||
union
|
||||
{
|
||||
struct vkd3d_shader_parameter_immediate_constant immediate_constant;
|
||||
struct vkd3d_shader_parameter_specialization_constant specialization_constant;
|
||||
void *_pointer_pad;
|
||||
uint32_t _pad[4];
|
||||
} u;
|
||||
};
|
||||
|
||||
/**
|
||||
* Symbolic register indices for mapping uniform constant register sets in
|
||||
* legacy Direct3D bytecode to constant buffer views in the target environment.
|
||||
@ -1994,6 +2013,44 @@ struct vkd3d_shader_varying_map_info
|
||||
unsigned int varying_count;
|
||||
};
|
||||
|
||||
/**
|
||||
* Interface information regarding a builtin shader parameter.
|
||||
*
|
||||
* Like compile options specified with struct vkd3d_shader_compile_option,
|
||||
* parameters are used to specify certain values which are not part of the
|
||||
* source shader bytecode but which need to be specified in the shader bytecode
|
||||
* in the target format.
|
||||
* Unlike struct vkd3d_shader_compile_option, however, this structure allows
|
||||
* parameters to be specified in a variety of different ways, as described by
|
||||
* enum vkd3d_shader_parameter_type.
|
||||
*
|
||||
* This structure is an extended version of struct vkd3d_shader_parameter as
|
||||
* used in struct vkd3d_shader_spirv_target_info, which allows more parameter
|
||||
* types to be used, and also allows specifying parameters when compiling
|
||||
* shaders to target types other than SPIR-V. If this structure is chained
|
||||
* along with vkd3d_shader_spirv_target_info, any parameters specified in the
|
||||
* latter structure are ignored.
|
||||
*
|
||||
* This structure is passed to vkd3d_shader_compile() and extends
|
||||
* vkd3d_shader_compile_info.
|
||||
*
|
||||
* This structure contains only input parameters.
|
||||
*
|
||||
* \since 1.13
|
||||
*/
|
||||
struct vkd3d_shader_parameter_info
|
||||
{
|
||||
/** Must be set to VKD3D_SHADER_STRUCTURE_TYPE_PARAMETER_INFO. */
|
||||
enum vkd3d_shader_structure_type type;
|
||||
/** Optional pointer to a structure containing further parameters. */
|
||||
const void *next;
|
||||
|
||||
/** Pointer to an array of dynamic parameters for this shader instance. */
|
||||
const struct vkd3d_shader_parameter1 *parameters;
|
||||
/** Size, in elements, of \ref parameters. */
|
||||
unsigned int parameter_count;
|
||||
};
|
||||
|
||||
#ifdef LIBVKD3D_SHADER_SOURCE
|
||||
# define VKD3D_SHADER_API VKD3D_EXPORT
|
||||
#else
|
||||
@ -2077,6 +2134,7 @@ VKD3D_SHADER_API const enum vkd3d_shader_target_type *vkd3d_shader_get_supported
|
||||
* - vkd3d_shader_descriptor_offset_info
|
||||
* - vkd3d_shader_hlsl_source_info
|
||||
* - vkd3d_shader_interface_info
|
||||
* - vkd3d_shader_parameter_info
|
||||
* - vkd3d_shader_preprocess_info
|
||||
* - vkd3d_shader_scan_combined_resource_sampler_info
|
||||
* - vkd3d_shader_scan_descriptor_info
|
||||
|
@ -1272,7 +1272,7 @@ static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1, st
|
||||
sm1->end = &code[token_count];
|
||||
|
||||
/* Estimate instruction count to avoid reallocation in most shaders. */
|
||||
if (!vsir_program_init(program, &version, code_size != ~(size_t)0 ? token_count / 4u + 4 : 16))
|
||||
if (!vsir_program_init(program, compile_info, &version, code_size != ~(size_t)0 ? token_count / 4u + 4 : 16))
|
||||
return VKD3D_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
vkd3d_shader_parser_init(&sm1->p, program, message_context, compile_info->source_name);
|
||||
|
@ -10206,12 +10206,13 @@ static struct sm6_function *sm6_parser_get_function(const struct sm6_parser *sm6
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_program *program, const char *source_name,
|
||||
static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_program *program,
|
||||
const struct vkd3d_shader_compile_info *compile_info,
|
||||
struct vkd3d_shader_message_context *message_context, struct dxbc_shader_desc *dxbc_desc)
|
||||
{
|
||||
size_t count, length, function_count, expected_function_count, byte_code_size = dxbc_desc->byte_code_size;
|
||||
const struct vkd3d_shader_location location = {.source_name = compile_info->source_name};
|
||||
struct shader_signature *patch_constant_signature, *output_signature, *input_signature;
|
||||
const struct vkd3d_shader_location location = {.source_name = source_name};
|
||||
uint32_t version_token, dxil_version, token_count, magic;
|
||||
const uint32_t *byte_code = dxbc_desc->byte_code;
|
||||
unsigned int chunk_offset, chunk_size;
|
||||
@ -10302,9 +10303,9 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro
|
||||
|
||||
/* Estimate instruction count to avoid reallocation in most shaders. */
|
||||
count = max(token_count, 400) - 400;
|
||||
if (!vsir_program_init(program, &version, (count + (count >> 2)) / 2u + 10))
|
||||
if (!vsir_program_init(program, compile_info, &version, (count + (count >> 2)) / 2u + 10))
|
||||
return VKD3D_ERROR_OUT_OF_MEMORY;
|
||||
vkd3d_shader_parser_init(&sm6->p, program, message_context, source_name);
|
||||
vkd3d_shader_parser_init(&sm6->p, program, message_context, compile_info->source_name);
|
||||
sm6->ptr = &sm6->start[1];
|
||||
sm6->bitpos = 2;
|
||||
|
||||
@ -10565,7 +10566,7 @@ int dxil_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t co
|
||||
dxbc_desc.byte_code = byte_code;
|
||||
}
|
||||
|
||||
ret = sm6_parser_init(&sm6, program, compile_info->source_name, message_context, &dxbc_desc);
|
||||
ret = sm6_parser_init(&sm6, program, compile_info, message_context, &dxbc_desc);
|
||||
free_dxbc_shader_desc(&dxbc_desc);
|
||||
vkd3d_free(byte_code);
|
||||
|
||||
|
@ -5691,7 +5691,7 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl
|
||||
version.major = ctx->profile->major_version;
|
||||
version.minor = ctx->profile->minor_version;
|
||||
version.type = ctx->profile->type;
|
||||
if (!vsir_program_init(program, &version, 0))
|
||||
if (!vsir_program_init(program, NULL, &version, 0))
|
||||
{
|
||||
ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
|
||||
return;
|
||||
|
@ -19,9 +19,73 @@
|
||||
#include "vkd3d_shader_private.h"
|
||||
#include "vkd3d_types.h"
|
||||
|
||||
bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_version *version, unsigned int reserve)
|
||||
static int convert_parameter_info(const struct vkd3d_shader_compile_info *compile_info,
|
||||
unsigned int *ret_count, const struct vkd3d_shader_parameter1 **ret_parameters)
|
||||
{
|
||||
const struct vkd3d_shader_spirv_target_info *spirv_info;
|
||||
struct vkd3d_shader_parameter1 *parameters;
|
||||
|
||||
*ret_count = 0;
|
||||
*ret_parameters = NULL;
|
||||
|
||||
if (!(spirv_info = vkd3d_find_struct(compile_info->next, SPIRV_TARGET_INFO)) || !spirv_info->parameter_count)
|
||||
return VKD3D_OK;
|
||||
|
||||
if (!(parameters = vkd3d_calloc(spirv_info->parameter_count, sizeof(*parameters))))
|
||||
return VKD3D_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
for (unsigned int i = 0; i < spirv_info->parameter_count; ++i)
|
||||
{
|
||||
const struct vkd3d_shader_parameter *src = &spirv_info->parameters[i];
|
||||
struct vkd3d_shader_parameter1 *dst = ¶meters[i];
|
||||
|
||||
dst->name = src->name;
|
||||
dst->type = src->type;
|
||||
dst->data_type = src->data_type;
|
||||
|
||||
if (src->type == VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT)
|
||||
{
|
||||
dst->u.immediate_constant = src->u.immediate_constant;
|
||||
}
|
||||
else if (src->type == VKD3D_SHADER_PARAMETER_TYPE_SPECIALIZATION_CONSTANT)
|
||||
{
|
||||
dst->u.specialization_constant = src->u.specialization_constant;
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR("Invalid parameter type %#x.\n", src->type);
|
||||
return VKD3D_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
}
|
||||
|
||||
*ret_count = spirv_info->parameter_count;
|
||||
*ret_parameters = parameters;
|
||||
|
||||
return VKD3D_OK;
|
||||
}
|
||||
|
||||
bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info,
|
||||
const struct vkd3d_shader_version *version, unsigned int reserve)
|
||||
{
|
||||
memset(program, 0, sizeof(*program));
|
||||
|
||||
if (compile_info)
|
||||
{
|
||||
const struct vkd3d_shader_parameter_info *parameter_info;
|
||||
|
||||
if ((parameter_info = vkd3d_find_struct(compile_info->next, PARAMETER_INFO)))
|
||||
{
|
||||
program->parameter_count = parameter_info->parameter_count;
|
||||
program->parameters = parameter_info->parameters;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (convert_parameter_info(compile_info, &program->parameter_count, &program->parameters) < 0)
|
||||
return false;
|
||||
program->free_parameters = true;
|
||||
}
|
||||
}
|
||||
|
||||
program->shader_version = *version;
|
||||
return shader_instruction_array_init(&program->instructions, reserve);
|
||||
}
|
||||
@ -30,6 +94,8 @@ void vsir_program_cleanup(struct vsir_program *program)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (program->free_parameters)
|
||||
vkd3d_free((void *)program->parameters);
|
||||
for (i = 0; i < program->block_name_count; ++i)
|
||||
vkd3d_free((void *)program->block_names[i]);
|
||||
vkd3d_free(program->block_names);
|
||||
|
@ -2418,6 +2418,8 @@ struct spirv_compiler
|
||||
uint32_t *descriptor_offset_ids;
|
||||
struct vkd3d_push_constant_buffer_binding *push_constants;
|
||||
const struct vkd3d_shader_spirv_target_info *spirv_target_info;
|
||||
const struct vkd3d_shader_parameter1 *parameters;
|
||||
unsigned int parameter_count;
|
||||
|
||||
bool prolog_emitted;
|
||||
struct shader_signature input_signature;
|
||||
@ -3290,16 +3292,15 @@ static uint32_t spirv_compiler_emit_array_variable(struct spirv_compiler *compil
|
||||
return vkd3d_spirv_build_op_variable(builder, stream, ptr_type_id, storage_class, 0);
|
||||
}
|
||||
|
||||
static const struct vkd3d_shader_parameter *spirv_compiler_get_shader_parameter(
|
||||
static const struct vkd3d_shader_parameter1 *spirv_compiler_get_shader_parameter(
|
||||
struct spirv_compiler *compiler, enum vkd3d_shader_parameter_name name)
|
||||
{
|
||||
const struct vkd3d_shader_spirv_target_info *info = compiler->spirv_target_info;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; info && i < info->parameter_count; ++i)
|
||||
for (i = 0; i < compiler->parameter_count; ++i)
|
||||
{
|
||||
if (info->parameters[i].name == name)
|
||||
return &info->parameters[i];
|
||||
if (compiler->parameters[i].name == name)
|
||||
return &compiler->parameters[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@ -3396,7 +3397,7 @@ static uint32_t spirv_compiler_get_spec_constant(struct spirv_compiler *compiler
|
||||
static uint32_t spirv_compiler_emit_uint_shader_parameter(struct spirv_compiler *compiler,
|
||||
enum vkd3d_shader_parameter_name name)
|
||||
{
|
||||
const struct vkd3d_shader_parameter *parameter;
|
||||
const struct vkd3d_shader_parameter1 *parameter;
|
||||
|
||||
if (!(parameter = spirv_compiler_get_shader_parameter(compiler, name)))
|
||||
{
|
||||
@ -10570,6 +10571,9 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, struct
|
||||
|
||||
spirv_compiler_emit_descriptor_declarations(compiler);
|
||||
|
||||
compiler->parameter_count = program->parameter_count;
|
||||
compiler->parameters = program->parameters;
|
||||
|
||||
if (program->block_count && !spirv_compiler_init_blocks(compiler, program->block_count))
|
||||
return VKD3D_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
|
@ -2493,7 +2493,7 @@ fail:
|
||||
}
|
||||
|
||||
static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, struct vsir_program *program,
|
||||
const uint32_t *byte_code, size_t byte_code_size, const char *source_name,
|
||||
const uint32_t *byte_code, size_t byte_code_size, const struct vkd3d_shader_compile_info *compile_info,
|
||||
struct vkd3d_shader_message_context *message_context)
|
||||
{
|
||||
struct vkd3d_shader_version version;
|
||||
@ -2552,9 +2552,9 @@ static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, struct vsir_pro
|
||||
version.minor = VKD3D_SM4_VERSION_MINOR(version_token);
|
||||
|
||||
/* Estimate instruction count to avoid reallocation in most shaders. */
|
||||
if (!vsir_program_init(program, &version, token_count / 7u + 20))
|
||||
if (!vsir_program_init(program, compile_info, &version, token_count / 7u + 20))
|
||||
return false;
|
||||
vkd3d_shader_parser_init(&sm4->p, program, message_context, source_name);
|
||||
vkd3d_shader_parser_init(&sm4->p, program, message_context, compile_info->source_name);
|
||||
sm4->ptr = sm4->start;
|
||||
|
||||
init_sm4_lookup_tables(&sm4->lookup);
|
||||
@ -2651,7 +2651,7 @@ int tpf_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t con
|
||||
}
|
||||
|
||||
if (!shader_sm4_init(&sm4, program, dxbc_desc.byte_code, dxbc_desc.byte_code_size,
|
||||
compile_info->source_name, message_context))
|
||||
compile_info, message_context))
|
||||
{
|
||||
WARN("Failed to initialise shader parser.\n");
|
||||
free_dxbc_shader_desc(&dxbc_desc);
|
||||
|
@ -1362,6 +1362,10 @@ struct vsir_program
|
||||
struct shader_signature output_signature;
|
||||
struct shader_signature patch_constant_signature;
|
||||
|
||||
unsigned int parameter_count;
|
||||
const struct vkd3d_shader_parameter1 *parameters;
|
||||
bool free_parameters;
|
||||
|
||||
unsigned int input_control_point_count, output_control_point_count;
|
||||
unsigned int flat_constant_count[3];
|
||||
unsigned int block_count;
|
||||
@ -1377,7 +1381,8 @@ void vsir_program_cleanup(struct vsir_program *program);
|
||||
int vsir_program_compile(struct vsir_program *program, uint64_t config_flags,
|
||||
const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out,
|
||||
struct vkd3d_shader_message_context *message_context);
|
||||
bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_version *version, unsigned int reserve);
|
||||
bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info,
|
||||
const struct vkd3d_shader_version *version, unsigned int reserve);
|
||||
enum vkd3d_result vsir_program_normalise(struct vsir_program *program, uint64_t config_flags,
|
||||
const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context);
|
||||
enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t config_flags,
|
||||
|
Loading…
Reference in New Issue
Block a user