mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-01-28 13:05:02 -08:00
vkd3d-shader/tpf: Use the I/O signatures from the vsir program in tpf_write_signature().
This commit is contained in:
parent
10442369d8
commit
c75fbaf94e
Notes:
Henri Verbeet
2024-10-16 21:46:52 +02:00
Approved-by: Elizabeth Figura (@zfigura) Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1152
@ -6276,23 +6276,109 @@ void hlsl_run_const_passes(struct hlsl_ctx *ctx, struct hlsl_block *body)
|
|||||||
} while (progress);
|
} while (progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sm1_generate_vsir_signature_entry(struct hlsl_ctx *ctx,
|
static void generate_vsir_signature_entry(struct hlsl_ctx *ctx,
|
||||||
struct vsir_program *program, bool output, struct hlsl_ir_var *var)
|
struct vsir_program *program, bool output, struct hlsl_ir_var *var)
|
||||||
{
|
{
|
||||||
enum vkd3d_shader_sysval_semantic sysval = VKD3D_SHADER_SV_NONE;
|
enum vkd3d_shader_sysval_semantic sysval = VKD3D_SHADER_SV_NONE;
|
||||||
|
enum vkd3d_shader_component_type component_type;
|
||||||
|
unsigned int register_index, mask, use_mask;
|
||||||
|
const char *name = var->semantic.name;
|
||||||
enum vkd3d_shader_register_type type;
|
enum vkd3d_shader_register_type type;
|
||||||
struct shader_signature *signature;
|
struct shader_signature *signature;
|
||||||
struct signature_element *element;
|
struct signature_element *element;
|
||||||
unsigned int register_index, mask;
|
|
||||||
|
|
||||||
if ((!output && !var->last_read) || (output && !var->first_write))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (output)
|
if (output)
|
||||||
signature = &program->output_signature;
|
signature = &program->output_signature;
|
||||||
else
|
else
|
||||||
signature = &program->input_signature;
|
signature = &program->input_signature;
|
||||||
|
|
||||||
|
if (hlsl_version_ge(ctx, 4, 0))
|
||||||
|
{
|
||||||
|
struct vkd3d_string_buffer *string;
|
||||||
|
bool has_idx, ret;
|
||||||
|
|
||||||
|
ret = sysval_semantic_from_hlsl(&sysval, ctx, &var->semantic, output);
|
||||||
|
VKD3D_ASSERT(ret);
|
||||||
|
if (sysval == ~0u)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (hlsl_sm4_register_from_semantic(ctx, &var->semantic, output, &type, &has_idx))
|
||||||
|
{
|
||||||
|
register_index = has_idx ? var->semantic.index : ~0u;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VKD3D_ASSERT(var->regs[HLSL_REGSET_NUMERIC].allocated);
|
||||||
|
register_index = var->regs[HLSL_REGSET_NUMERIC].id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NOTE: remember to change this to the actually allocated mask once
|
||||||
|
* we start optimizing interstage signatures. */
|
||||||
|
mask = (1u << var->data_type->dimx) - 1;
|
||||||
|
use_mask = mask; /* FIXME: retrieve use mask accurately. */
|
||||||
|
|
||||||
|
switch (var->data_type->e.numeric.type)
|
||||||
|
{
|
||||||
|
case HLSL_TYPE_FLOAT:
|
||||||
|
case HLSL_TYPE_HALF:
|
||||||
|
component_type = VKD3D_SHADER_COMPONENT_FLOAT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HLSL_TYPE_INT:
|
||||||
|
component_type = VKD3D_SHADER_COMPONENT_INT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HLSL_TYPE_BOOL:
|
||||||
|
case HLSL_TYPE_UINT:
|
||||||
|
component_type = VKD3D_SHADER_COMPONENT_UINT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if ((string = hlsl_type_to_string(ctx, var->data_type)))
|
||||||
|
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
|
||||||
|
"Invalid data type %s for semantic variable %s.", string->buffer, var->name);
|
||||||
|
hlsl_release_string_buffer(ctx, string);
|
||||||
|
component_type = VKD3D_SHADER_COMPONENT_VOID;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sysval == VKD3D_SHADER_SV_TARGET && !ascii_strcasecmp(name, "color"))
|
||||||
|
name = "SV_Target";
|
||||||
|
else if (sysval == VKD3D_SHADER_SV_DEPTH && !ascii_strcasecmp(name, "depth"))
|
||||||
|
name ="SV_Depth";
|
||||||
|
else if (sysval == VKD3D_SHADER_SV_POSITION && !ascii_strcasecmp(name, "position"))
|
||||||
|
name = "SV_Position";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((!output && !var->last_read) || (output && !var->first_write))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!sm1_register_from_semantic_name(&program->shader_version,
|
||||||
|
var->semantic.name, var->semantic.index, output, &type, ®ister_index))
|
||||||
|
{
|
||||||
|
enum vkd3d_decl_usage usage;
|
||||||
|
unsigned int usage_idx;
|
||||||
|
bool ret;
|
||||||
|
|
||||||
|
register_index = var->regs[HLSL_REGSET_NUMERIC].id;
|
||||||
|
|
||||||
|
ret = sm1_usage_from_semantic_name(var->semantic.name, var->semantic.index, &usage, &usage_idx);
|
||||||
|
VKD3D_ASSERT(ret);
|
||||||
|
/* With the exception of vertex POSITION output, none of these are
|
||||||
|
* system values. Pixel POSITION input is not equivalent to
|
||||||
|
* SV_Position; the closer equivalent is VPOS, which is not declared
|
||||||
|
* as a semantic. */
|
||||||
|
if (program->shader_version.type == VKD3D_SHADER_TYPE_VERTEX
|
||||||
|
&& output && usage == VKD3D_DECL_USAGE_POSITION)
|
||||||
|
sysval = VKD3D_SHADER_SV_POSITION;
|
||||||
|
}
|
||||||
|
|
||||||
|
mask = (1 << var->data_type->dimx) - 1;
|
||||||
|
use_mask = mask; /* FIXME: retrieve use mask accurately. */
|
||||||
|
component_type = VKD3D_SHADER_COMPONENT_FLOAT;
|
||||||
|
}
|
||||||
|
|
||||||
if (!vkd3d_array_reserve((void **)&signature->elements, &signature->elements_capacity,
|
if (!vkd3d_array_reserve((void **)&signature->elements, &signature->elements_capacity,
|
||||||
signature->element_count + 1, sizeof(*signature->elements)))
|
signature->element_count + 1, sizeof(*signature->elements)))
|
||||||
{
|
{
|
||||||
@ -6300,30 +6386,9 @@ static void sm1_generate_vsir_signature_entry(struct hlsl_ctx *ctx,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
element = &signature->elements[signature->element_count++];
|
element = &signature->elements[signature->element_count++];
|
||||||
|
|
||||||
if (!sm1_register_from_semantic_name(&program->shader_version,
|
|
||||||
var->semantic.name, var->semantic.index, output, &type, ®ister_index))
|
|
||||||
{
|
|
||||||
enum vkd3d_decl_usage usage;
|
|
||||||
unsigned int usage_idx;
|
|
||||||
bool ret;
|
|
||||||
|
|
||||||
register_index = var->regs[HLSL_REGSET_NUMERIC].id;
|
|
||||||
|
|
||||||
ret = sm1_usage_from_semantic_name(var->semantic.name, var->semantic.index, &usage, &usage_idx);
|
|
||||||
VKD3D_ASSERT(ret);
|
|
||||||
/* With the exception of vertex POSITION output, none of these are
|
|
||||||
* system values. Pixel POSITION input is not equivalent to
|
|
||||||
* SV_Position; the closer equivalent is VPOS, which is not declared
|
|
||||||
* as a semantic. */
|
|
||||||
if (program->shader_version.type == VKD3D_SHADER_TYPE_VERTEX
|
|
||||||
&& output && usage == VKD3D_DECL_USAGE_POSITION)
|
|
||||||
sysval = VKD3D_SHADER_SV_POSITION;
|
|
||||||
}
|
|
||||||
mask = (1 << var->data_type->dimx) - 1;
|
|
||||||
|
|
||||||
memset(element, 0, sizeof(*element));
|
memset(element, 0, sizeof(*element));
|
||||||
if (!(element->semantic_name = vkd3d_strdup(var->semantic.name)))
|
|
||||||
|
if (!(element->semantic_name = vkd3d_strdup(name)))
|
||||||
{
|
{
|
||||||
--signature->element_count;
|
--signature->element_count;
|
||||||
ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
|
ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
|
||||||
@ -6331,27 +6396,27 @@ static void sm1_generate_vsir_signature_entry(struct hlsl_ctx *ctx,
|
|||||||
}
|
}
|
||||||
element->semantic_index = var->semantic.index;
|
element->semantic_index = var->semantic.index;
|
||||||
element->sysval_semantic = sysval;
|
element->sysval_semantic = sysval;
|
||||||
element->component_type = VKD3D_SHADER_COMPONENT_FLOAT;
|
element->component_type = component_type;
|
||||||
element->register_index = register_index;
|
element->register_index = register_index;
|
||||||
element->target_location = register_index;
|
element->target_location = register_index;
|
||||||
element->register_count = 1;
|
element->register_count = 1;
|
||||||
element->mask = mask;
|
element->mask = mask;
|
||||||
element->used_mask = mask;
|
element->used_mask = use_mask;
|
||||||
if (program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL && !output)
|
if (program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL && !output)
|
||||||
element->interpolation_mode = VKD3DSIM_LINEAR;
|
element->interpolation_mode = VKD3DSIM_LINEAR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sm1_generate_vsir_signature(struct hlsl_ctx *ctx,
|
static void generate_vsir_signature(struct hlsl_ctx *ctx,
|
||||||
struct hlsl_ir_function_decl *func, struct vsir_program *program)
|
struct vsir_program *program, struct hlsl_ir_function_decl *func)
|
||||||
{
|
{
|
||||||
struct hlsl_ir_var *var;
|
struct hlsl_ir_var *var;
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY(var, &func->extern_vars, struct hlsl_ir_var, extern_entry)
|
LIST_FOR_EACH_ENTRY(var, &func->extern_vars, struct hlsl_ir_var, extern_entry)
|
||||||
{
|
{
|
||||||
if (var->is_input_semantic)
|
if (var->is_input_semantic)
|
||||||
sm1_generate_vsir_signature_entry(ctx, program, false, var);
|
generate_vsir_signature_entry(ctx, program, false, var);
|
||||||
if (var->is_output_semantic)
|
if (var->is_output_semantic)
|
||||||
sm1_generate_vsir_signature_entry(ctx, program, true, var);
|
generate_vsir_signature_entry(ctx, program, true, var);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7308,7 +7373,7 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl
|
|||||||
ctab->code = buffer.data;
|
ctab->code = buffer.data;
|
||||||
ctab->size = buffer.size;
|
ctab->size = buffer.size;
|
||||||
|
|
||||||
sm1_generate_vsir_signature(ctx, entry_func, program);
|
generate_vsir_signature(ctx, program, entry_func);
|
||||||
|
|
||||||
hlsl_block_init(&block);
|
hlsl_block_init(&block);
|
||||||
sm1_generate_vsir_constant_defs(ctx, program, &block);
|
sm1_generate_vsir_constant_defs(ctx, program, &block);
|
||||||
@ -7335,6 +7400,8 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl
|
|||||||
ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
|
ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
generate_vsir_signature(ctx, program, entry_func);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct hlsl_ir_jump *loop_unrolling_find_jump(struct hlsl_block *block, struct hlsl_ir_node *stop_point,
|
static struct hlsl_ir_jump *loop_unrolling_find_jump(struct hlsl_block *block, struct hlsl_ir_node *stop_point,
|
||||||
|
@ -1407,6 +1407,7 @@ struct tpf_compiler
|
|||||||
{
|
{
|
||||||
/* OBJECTIVE: We want to get rid of this HLSL IR specific field. */
|
/* OBJECTIVE: We want to get rid of this HLSL IR specific field. */
|
||||||
struct hlsl_ctx *ctx;
|
struct hlsl_ctx *ctx;
|
||||||
|
struct vsir_program *program;
|
||||||
struct vkd3d_sm4_lookup_tables lookup;
|
struct vkd3d_sm4_lookup_tables lookup;
|
||||||
struct sm4_stat *stat;
|
struct sm4_stat *stat;
|
||||||
|
|
||||||
@ -3127,110 +3128,51 @@ static void add_section(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc,
|
|||||||
ctx->result = buffer->status;
|
ctx->result = buffer->status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tpf_write_signature(struct tpf_compiler *tpf, const struct hlsl_ir_function_decl *func, bool output)
|
static void tpf_write_signature(struct tpf_compiler *tpf, bool output)
|
||||||
{
|
{
|
||||||
struct vkd3d_bytecode_buffer buffer = {0};
|
struct vkd3d_bytecode_buffer buffer = {0};
|
||||||
struct vkd3d_string_buffer *string;
|
struct shader_signature *signature;
|
||||||
struct hlsl_ctx *ctx = tpf->ctx;
|
struct hlsl_ctx *ctx = tpf->ctx;
|
||||||
const struct hlsl_ir_var *var;
|
|
||||||
size_t count_position;
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
bool ret;
|
|
||||||
|
|
||||||
count_position = put_u32(&buffer, 0);
|
if (output)
|
||||||
|
signature = &tpf->program->output_signature;
|
||||||
|
else
|
||||||
|
signature = &tpf->program->input_signature;
|
||||||
|
|
||||||
|
put_u32(&buffer, signature->element_count);
|
||||||
put_u32(&buffer, 8); /* unknown */
|
put_u32(&buffer, 8); /* unknown */
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY(var, &func->extern_vars, struct hlsl_ir_var, extern_entry)
|
for (i = 0; i < signature->element_count; ++i)
|
||||||
{
|
{
|
||||||
unsigned int width = (1u << var->data_type->dimx) - 1, use_mask;
|
const struct signature_element *element = &signature->elements[i];
|
||||||
enum vkd3d_shader_sysval_semantic semantic;
|
enum vkd3d_shader_sysval_semantic sysval;
|
||||||
uint32_t usage_idx, reg_idx;
|
uint32_t used_mask = element->used_mask;
|
||||||
bool has_idx;
|
|
||||||
|
|
||||||
if ((output && !var->is_output_semantic) || (!output && !var->is_input_semantic))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ret = sysval_semantic_from_hlsl(&semantic, ctx, &var->semantic, output);
|
|
||||||
VKD3D_ASSERT(ret);
|
|
||||||
if (semantic == ~0u)
|
|
||||||
continue;
|
|
||||||
usage_idx = var->semantic.index;
|
|
||||||
|
|
||||||
if (hlsl_sm4_register_from_semantic(ctx, &var->semantic, output, NULL, &has_idx))
|
|
||||||
{
|
|
||||||
reg_idx = has_idx ? var->semantic.index : ~0u;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
VKD3D_ASSERT(var->regs[HLSL_REGSET_NUMERIC].allocated);
|
|
||||||
reg_idx = var->regs[HLSL_REGSET_NUMERIC].id;
|
|
||||||
}
|
|
||||||
|
|
||||||
use_mask = width; /* FIXME: accurately report use mask */
|
|
||||||
if (output)
|
if (output)
|
||||||
use_mask = 0xf ^ use_mask;
|
used_mask = 0xf ^ used_mask;
|
||||||
|
|
||||||
/* Special pixel shader semantics (TARGET, DEPTH, COVERAGE). */
|
sysval = element->sysval_semantic;
|
||||||
if (semantic >= VKD3D_SHADER_SV_TARGET)
|
if (sysval >= VKD3D_SHADER_SV_TARGET)
|
||||||
semantic = VKD3D_SHADER_SV_NONE;
|
sysval = VKD3D_SHADER_SV_NONE;
|
||||||
|
|
||||||
put_u32(&buffer, 0); /* name */
|
put_u32(&buffer, 0); /* name */
|
||||||
put_u32(&buffer, usage_idx);
|
put_u32(&buffer, element->semantic_index);
|
||||||
put_u32(&buffer, semantic);
|
put_u32(&buffer, sysval);
|
||||||
switch (var->data_type->e.numeric.type)
|
put_u32(&buffer, element->component_type);
|
||||||
{
|
put_u32(&buffer, element->register_index);
|
||||||
case HLSL_TYPE_FLOAT:
|
put_u32(&buffer, vkd3d_make_u16(element->mask, used_mask));
|
||||||
case HLSL_TYPE_HALF:
|
|
||||||
put_u32(&buffer, VKD3D_SHADER_COMPONENT_FLOAT);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HLSL_TYPE_INT:
|
|
||||||
put_u32(&buffer, VKD3D_SHADER_COMPONENT_INT);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HLSL_TYPE_BOOL:
|
|
||||||
case HLSL_TYPE_UINT:
|
|
||||||
put_u32(&buffer, VKD3D_SHADER_COMPONENT_UINT);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
if ((string = hlsl_type_to_string(ctx, var->data_type)))
|
|
||||||
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
|
|
||||||
"Invalid data type %s for semantic variable %s.", string->buffer, var->name);
|
|
||||||
hlsl_release_string_buffer(ctx, string);
|
|
||||||
put_u32(&buffer, VKD3D_SHADER_COMPONENT_VOID);
|
|
||||||
}
|
|
||||||
put_u32(&buffer, reg_idx);
|
|
||||||
put_u32(&buffer, vkd3d_make_u16(width, use_mask));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
i = 0;
|
for (i = 0; i < signature->element_count; ++i)
|
||||||
LIST_FOR_EACH_ENTRY(var, &func->extern_vars, struct hlsl_ir_var, extern_entry)
|
|
||||||
{
|
{
|
||||||
enum vkd3d_shader_sysval_semantic semantic;
|
const struct signature_element *element = &signature->elements[i];
|
||||||
const char *name = var->semantic.name;
|
|
||||||
size_t string_offset;
|
size_t string_offset;
|
||||||
|
|
||||||
if ((output && !var->is_output_semantic) || (!output && !var->is_input_semantic))
|
string_offset = put_string(&buffer, element->semantic_name);
|
||||||
continue;
|
set_u32(&buffer, (2 + i * 6) * sizeof(uint32_t), string_offset);
|
||||||
|
|
||||||
sysval_semantic_from_hlsl(&semantic, ctx, &var->semantic, output);
|
|
||||||
if (semantic == ~0u)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (semantic == VKD3D_SHADER_SV_TARGET && !ascii_strcasecmp(name, "color"))
|
|
||||||
string_offset = put_string(&buffer, "SV_Target");
|
|
||||||
else if (semantic == VKD3D_SHADER_SV_DEPTH && !ascii_strcasecmp(name, "depth"))
|
|
||||||
string_offset = put_string(&buffer, "SV_Depth");
|
|
||||||
else if (semantic == VKD3D_SHADER_SV_POSITION && !ascii_strcasecmp(name, "position"))
|
|
||||||
string_offset = put_string(&buffer, "SV_Position");
|
|
||||||
else
|
|
||||||
string_offset = put_string(&buffer, name);
|
|
||||||
set_u32(&buffer, (2 + i++ * 6) * sizeof(uint32_t), string_offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set_u32(&buffer, count_position, i);
|
|
||||||
|
|
||||||
add_section(ctx, &tpf->dxbc, output ? TAG_OSGN : TAG_ISGN, &buffer);
|
add_section(ctx, &tpf->dxbc, output ? TAG_OSGN : TAG_ISGN, &buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6575,13 +6517,14 @@ int tpf_compile(struct vsir_program *program, uint64_t config_flags,
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
tpf.ctx = ctx;
|
tpf.ctx = ctx;
|
||||||
|
tpf.program = program;
|
||||||
tpf.buffer = NULL;
|
tpf.buffer = NULL;
|
||||||
tpf.stat = &stat;
|
tpf.stat = &stat;
|
||||||
init_sm4_lookup_tables(&tpf.lookup);
|
init_sm4_lookup_tables(&tpf.lookup);
|
||||||
dxbc_writer_init(&tpf.dxbc);
|
dxbc_writer_init(&tpf.dxbc);
|
||||||
|
|
||||||
tpf_write_signature(&tpf, entry_func, false);
|
tpf_write_signature(&tpf, false);
|
||||||
tpf_write_signature(&tpf, entry_func, true);
|
tpf_write_signature(&tpf, true);
|
||||||
write_sm4_rdef(ctx, &tpf.dxbc);
|
write_sm4_rdef(ctx, &tpf.dxbc);
|
||||||
tpf_write_shdr(&tpf, entry_func);
|
tpf_write_shdr(&tpf, entry_func);
|
||||||
tpf_write_sfi0(&tpf);
|
tpf_write_sfi0(&tpf);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user