mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
vkd3d-shader/hlsl: Handle resource components individually for SM 5.0.
This commit is contained in:
parent
8f8c7a02ee
commit
c58d666d1b
Notes:
Alexandre Julliard
2023-07-17 23:25:21 +02:00
Approved-by: Giovanni Mascellani (@giomasce) Approved-by: Zebediah Figura (@zfigura) Approved-by: Henri Verbeet (@hverbeet) Approved-by: Alexandre Julliard (@julliard) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/209
@ -430,6 +430,51 @@ struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl
|
||||
return type;
|
||||
}
|
||||
|
||||
unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_type *type,
|
||||
enum hlsl_regset regset, unsigned int index)
|
||||
{
|
||||
struct hlsl_type *next_type;
|
||||
unsigned int offset = 0;
|
||||
unsigned int idx;
|
||||
|
||||
while (!type_is_single_component(type))
|
||||
{
|
||||
next_type = type;
|
||||
idx = traverse_path_from_component_index(ctx, &next_type, &index);
|
||||
|
||||
switch (type->class)
|
||||
{
|
||||
case HLSL_CLASS_SCALAR:
|
||||
case HLSL_CLASS_VECTOR:
|
||||
case HLSL_CLASS_MATRIX:
|
||||
if (regset == HLSL_REGSET_NUMERIC)
|
||||
offset += idx;
|
||||
break;
|
||||
|
||||
case HLSL_CLASS_STRUCT:
|
||||
offset += type->e.record.fields[idx].reg_offset[regset];
|
||||
break;
|
||||
|
||||
case HLSL_CLASS_ARRAY:
|
||||
if (regset == HLSL_REGSET_NUMERIC)
|
||||
offset += idx * align(type->e.array.type->reg_size[regset], 4);
|
||||
else
|
||||
offset += idx * type->e.array.type->reg_size[regset];
|
||||
break;
|
||||
|
||||
case HLSL_CLASS_OBJECT:
|
||||
assert(idx == 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
vkd3d_unreachable();
|
||||
}
|
||||
type = next_type;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
static bool init_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_var *var,
|
||||
unsigned int path_len)
|
||||
{
|
||||
@ -2068,6 +2113,31 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru
|
||||
}
|
||||
}
|
||||
|
||||
struct vkd3d_string_buffer *hlsl_component_to_string(struct hlsl_ctx *ctx, const struct hlsl_ir_var *var,
|
||||
unsigned int index)
|
||||
{
|
||||
struct hlsl_type *type = var->data_type, *current_type;
|
||||
struct vkd3d_string_buffer *buffer;
|
||||
unsigned int element_index;
|
||||
|
||||
if (!(buffer = hlsl_get_string_buffer(ctx)))
|
||||
return NULL;
|
||||
|
||||
vkd3d_string_buffer_printf(buffer, "%s", var->name);
|
||||
|
||||
while (!type_is_single_component(type))
|
||||
{
|
||||
current_type = type;
|
||||
element_index = traverse_path_from_component_index(ctx, &type, &index);
|
||||
if (current_type->class == HLSL_CLASS_STRUCT)
|
||||
vkd3d_string_buffer_printf(buffer, ".%s", current_type->e.record.fields[element_index].name);
|
||||
else
|
||||
vkd3d_string_buffer_printf(buffer, "[%u]", element_index);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
const char *debug_hlsl_type(struct hlsl_ctx *ctx, const struct hlsl_type *type)
|
||||
{
|
||||
struct vkd3d_string_buffer *string;
|
||||
|
@ -1068,6 +1068,8 @@ const char *debug_hlsl_writemask(unsigned int writemask);
|
||||
const char *debug_hlsl_swizzle(unsigned int swizzle, unsigned int count);
|
||||
|
||||
struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const struct hlsl_type *type);
|
||||
struct vkd3d_string_buffer *hlsl_component_to_string(struct hlsl_ctx *ctx, const struct hlsl_ir_var *var,
|
||||
unsigned int index);
|
||||
struct vkd3d_string_buffer *hlsl_modifiers_to_string(struct hlsl_ctx *ctx, unsigned int modifiers);
|
||||
const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type);
|
||||
|
||||
@ -1202,6 +1204,8 @@ unsigned int hlsl_type_component_count(const struct hlsl_type *type);
|
||||
unsigned int hlsl_type_get_array_element_reg_size(const struct hlsl_type *type, enum hlsl_regset regset);
|
||||
struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl_type *type,
|
||||
unsigned int index);
|
||||
unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_type *type,
|
||||
enum hlsl_regset regset, unsigned int index);
|
||||
bool hlsl_type_is_row_major(const struct hlsl_type *type);
|
||||
unsigned int hlsl_type_minor_size(const struct hlsl_type *type);
|
||||
unsigned int hlsl_type_major_size(const struct hlsl_type *type);
|
||||
|
@ -3007,6 +3007,7 @@ static void sm4_free_extern_resources(struct extern_resource *extern_resources,
|
||||
|
||||
static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, unsigned int *count)
|
||||
{
|
||||
bool separate_components = ctx->profile->major_version == 5 && ctx->profile->minor_version == 0;
|
||||
struct extern_resource *extern_resources = NULL;
|
||||
const struct hlsl_ir_var *var;
|
||||
enum hlsl_regset regset;
|
||||
@ -3016,6 +3017,66 @@ static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, un
|
||||
*count = 0;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
|
||||
{
|
||||
if (separate_components)
|
||||
{
|
||||
unsigned int component_count = hlsl_type_component_count(var->data_type);
|
||||
unsigned int k, regset_offset;
|
||||
|
||||
for (k = 0; k < component_count; ++k)
|
||||
{
|
||||
struct hlsl_type *component_type = hlsl_type_get_component_type(ctx, var->data_type, k);
|
||||
struct vkd3d_string_buffer *name_buffer;
|
||||
|
||||
if (!hlsl_type_is_resource(component_type))
|
||||
continue;
|
||||
|
||||
regset = hlsl_type_get_regset(component_type);
|
||||
regset_offset = hlsl_type_get_component_offset(ctx, var->data_type, regset, k);
|
||||
|
||||
if (regset_offset > var->regs[regset].bind_count)
|
||||
continue;
|
||||
|
||||
if (var->objects_usage[regset][regset_offset].used)
|
||||
{
|
||||
if (!(hlsl_array_reserve(ctx, (void **)&extern_resources, &capacity, *count + 1,
|
||||
sizeof(*extern_resources))))
|
||||
{
|
||||
sm4_free_extern_resources(extern_resources, *count);
|
||||
*count = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(name_buffer = hlsl_component_to_string(ctx, var, k)))
|
||||
{
|
||||
sm4_free_extern_resources(extern_resources, *count);
|
||||
*count = 0;
|
||||
return NULL;
|
||||
}
|
||||
if (!(name = hlsl_strdup(ctx, name_buffer->buffer)))
|
||||
{
|
||||
sm4_free_extern_resources(extern_resources, *count);
|
||||
*count = 0;
|
||||
hlsl_release_string_buffer(ctx, name_buffer);
|
||||
return NULL;
|
||||
}
|
||||
hlsl_release_string_buffer(ctx, name_buffer);
|
||||
|
||||
extern_resources[*count].var = NULL;
|
||||
|
||||
extern_resources[*count].name = name;
|
||||
extern_resources[*count].data_type = component_type;
|
||||
extern_resources[*count].is_user_packed = false;
|
||||
|
||||
extern_resources[*count].regset = regset;
|
||||
extern_resources[*count].id = var->regs[regset].id + regset_offset;
|
||||
extern_resources[*count].bind_count = 1;
|
||||
|
||||
++*count;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!hlsl_type_is_resource(var->data_type))
|
||||
continue;
|
||||
@ -3048,9 +3109,9 @@ static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, un
|
||||
extern_resources[*count].id = var->regs[regset].id;
|
||||
extern_resources[*count].bind_count = var->regs[regset].bind_count;
|
||||
|
||||
|
||||
++*count;
|
||||
}
|
||||
}
|
||||
|
||||
qsort(extern_resources, *count, sizeof(*extern_resources), sm4_compare_extern_resources);
|
||||
return extern_resources;
|
||||
@ -4980,33 +5041,15 @@ static void write_sm4_gather(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer
|
||||
static void write_sm4_resource_load(struct hlsl_ctx *ctx,
|
||||
struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_resource_load *load)
|
||||
{
|
||||
const struct hlsl_type *resource_type = load->resource.var->data_type;
|
||||
const struct hlsl_ir_node *texel_offset = load->texel_offset.node;
|
||||
const struct hlsl_ir_node *sample_index = load->sample_index.node;
|
||||
const struct hlsl_ir_node *coords = load->coords.node;
|
||||
|
||||
if (!hlsl_type_is_resource(resource_type))
|
||||
{
|
||||
hlsl_fixme(ctx, &load->node.loc, "Separate object fields as new variables.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (load->sampler.var)
|
||||
{
|
||||
const struct hlsl_type *sampler_type = load->sampler.var->data_type;
|
||||
|
||||
if (!hlsl_type_is_resource(sampler_type))
|
||||
{
|
||||
hlsl_fixme(ctx, &load->node.loc, "Separate object fields as new variables.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!load->sampler.var->is_uniform)
|
||||
if (load->sampler.var && !load->sampler.var->is_uniform)
|
||||
{
|
||||
hlsl_fixme(ctx, &load->node.loc, "Sample using non-uniform sampler variable.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!load->resource.var->is_uniform)
|
||||
{
|
||||
@ -5060,13 +5103,7 @@ static void write_sm4_resource_load(struct hlsl_ctx *ctx,
|
||||
static void write_sm4_resource_store(struct hlsl_ctx *ctx,
|
||||
struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_resource_store *store)
|
||||
{
|
||||
const struct hlsl_type *resource_type = store->resource.var->data_type;
|
||||
|
||||
if (!hlsl_type_is_resource(resource_type))
|
||||
{
|
||||
hlsl_fixme(ctx, &store->node.loc, "Separate object fields as new variables.");
|
||||
return;
|
||||
}
|
||||
struct hlsl_type *resource_type = hlsl_deref_get_type(ctx, &store->resource);
|
||||
|
||||
if (!store->resource.var->is_uniform)
|
||||
{
|
||||
|
@ -694,7 +694,7 @@ shader model >= 5.0
|
||||
size (1, 1)
|
||||
0.0 0.0 0.0 0.5
|
||||
|
||||
[pixel shader todo]
|
||||
[pixel shader]
|
||||
struct apple
|
||||
{
|
||||
float2 a;
|
||||
@ -718,5 +718,5 @@ uniform 0 float4 0.0 1.0 2.0 3.0
|
||||
uniform 4 float4 4.0 5.0 6.0 7.0
|
||||
uniform 8 float4 8.0 9.0 10.0 11.0
|
||||
uniform 12 float4 12.0 13.0 14.0 15.0
|
||||
todo draw quad
|
||||
todo probe all rgba (124.0, 135.0, 146.0, 150.5)
|
||||
draw quad
|
||||
probe all rgba (124.0, 135.0, 146.0, 150.5)
|
||||
|
Loading…
Reference in New Issue
Block a user