mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-09-12 18:50:22 -07:00
vkd3d-shader/hlsl: Parse the Append() method for stream outputs.
This commit is contained in:
Notes:
Henri Verbeet
2025-04-23 18:18:33 +02:00
Approved-by: Elizabeth Figura (@zfigura) Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1458
@@ -2057,24 +2057,28 @@ struct hlsl_ir_node *hlsl_block_add_resource_load(struct hlsl_ctx *ctx, struct h
|
|||||||
return append_new_instr(ctx, block, hlsl_new_resource_load(ctx, params, loc));
|
return append_new_instr(ctx, block, hlsl_new_resource_load(ctx, params, loc));
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, const struct hlsl_deref *resource,
|
static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, enum hlsl_resource_store_type type,
|
||||||
struct hlsl_ir_node *coords, struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc)
|
const struct hlsl_deref *resource, struct hlsl_ir_node *coords, struct hlsl_ir_node *value,
|
||||||
|
const struct vkd3d_shader_location *loc)
|
||||||
{
|
{
|
||||||
struct hlsl_ir_resource_store *store;
|
struct hlsl_ir_resource_store *store;
|
||||||
|
|
||||||
if (!(store = hlsl_alloc(ctx, sizeof(*store))))
|
if (!(store = hlsl_alloc(ctx, sizeof(*store))))
|
||||||
return NULL;
|
return NULL;
|
||||||
init_node(&store->node, HLSL_IR_RESOURCE_STORE, NULL, loc);
|
init_node(&store->node, HLSL_IR_RESOURCE_STORE, NULL, loc);
|
||||||
|
store->store_type = type;
|
||||||
|
|
||||||
hlsl_copy_deref(ctx, &store->resource, resource);
|
hlsl_copy_deref(ctx, &store->resource, resource);
|
||||||
hlsl_src_from_node(&store->coords, coords);
|
hlsl_src_from_node(&store->coords, coords);
|
||||||
hlsl_src_from_node(&store->value, value);
|
hlsl_src_from_node(&store->value, value);
|
||||||
return &store->node;
|
return &store->node;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block, const struct hlsl_deref *resource,
|
void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
||||||
struct hlsl_ir_node *coords, struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc)
|
enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords,
|
||||||
|
struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc)
|
||||||
{
|
{
|
||||||
append_new_instr(ctx, block, hlsl_new_resource_store(ctx, resource, coords, value, loc));
|
append_new_instr(ctx, block, hlsl_new_resource_store(ctx, type, resource, coords, value, loc));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned int component_count,
|
struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned int component_count,
|
||||||
@@ -2593,6 +2597,7 @@ static struct hlsl_ir_node *clone_resource_store(struct hlsl_ctx *ctx,
|
|||||||
if (!(dst = hlsl_alloc(ctx, sizeof(*dst))))
|
if (!(dst = hlsl_alloc(ctx, sizeof(*dst))))
|
||||||
return NULL;
|
return NULL;
|
||||||
init_node(&dst->node, HLSL_IR_RESOURCE_STORE, NULL, &src->node.loc);
|
init_node(&dst->node, HLSL_IR_RESOURCE_STORE, NULL, &src->node.loc);
|
||||||
|
dst->store_type = src->store_type;
|
||||||
if (!clone_deref(ctx, map, &dst->resource, &src->resource))
|
if (!clone_deref(ctx, map, &dst->resource, &src->resource))
|
||||||
{
|
{
|
||||||
vkd3d_free(dst);
|
vkd3d_free(dst);
|
||||||
@@ -3724,12 +3729,25 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru
|
|||||||
|
|
||||||
static void dump_ir_resource_store(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_resource_store *store)
|
static void dump_ir_resource_store(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_resource_store *store)
|
||||||
{
|
{
|
||||||
vkd3d_string_buffer_printf(buffer, "store_resource(resource = ");
|
static const char *const type_names[] =
|
||||||
|
{
|
||||||
|
[HLSL_RESOURCE_STORE] = "store_resource",
|
||||||
|
[HLSL_RESOURCE_STREAM_APPEND] = "stream_append",
|
||||||
|
};
|
||||||
|
|
||||||
|
VKD3D_ASSERT(store->store_type < ARRAY_SIZE(type_names));
|
||||||
|
vkd3d_string_buffer_printf(buffer, "%s(resource = ", type_names[store->store_type]);
|
||||||
dump_deref(buffer, &store->resource);
|
dump_deref(buffer, &store->resource);
|
||||||
vkd3d_string_buffer_printf(buffer, ", coords = ");
|
if (store->coords.node)
|
||||||
dump_src(buffer, &store->coords);
|
{
|
||||||
vkd3d_string_buffer_printf(buffer, ", value = ");
|
vkd3d_string_buffer_printf(buffer, ", coords = ");
|
||||||
dump_src(buffer, &store->value);
|
dump_src(buffer, &store->coords);
|
||||||
|
}
|
||||||
|
if (store->value.node)
|
||||||
|
{
|
||||||
|
vkd3d_string_buffer_printf(buffer, ", value = ");
|
||||||
|
dump_src(buffer, &store->value);
|
||||||
|
}
|
||||||
vkd3d_string_buffer_printf(buffer, ")");
|
vkd3d_string_buffer_printf(buffer, ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -894,9 +894,16 @@ struct hlsl_ir_resource_load
|
|||||||
enum hlsl_sampler_dim sampling_dim;
|
enum hlsl_sampler_dim sampling_dim;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum hlsl_resource_store_type
|
||||||
|
{
|
||||||
|
HLSL_RESOURCE_STORE,
|
||||||
|
HLSL_RESOURCE_STREAM_APPEND,
|
||||||
|
};
|
||||||
|
|
||||||
struct hlsl_ir_resource_store
|
struct hlsl_ir_resource_store
|
||||||
{
|
{
|
||||||
struct hlsl_ir_node node;
|
struct hlsl_ir_node node;
|
||||||
|
enum hlsl_resource_store_type store_type;
|
||||||
struct hlsl_deref resource;
|
struct hlsl_deref resource;
|
||||||
struct hlsl_src coords, value;
|
struct hlsl_src coords, value;
|
||||||
};
|
};
|
||||||
@@ -1554,8 +1561,9 @@ void hlsl_block_add_loop(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
|||||||
unsigned int unroll_limit, const struct vkd3d_shader_location *loc);
|
unsigned int unroll_limit, const struct vkd3d_shader_location *loc);
|
||||||
struct hlsl_ir_node *hlsl_block_add_resource_load(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
struct hlsl_ir_node *hlsl_block_add_resource_load(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
||||||
const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc);
|
const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc);
|
||||||
void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block, const struct hlsl_deref *resource,
|
void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
||||||
struct hlsl_ir_node *coords, struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc);
|
enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords,
|
||||||
|
struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc);
|
||||||
struct hlsl_ir_node *hlsl_block_add_simple_load(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
struct hlsl_ir_node *hlsl_block_add_simple_load(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
||||||
struct hlsl_ir_var *var, const struct vkd3d_shader_location *loc);
|
struct hlsl_ir_var *var, const struct vkd3d_shader_location *loc);
|
||||||
void hlsl_block_add_simple_store(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
void hlsl_block_add_simple_store(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
||||||
|
@@ -2115,7 +2115,7 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc
|
|||||||
VKD3D_ASSERT(coords->data_type->e.numeric.type == HLSL_TYPE_UINT);
|
VKD3D_ASSERT(coords->data_type->e.numeric.type == HLSL_TYPE_UINT);
|
||||||
VKD3D_ASSERT(coords->data_type->e.numeric.dimx == dim_count);
|
VKD3D_ASSERT(coords->data_type->e.numeric.dimx == dim_count);
|
||||||
|
|
||||||
hlsl_block_add_resource_store(ctx, block, &resource_deref, coords, rhs, &lhs->loc);
|
hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &resource_deref, coords, rhs, &lhs->loc);
|
||||||
hlsl_cleanup_deref(&resource_deref);
|
hlsl_cleanup_deref(&resource_deref);
|
||||||
}
|
}
|
||||||
else if (matrix_writemask)
|
else if (matrix_writemask)
|
||||||
@@ -6220,12 +6220,37 @@ static bool add_store_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block
|
|||||||
if (!hlsl_init_deref_from_index_chain(ctx, &resource_deref, object))
|
if (!hlsl_init_deref_from_index_chain(ctx, &resource_deref, object))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
hlsl_block_add_resource_store(ctx, block, &resource_deref, offset, rhs, loc);
|
hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &resource_deref, offset, rhs, loc);
|
||||||
hlsl_cleanup_deref(&resource_deref);
|
hlsl_cleanup_deref(&resource_deref);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool add_so_append_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *object,
|
||||||
|
const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
|
||||||
|
{
|
||||||
|
struct hlsl_deref so_deref;
|
||||||
|
struct hlsl_ir_node *rhs;
|
||||||
|
|
||||||
|
if (params->args_count != 1)
|
||||||
|
{
|
||||||
|
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT,
|
||||||
|
"Wrong number of arguments to method '%s': expected 1.", name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hlsl_init_deref_from_index_chain(ctx, &so_deref, object))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!(rhs = add_implicit_conversion(ctx, block, params->args[0], object->data_type->e.so.type, loc)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_APPEND, &so_deref, NULL, rhs, loc);
|
||||||
|
hlsl_cleanup_deref(&so_deref);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct method_function
|
static const struct method_function
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
@@ -6269,6 +6294,11 @@ static const struct method_function uav_methods[] =
|
|||||||
{ "Store4", add_store_method_call, "00000000000001" },
|
{ "Store4", add_store_method_call, "00000000000001" },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct method_function so_methods[] =
|
||||||
|
{
|
||||||
|
{ "Append", add_so_append_method_call, "" },
|
||||||
|
};
|
||||||
|
|
||||||
static int object_method_function_name_compare(const void *a, const void *b)
|
static int object_method_function_name_compare(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
const struct method_function *func = b;
|
const struct method_function *func = b;
|
||||||
@@ -6280,8 +6310,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, stru
|
|||||||
const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
|
const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
|
||||||
{
|
{
|
||||||
const struct hlsl_type *object_type = object->data_type;
|
const struct hlsl_type *object_type = object->data_type;
|
||||||
const struct method_function *method, *methods;
|
const struct method_function *method;
|
||||||
unsigned int count;
|
|
||||||
|
|
||||||
if (object_type->class == HLSL_CLASS_ERROR)
|
if (object_type->class == HLSL_CLASS_ERROR)
|
||||||
{
|
{
|
||||||
@@ -6300,13 +6329,24 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, stru
|
|||||||
|
|
||||||
if (object_type->class == HLSL_CLASS_TEXTURE)
|
if (object_type->class == HLSL_CLASS_TEXTURE)
|
||||||
{
|
{
|
||||||
count = ARRAY_SIZE(texture_methods);
|
method = bsearch(name, texture_methods, ARRAY_SIZE(texture_methods), sizeof(*method),
|
||||||
methods = texture_methods;
|
object_method_function_name_compare);
|
||||||
|
|
||||||
|
if (method && method->valid_dims[object_type->sampler_dim] != '1')
|
||||||
|
method = NULL;
|
||||||
}
|
}
|
||||||
else if (object_type->class == HLSL_CLASS_UAV)
|
else if (object_type->class == HLSL_CLASS_UAV)
|
||||||
{
|
{
|
||||||
count = ARRAY_SIZE(uav_methods);
|
method = bsearch(name, uav_methods, ARRAY_SIZE(uav_methods), sizeof(*method),
|
||||||
methods = uav_methods;
|
object_method_function_name_compare);
|
||||||
|
|
||||||
|
if (method && method->valid_dims[object_type->sampler_dim] != '1')
|
||||||
|
method = NULL;
|
||||||
|
}
|
||||||
|
else if (object_type->class == HLSL_CLASS_STREAM_OUTPUT)
|
||||||
|
{
|
||||||
|
method = bsearch(name, so_methods, ARRAY_SIZE(so_methods), sizeof(*method),
|
||||||
|
object_method_function_name_compare);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -6319,17 +6359,10 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, stru
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
method = bsearch(name, methods, count, sizeof(*method),
|
if (method)
|
||||||
object_method_function_name_compare);
|
|
||||||
|
|
||||||
if (method && method->valid_dims[object_type->sampler_dim] == '1')
|
|
||||||
{
|
|
||||||
return method->handler(ctx, block, object, name, params, loc);
|
return method->handler(ctx, block, object, name, params, loc);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
return raise_invalid_method_object_type(ctx, object_type, name, loc);
|
return raise_invalid_method_object_type(ctx, object_type, name, loc);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool add_object_property_access(struct hlsl_ctx *ctx,
|
static bool add_object_property_access(struct hlsl_ctx *ctx,
|
||||||
|
@@ -5359,8 +5359,10 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop
|
|||||||
var = store->resource.var;
|
var = store->resource.var;
|
||||||
var->last_read = max(var->last_read, last_read);
|
var->last_read = max(var->last_read, last_read);
|
||||||
deref_mark_last_read(&store->resource, last_read);
|
deref_mark_last_read(&store->resource, last_read);
|
||||||
store->coords.node->last_read = last_read;
|
if (store->coords.node)
|
||||||
store->value.node->last_read = last_read;
|
store->coords.node->last_read = last_read;
|
||||||
|
if (store->value.node)
|
||||||
|
store->value.node->last_read = last_read;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case HLSL_IR_SWIZZLE:
|
case HLSL_IR_SWIZZLE:
|
||||||
@@ -10632,6 +10634,12 @@ static bool sm4_generate_vsir_instr_resource_store(struct hlsl_ctx *ctx,
|
|||||||
struct vkd3d_shader_instruction *ins;
|
struct vkd3d_shader_instruction *ins;
|
||||||
unsigned int writemask;
|
unsigned int writemask;
|
||||||
|
|
||||||
|
if (store->store_type != HLSL_RESOURCE_STORE)
|
||||||
|
{
|
||||||
|
hlsl_fixme(ctx, &instr->loc, "Stream output operations.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!store->resource.var->is_uniform)
|
if (!store->resource.var->is_uniform)
|
||||||
{
|
{
|
||||||
hlsl_fixme(ctx, &store->node.loc, "Store to non-uniform resource variable.");
|
hlsl_fixme(ctx, &store->node.loc, "Store to non-uniform resource variable.");
|
||||||
|
Reference in New Issue
Block a user