mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-09-12 18:50:22 -07:00
vkd3d-shader/hlsl: Parse the shader 'compile' syntax.
The hlsl_ir_compile node is introduced to represent the "compile" syntax, and later the CompileShader() and ConstructGSWithSO() constructs. It basically represents a function call that remembers its arguments using hlsl_srcs and keeps its own instruction block, which is discarded when working on non-effect shaders. For shader compilations it can be asserted that args_count is 1, and that this argument (and the last node in hlsl_ir_effect_call.instrs) is a regular hlsl_ir_call pointing to the declaration of the function to be compiled.
This commit is contained in:
committed by
Henri Verbeet
parent
379cd9b7b5
commit
45f18a7838
Notes:
Henri Verbeet
2024-09-04 18:48:35 +02:00
Approved-by: Elizabeth Figura (@zfigura) Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/943
@@ -254,6 +254,45 @@ bool hlsl_type_is_resource(const struct hlsl_type *type)
|
||||
}
|
||||
}
|
||||
|
||||
bool hlsl_type_is_shader(const struct hlsl_type *type)
|
||||
{
|
||||
switch (type->class)
|
||||
{
|
||||
case HLSL_CLASS_ARRAY:
|
||||
return hlsl_type_is_shader(type->e.array.type);
|
||||
|
||||
case HLSL_CLASS_COMPUTE_SHADER:
|
||||
case HLSL_CLASS_DOMAIN_SHADER:
|
||||
case HLSL_CLASS_GEOMETRY_SHADER:
|
||||
case HLSL_CLASS_HULL_SHADER:
|
||||
case HLSL_CLASS_PIXEL_SHADER:
|
||||
case HLSL_CLASS_VERTEX_SHADER:
|
||||
return true;
|
||||
|
||||
case HLSL_CLASS_SCALAR:
|
||||
case HLSL_CLASS_VECTOR:
|
||||
case HLSL_CLASS_MATRIX:
|
||||
case HLSL_CLASS_STRUCT:
|
||||
case HLSL_CLASS_DEPTH_STENCIL_STATE:
|
||||
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
|
||||
case HLSL_CLASS_EFFECT_GROUP:
|
||||
case HLSL_CLASS_PASS:
|
||||
case HLSL_CLASS_RASTERIZER_STATE:
|
||||
case HLSL_CLASS_RENDER_TARGET_VIEW:
|
||||
case HLSL_CLASS_SAMPLER:
|
||||
case HLSL_CLASS_STRING:
|
||||
case HLSL_CLASS_TECHNIQUE:
|
||||
case HLSL_CLASS_TEXTURE:
|
||||
case HLSL_CLASS_UAV:
|
||||
case HLSL_CLASS_CONSTANT_BUFFER:
|
||||
case HLSL_CLASS_BLEND_STATE:
|
||||
case HLSL_CLASS_VOID:
|
||||
case HLSL_CLASS_NULL:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Only intended to be used for derefs (after copies have been lowered to components or vectors) or
|
||||
* resources, since for both their data types span across a single regset. */
|
||||
static enum hlsl_regset type_get_regset(const struct hlsl_type *type)
|
||||
@@ -1808,6 +1847,54 @@ struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned
|
||||
return &swizzle->node;
|
||||
}
|
||||
|
||||
struct hlsl_ir_node *hlsl_new_compile(struct hlsl_ctx *ctx, const char *profile_name,
|
||||
struct hlsl_ir_node **args, unsigned int args_count, struct hlsl_block *args_instrs,
|
||||
const struct vkd3d_shader_location *loc)
|
||||
{
|
||||
const struct hlsl_profile_info *profile_info = NULL;
|
||||
struct hlsl_ir_compile *compile;
|
||||
struct hlsl_type *type = NULL;
|
||||
unsigned int i;
|
||||
|
||||
if (!(profile_info = hlsl_get_target_info(profile_name)))
|
||||
{
|
||||
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_PROFILE, "Unknown profile \"%s\".", profile_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (profile_info->type == VKD3D_SHADER_TYPE_PIXEL)
|
||||
type = hlsl_get_type(ctx->cur_scope, "PixelShader", true, true);
|
||||
else if (profile_info->type == VKD3D_SHADER_TYPE_VERTEX)
|
||||
type = hlsl_get_type(ctx->cur_scope, "VertexShader", true, true);
|
||||
|
||||
if (!type)
|
||||
{
|
||||
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_PROFILE, "Invalid profile \"%s\".", profile_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(compile = hlsl_alloc(ctx, sizeof(*compile))))
|
||||
return NULL;
|
||||
|
||||
init_node(&compile->node, HLSL_IR_COMPILE, type, loc);
|
||||
|
||||
compile->profile = profile_info;
|
||||
|
||||
hlsl_block_init(&compile->instrs);
|
||||
hlsl_block_add_block(&compile->instrs, args_instrs);
|
||||
|
||||
compile->args_count = args_count;
|
||||
if (!(compile->args = hlsl_alloc(ctx, sizeof(*compile->args) * args_count)))
|
||||
{
|
||||
vkd3d_free(compile);
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < compile->args_count; ++i)
|
||||
hlsl_src_from_node(&compile->args[i], args[i]);
|
||||
|
||||
return &compile->node;
|
||||
}
|
||||
|
||||
struct hlsl_ir_node *hlsl_new_stateblock_constant(struct hlsl_ctx *ctx, const char *name,
|
||||
struct vkd3d_shader_location *loc)
|
||||
{
|
||||
@@ -2158,6 +2245,43 @@ static struct hlsl_ir_node *clone_index(struct hlsl_ctx *ctx, struct clone_instr
|
||||
return dst;
|
||||
}
|
||||
|
||||
static struct hlsl_ir_node *clone_compile(struct hlsl_ctx *ctx,
|
||||
struct clone_instr_map *map, struct hlsl_ir_compile *compile)
|
||||
{
|
||||
const char *profile_name = NULL;
|
||||
struct hlsl_ir_node **args;
|
||||
struct hlsl_ir_node *node;
|
||||
struct hlsl_block block;
|
||||
unsigned int i;
|
||||
|
||||
if (!(clone_block(ctx, &block, &compile->instrs, map)))
|
||||
return NULL;
|
||||
|
||||
if (!(args = hlsl_alloc(ctx, sizeof(*args) * compile->args_count)))
|
||||
{
|
||||
hlsl_block_cleanup(&block);
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < compile->args_count; ++i)
|
||||
{
|
||||
args[i] = map_instr(map, compile->args[i].node);
|
||||
VKD3D_ASSERT(args[i]);
|
||||
}
|
||||
|
||||
if (compile->profile)
|
||||
profile_name = compile->profile->name;
|
||||
|
||||
if (!(node = hlsl_new_compile(ctx, profile_name, args, compile->args_count, &block, &compile->node.loc)))
|
||||
{
|
||||
hlsl_block_cleanup(&block);
|
||||
vkd3d_free(args);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vkd3d_free(args);
|
||||
return node;
|
||||
}
|
||||
|
||||
static struct hlsl_ir_node *clone_stateblock_constant(struct hlsl_ctx *ctx,
|
||||
struct clone_instr_map *map, struct hlsl_ir_stateblock_constant *constant)
|
||||
{
|
||||
@@ -2300,6 +2424,9 @@ static struct hlsl_ir_node *clone_instr(struct hlsl_ctx *ctx,
|
||||
case HLSL_IR_SWIZZLE:
|
||||
return clone_swizzle(ctx, map, hlsl_ir_swizzle(instr));
|
||||
|
||||
case HLSL_IR_COMPILE:
|
||||
return clone_compile(ctx, map, hlsl_ir_compile(instr));
|
||||
|
||||
case HLSL_IR_STATEBLOCK_CONSTANT:
|
||||
return clone_stateblock_constant(ctx, map, hlsl_ir_stateblock_constant(instr));
|
||||
|
||||
@@ -2717,6 +2844,8 @@ const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type)
|
||||
[HLSL_IR_STORE ] = "HLSL_IR_STORE",
|
||||
[HLSL_IR_SWITCH ] = "HLSL_IR_SWITCH",
|
||||
[HLSL_IR_SWIZZLE ] = "HLSL_IR_SWIZZLE",
|
||||
|
||||
[HLSL_IR_COMPILE] = "HLSL_IR_COMPILE",
|
||||
[HLSL_IR_STATEBLOCK_CONSTANT] = "HLSL_IR_STATEBLOCK_CONSTANT",
|
||||
[HLSL_IR_VSIR_INSTRUCTION_REF] = "HLSL_IR_VSIR_INSTRUCTION_REF",
|
||||
};
|
||||
@@ -3166,6 +3295,25 @@ static void dump_ir_index(struct vkd3d_string_buffer *buffer, const struct hlsl_
|
||||
vkd3d_string_buffer_printf(buffer, "]");
|
||||
}
|
||||
|
||||
static void dump_ir_compile(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer,
|
||||
const struct hlsl_ir_compile *compile)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
vkd3d_string_buffer_printf(buffer, "compile %s {\n", compile->profile->name);
|
||||
|
||||
dump_block(ctx, buffer, &compile->instrs);
|
||||
|
||||
vkd3d_string_buffer_printf(buffer, " %10s } (", "");
|
||||
for (i = 0; i < compile->args_count; ++i)
|
||||
{
|
||||
dump_src(buffer, &compile->args[i]);
|
||||
if (i + 1 < compile->args_count)
|
||||
vkd3d_string_buffer_printf(buffer, ", ");
|
||||
}
|
||||
vkd3d_string_buffer_printf(buffer, ")");
|
||||
}
|
||||
|
||||
static void dump_ir_stateblock_constant(struct vkd3d_string_buffer *buffer,
|
||||
const struct hlsl_ir_stateblock_constant *constant)
|
||||
{
|
||||
@@ -3265,6 +3413,10 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer,
|
||||
dump_ir_swizzle(buffer, hlsl_ir_swizzle(instr));
|
||||
break;
|
||||
|
||||
case HLSL_IR_COMPILE:
|
||||
dump_ir_compile(ctx, buffer, hlsl_ir_compile(instr));
|
||||
break;
|
||||
|
||||
case HLSL_IR_STATEBLOCK_CONSTANT:
|
||||
dump_ir_stateblock_constant(buffer, hlsl_ir_stateblock_constant(instr));
|
||||
break;
|
||||
@@ -3484,6 +3636,17 @@ static void free_ir_index(struct hlsl_ir_index *index)
|
||||
vkd3d_free(index);
|
||||
}
|
||||
|
||||
static void free_ir_compile(struct hlsl_ir_compile *compile)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < compile->args_count; ++i)
|
||||
hlsl_src_remove(&compile->args[i]);
|
||||
|
||||
hlsl_block_cleanup(&compile->instrs);
|
||||
vkd3d_free(compile);
|
||||
}
|
||||
|
||||
static void free_ir_stateblock_constant(struct hlsl_ir_stateblock_constant *constant)
|
||||
{
|
||||
vkd3d_free(constant->name);
|
||||
@@ -3552,6 +3715,10 @@ void hlsl_free_instr(struct hlsl_ir_node *node)
|
||||
free_ir_switch(hlsl_ir_switch(node));
|
||||
break;
|
||||
|
||||
case HLSL_IR_COMPILE:
|
||||
free_ir_compile(hlsl_ir_compile(node));
|
||||
break;
|
||||
|
||||
case HLSL_IR_STATEBLOCK_CONSTANT:
|
||||
free_ir_stateblock_constant(hlsl_ir_stateblock_constant(node));
|
||||
break;
|
||||
|
Reference in New Issue
Block a user