mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-12-15 08:03:30 -08:00
vkd3d-shader/hlsl: Store parsed values in hlsl_ir_compile().
Makes emitting shaders from fx.c easier, and brings parsing failures upfront. Non-effect target profiles don't perform any type checks on ConstructGSWithSO(), nor use shader objects in any way, but they do check if the argument count is correct. So we create a GeometryShader object with NULL decl and profile when targeting non-effect profiles, so our type checks still work and implicit conversions aren't attempted.
This commit is contained in:
committed by
Henri Verbeet
parent
ffe1a433d9
commit
b17923b5ba
Notes:
Henri Verbeet
2025-12-09 17:21:49 +01:00
Approved-by: Francisco Casas (@fcasas) Approved-by: Nikolay Sivov (@nsivov) Approved-by: Elizabeth Figura (@zfigura) Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1340
@@ -2289,61 +2289,91 @@ struct hlsl_ir_node *hlsl_new_matrix_swizzle(struct hlsl_ctx *ctx, struct hlsl_m
|
|||||||
return &swizzle->node;
|
return &swizzle->node;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct hlsl_ir_node *hlsl_new_compile(struct hlsl_ctx *ctx, enum hlsl_compile_type compile_type,
|
static struct hlsl_ir_compile *new_compile(struct hlsl_ctx *ctx, const struct hlsl_profile_info *profile,
|
||||||
const char *profile_name, struct hlsl_ir_node **args, unsigned int args_count,
|
struct hlsl_ir_function_decl *decl, struct hlsl_block *initializer, struct hlsl_type *type,
|
||||||
struct hlsl_block *args_instrs, const struct vkd3d_shader_location *loc)
|
uint32_t stream, size_t count, const char *output_decls[4], const struct vkd3d_shader_location *loc)
|
||||||
{
|
{
|
||||||
const struct hlsl_profile_info *profile_info = NULL;
|
|
||||||
struct hlsl_ir_compile *compile;
|
struct hlsl_ir_compile *compile;
|
||||||
struct hlsl_type *type = NULL;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
switch (compile_type)
|
|
||||||
{
|
|
||||||
case HLSL_COMPILE_TYPE_COMPILE:
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HLSL_COMPILE_TYPE_CONSTRUCTGSWITHSO:
|
|
||||||
type = hlsl_get_type(ctx->cur_scope, "GeometryShader", true, true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(compile = hlsl_alloc(ctx, sizeof(*compile))))
|
if (!(compile = hlsl_alloc(ctx, sizeof(*compile))))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
init_node(&compile->node, HLSL_IR_COMPILE, type, loc);
|
init_node(&compile->node, HLSL_IR_COMPILE, type, loc);
|
||||||
|
hlsl_block_init(&compile->initializers);
|
||||||
|
hlsl_block_add_block(&compile->initializers, initializer);
|
||||||
|
|
||||||
compile->compile_type = compile_type;
|
compile->profile = profile;
|
||||||
compile->profile = profile_info;
|
compile->decl = decl;
|
||||||
|
compile->output.stream = stream;
|
||||||
|
compile->output.count = count;
|
||||||
|
|
||||||
hlsl_block_init(&compile->instrs);
|
for (size_t i = 0; i < count; ++i)
|
||||||
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);
|
if (output_decls[i])
|
||||||
|
compile->output.decls[i] = hlsl_strdup(ctx, output_decls[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return compile;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct hlsl_ir_node *hlsl_new_compile(struct hlsl_ctx *ctx, const struct hlsl_profile_info *profile,
|
||||||
|
struct hlsl_ir_function_decl *decl, struct hlsl_block *initializer, const struct vkd3d_shader_location *loc)
|
||||||
|
{
|
||||||
|
struct hlsl_ir_compile *compile;
|
||||||
|
struct hlsl_type *type = NULL;
|
||||||
|
|
||||||
|
switch (profile->type)
|
||||||
|
{
|
||||||
|
case VKD3D_SHADER_TYPE_PIXEL:
|
||||||
|
type = hlsl_get_type(ctx->cur_scope, "PixelShader", true, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VKD3D_SHADER_TYPE_VERTEX:
|
||||||
|
type = hlsl_get_type(ctx->cur_scope, "VertexShader", true, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VKD3D_SHADER_TYPE_GEOMETRY:
|
||||||
|
type = hlsl_get_type(ctx->cur_scope, "GeometryShader", true, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_PROFILE, "Invalid profile \"%s\".", profile->name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(compile = new_compile(ctx, profile, decl, initializer, type, 0, 0, NULL, loc)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return &compile->node;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct hlsl_ir_node *hlsl_new_compile_with_so(struct hlsl_ctx *ctx, struct hlsl_ir_compile *shader,
|
||||||
|
uint32_t stream, size_t count, const char *output_decls[4], const struct vkd3d_shader_location *loc)
|
||||||
|
{
|
||||||
|
struct hlsl_type *type = hlsl_get_type(ctx->cur_scope, "GeometryShader", true, true);
|
||||||
|
const struct hlsl_profile_info *profile = NULL;
|
||||||
|
struct hlsl_ir_function_decl *decl = NULL;
|
||||||
|
struct hlsl_ir_compile *compile;
|
||||||
|
struct hlsl_block initializers;
|
||||||
|
|
||||||
|
hlsl_block_init(&initializers);
|
||||||
|
|
||||||
|
/* non-fx profiles allow ConstructGSWithSO() but do not use nor type-check
|
||||||
|
* its arguments, so passing in NULL for "shader" creates a dummy geometry
|
||||||
|
* shader without any decl or profile. */
|
||||||
|
if (shader)
|
||||||
|
{
|
||||||
|
decl = shader->decl;
|
||||||
|
profile = shader->profile;
|
||||||
|
if (!(hlsl_clone_block(ctx, &initializers, &shader->initializers)))
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(compile = new_compile(ctx, profile, decl, &initializers, type, stream, count, output_decls, loc)))
|
||||||
|
{
|
||||||
|
hlsl_block_cleanup(&initializers);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
for (i = 0; i < compile->args_count; ++i)
|
|
||||||
hlsl_src_from_node(&compile->args[i], args[i]);
|
|
||||||
|
|
||||||
return &compile->node;
|
return &compile->node;
|
||||||
}
|
}
|
||||||
@@ -2878,43 +2908,17 @@ static struct hlsl_ir_node *clone_sync(struct hlsl_ctx *ctx, struct hlsl_ir_sync
|
|||||||
|
|
||||||
return &dst->node;
|
return &dst->node;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct hlsl_ir_node *clone_compile(struct hlsl_ctx *ctx,
|
static struct hlsl_ir_node *clone_compile(struct hlsl_ctx *ctx,
|
||||||
struct clone_instr_map *map, struct hlsl_ir_compile *compile)
|
struct clone_instr_map *map, struct hlsl_ir_compile *compile)
|
||||||
{
|
{
|
||||||
const char *profile_name = NULL;
|
struct hlsl_block initializers;
|
||||||
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)))
|
hlsl_clone_block(ctx, &initializers, &compile->initializers);
|
||||||
return NULL;
|
compile = new_compile(ctx, compile->profile, compile->decl, &initializers, compile->node.data_type,
|
||||||
|
compile->output.stream, compile->output.count, compile->output.decls, &compile->node.loc);
|
||||||
|
hlsl_block_cleanup(&initializers);
|
||||||
|
|
||||||
if (!(args = hlsl_alloc(ctx, sizeof(*args) * compile->args_count)))
|
return compile ? &compile->node : NULL;
|
||||||
{
|
|
||||||
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, compile->compile_type, 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_sampler_state(struct hlsl_ctx *ctx,
|
static struct hlsl_ir_node *clone_sampler_state(struct hlsl_ctx *ctx,
|
||||||
@@ -4069,26 +4073,24 @@ static void dump_ir_sync(struct vkd3d_string_buffer *buffer, const struct hlsl_i
|
|||||||
static void dump_ir_compile(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer,
|
static void dump_ir_compile(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer,
|
||||||
const struct hlsl_ir_compile *compile)
|
const struct hlsl_ir_compile *compile)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
vkd3d_string_buffer_printf(buffer, "compile %s {\n", compile->profile->name);
|
||||||
|
|
||||||
switch (compile->compile_type)
|
dump_block(ctx, buffer, &compile->initializers);
|
||||||
|
|
||||||
|
vkd3d_string_buffer_printf(buffer, " %10s }", "");
|
||||||
|
|
||||||
|
if (!compile->output.count)
|
||||||
|
return;
|
||||||
|
|
||||||
|
vkd3d_string_buffer_printf(buffer, "(");
|
||||||
|
for (size_t i = 0; i < compile->output.count; ++i)
|
||||||
{
|
{
|
||||||
case HLSL_COMPILE_TYPE_COMPILE:
|
const char *output = compile->output.decls[i];
|
||||||
vkd3d_string_buffer_printf(buffer, "compile %s {\n", compile->profile->name);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HLSL_COMPILE_TYPE_CONSTRUCTGSWITHSO:
|
if (!output)
|
||||||
vkd3d_string_buffer_printf(buffer, "ConstructGSWithSO {\n");
|
output = "NULL";
|
||||||
break;
|
vkd3d_string_buffer_printf(buffer, "%s", output);
|
||||||
}
|
if (i + 1 < compile->output.count)
|
||||||
|
|
||||||
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, ", ");
|
||||||
}
|
}
|
||||||
vkd3d_string_buffer_printf(buffer, ")");
|
vkd3d_string_buffer_printf(buffer, ")");
|
||||||
@@ -4455,12 +4457,11 @@ static void free_ir_sync(struct hlsl_ir_sync *sync)
|
|||||||
|
|
||||||
static void free_ir_compile(struct hlsl_ir_compile *compile)
|
static void free_ir_compile(struct hlsl_ir_compile *compile)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
hlsl_block_cleanup(&compile->initializers);
|
||||||
|
for (size_t i = 0; i < compile->output.count; ++i)
|
||||||
for (i = 0; i < compile->args_count; ++i)
|
{
|
||||||
hlsl_src_remove(&compile->args[i]);
|
vkd3d_free((void *)compile->output.decls[i]);
|
||||||
|
}
|
||||||
hlsl_block_cleanup(&compile->instrs);
|
|
||||||
vkd3d_free(compile);
|
vkd3d_free(compile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -957,33 +957,28 @@ struct hlsl_ir_string_constant
|
|||||||
char *string;
|
char *string;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Represents shader compilation call for effects, such as "CompileShader()".
|
#define HLSL_STREAM_OUTPUT_MAX 4
|
||||||
*
|
|
||||||
* Unlike hlsl_ir_call, it is not flattened, thus, it keeps track of its
|
/* Represents shader compilation call for effects, such as "CompileShader()". */
|
||||||
* arguments and maintains its own instruction block. */
|
|
||||||
struct hlsl_ir_compile
|
struct hlsl_ir_compile
|
||||||
{
|
{
|
||||||
struct hlsl_ir_node node;
|
struct hlsl_ir_node node;
|
||||||
|
|
||||||
enum hlsl_compile_type
|
/* Special field to store the profile argument. */
|
||||||
{
|
|
||||||
/* A shader compilation through the CompileShader() function or the "compile" syntax. */
|
|
||||||
HLSL_COMPILE_TYPE_COMPILE,
|
|
||||||
/* A call to ConstructGSWithSO(), which receives a geometry shader and retrieves one as well. */
|
|
||||||
HLSL_COMPILE_TYPE_CONSTRUCTGSWITHSO,
|
|
||||||
} compile_type;
|
|
||||||
|
|
||||||
/* Special field to store the profile argument for HLSL_COMPILE_TYPE_COMPILE. */
|
|
||||||
const struct hlsl_profile_info *profile;
|
const struct hlsl_profile_info *profile;
|
||||||
|
struct hlsl_ir_function_decl *decl;
|
||||||
|
|
||||||
/* Block containing the instructions required by the arguments of the
|
/* Block containing the static initializers passed as arguments of the
|
||||||
* compilation call. */
|
* compilation call. */
|
||||||
struct hlsl_block instrs;
|
struct hlsl_block initializers;
|
||||||
|
|
||||||
/* Arguments to the compilation call. For HLSL_COMPILE_TYPE_COMPILE
|
/* Stream Output constants, filled by a ConstructGSWithSO() call. */
|
||||||
* args[0] is an hlsl_ir_call to the specified function. */
|
struct
|
||||||
struct hlsl_src *args;
|
{
|
||||||
unsigned int args_count;
|
uint32_t stream;
|
||||||
|
unsigned count;
|
||||||
|
const char *decls[HLSL_STREAM_OUTPUT_MAX];
|
||||||
|
} output;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Represents a state block initialized with the "sampler_state" keyword. */
|
/* Represents a state block initialized with the "sampler_state" keyword. */
|
||||||
@@ -1745,9 +1740,10 @@ bool hlsl_index_is_resource_access(struct hlsl_ir_index *index);
|
|||||||
bool hlsl_index_chain_has_resource_access(struct hlsl_ir_index *index);
|
bool hlsl_index_chain_has_resource_access(struct hlsl_ir_index *index);
|
||||||
bool hlsl_index_chain_has_tgsm_access(struct hlsl_ir_index *index);
|
bool hlsl_index_chain_has_tgsm_access(struct hlsl_ir_index *index);
|
||||||
|
|
||||||
struct hlsl_ir_node *hlsl_new_compile(struct hlsl_ctx *ctx, enum hlsl_compile_type compile_type,
|
struct hlsl_ir_node *hlsl_new_compile(struct hlsl_ctx *ctx, const struct hlsl_profile_info *profile,
|
||||||
const char *profile_name, struct hlsl_ir_node **args, unsigned int args_count,
|
struct hlsl_ir_function_decl *decl, struct hlsl_block *initializer, const struct vkd3d_shader_location *loc);
|
||||||
struct hlsl_block *args_instrs, const struct vkd3d_shader_location *loc);
|
struct hlsl_ir_node *hlsl_new_compile_with_so(struct hlsl_ctx *ctx, struct hlsl_ir_compile *shader,
|
||||||
|
uint32_t stream, size_t count, const char *output_decls[4], const struct vkd3d_shader_location *loc);
|
||||||
struct hlsl_ir_node *hlsl_new_interlocked(struct hlsl_ctx *ctx, enum hlsl_interlocked_op op, struct hlsl_type *type,
|
struct hlsl_ir_node *hlsl_new_interlocked(struct hlsl_ctx *ctx, enum hlsl_interlocked_op op, struct hlsl_type *type,
|
||||||
const struct hlsl_deref *dst, struct hlsl_ir_node *coords, struct hlsl_ir_node *cmp_value,
|
const struct hlsl_deref *dst, struct hlsl_ir_node *coords, struct hlsl_ir_node *cmp_value,
|
||||||
struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc);
|
struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc);
|
||||||
|
|||||||
@@ -3015,11 +3015,9 @@ static void add_void_expr(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
|||||||
hlsl_block_add_expr(ctx, block, HLSL_OP0_VOID, operands, ctx->builtin_types.Void, loc);
|
hlsl_block_add_expr(ctx, block, HLSL_OP0_VOID, operands, ctx->builtin_types.Void, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct hlsl_ir_node *add_user_call(struct hlsl_ctx *ctx,
|
static bool parse_function_call_arguments(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl *func,
|
||||||
struct hlsl_ir_function_decl *func, const struct parse_initializer *args,
|
const struct parse_initializer *args, bool is_compile, const struct vkd3d_shader_location *loc)
|
||||||
bool is_compile, const struct vkd3d_shader_location *loc)
|
|
||||||
{
|
{
|
||||||
struct hlsl_ir_node *call;
|
|
||||||
unsigned int i, j, k;
|
unsigned int i, j, k;
|
||||||
|
|
||||||
VKD3D_ASSERT(args->args_count <= func->parameters.count);
|
VKD3D_ASSERT(args->args_count <= func->parameters.count);
|
||||||
@@ -3077,12 +3075,22 @@ static struct hlsl_ir_node *add_user_call(struct hlsl_ctx *ctx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct hlsl_ir_node *add_user_call(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func,
|
||||||
|
const struct parse_initializer *args, const struct vkd3d_shader_location *loc)
|
||||||
|
{
|
||||||
|
struct hlsl_ir_node *call;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (!parse_function_call_arguments(ctx, func, args, false, loc))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if (!(call = hlsl_new_call(ctx, func, loc)))
|
if (!(call = hlsl_new_call(ctx, func, loc)))
|
||||||
return NULL;
|
return NULL;
|
||||||
hlsl_block_add_instr(args->instrs, call);
|
|
||||||
|
|
||||||
if (is_compile)
|
hlsl_block_add_instr(args->instrs, call);
|
||||||
return call;
|
|
||||||
|
|
||||||
for (i = 0; i < args->args_count; ++i)
|
for (i = 0; i < args->args_count; ++i)
|
||||||
{
|
{
|
||||||
@@ -3288,7 +3296,7 @@ static bool write_acos_or_asin(struct hlsl_ctx *ctx,
|
|||||||
if (!func)
|
if (!func)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return !!add_user_call(ctx, func, params, false, loc);
|
return !!add_user_call(ctx, func, params, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool intrinsic_acos(struct hlsl_ctx *ctx,
|
static bool intrinsic_acos(struct hlsl_ctx *ctx,
|
||||||
@@ -3428,7 +3436,7 @@ static bool write_atan_or_atan2(struct hlsl_ctx *ctx,
|
|||||||
if (!func)
|
if (!func)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return !!add_user_call(ctx, func, params, false, loc);
|
return !!add_user_call(ctx, func, params, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool intrinsic_atan(struct hlsl_ctx *ctx,
|
static bool intrinsic_atan(struct hlsl_ctx *ctx,
|
||||||
@@ -3611,7 +3619,7 @@ static bool write_cosh_or_sinh(struct hlsl_ctx *ctx,
|
|||||||
if (!func)
|
if (!func)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return !!add_user_call(ctx, func, params, false, loc);
|
return !!add_user_call(ctx, func, params, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool intrinsic_cosh(struct hlsl_ctx *ctx,
|
static bool intrinsic_cosh(struct hlsl_ctx *ctx,
|
||||||
@@ -3823,7 +3831,7 @@ static bool intrinsic_determinant(struct hlsl_ctx *ctx,
|
|||||||
if (!func)
|
if (!func)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return !!add_user_call(ctx, func, params, false, loc);
|
return !!add_user_call(ctx, func, params, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool intrinsic_distance(struct hlsl_ctx *ctx,
|
static bool intrinsic_distance(struct hlsl_ctx *ctx,
|
||||||
@@ -3893,7 +3901,7 @@ static bool intrinsic_dst(struct hlsl_ctx *ctx, const struct parse_initializer *
|
|||||||
if (!func)
|
if (!func)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return !!add_user_call(ctx, func, params, false, loc);
|
return !!add_user_call(ctx, func, params, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool intrinsic_exp(struct hlsl_ctx *ctx,
|
static bool intrinsic_exp(struct hlsl_ctx *ctx,
|
||||||
@@ -3947,7 +3955,7 @@ static bool intrinsic_faceforward(struct hlsl_ctx *ctx,
|
|||||||
if (!func)
|
if (!func)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return !!add_user_call(ctx, func, params, false, loc);
|
return !!add_user_call(ctx, func, params, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool intrinsic_f16tof32(struct hlsl_ctx *ctx,
|
static bool intrinsic_f16tof32(struct hlsl_ctx *ctx,
|
||||||
@@ -4143,7 +4151,7 @@ static bool intrinsic_frexp(struct hlsl_ctx *ctx,
|
|||||||
if (!func)
|
if (!func)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return !!add_user_call(ctx, func, params, false, loc);
|
return !!add_user_call(ctx, func, params, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool intrinsic_fwidth(struct hlsl_ctx *ctx,
|
static bool intrinsic_fwidth(struct hlsl_ctx *ctx,
|
||||||
@@ -4170,7 +4178,7 @@ static bool intrinsic_fwidth(struct hlsl_ctx *ctx,
|
|||||||
if (!func)
|
if (!func)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return !!add_user_call(ctx, func, params, false, loc);
|
return !!add_user_call(ctx, func, params, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool intrinsic_isinf(struct hlsl_ctx *ctx,
|
static bool intrinsic_isinf(struct hlsl_ctx *ctx,
|
||||||
@@ -4270,7 +4278,7 @@ static bool intrinsic_lit(struct hlsl_ctx *ctx,
|
|||||||
if (!(func = hlsl_compile_internal_function(ctx, "lit", body)))
|
if (!(func = hlsl_compile_internal_function(ctx, "lit", body)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return !!add_user_call(ctx, func, params, false, loc);
|
return !!add_user_call(ctx, func, params, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool intrinsic_log(struct hlsl_ctx *ctx,
|
static bool intrinsic_log(struct hlsl_ctx *ctx,
|
||||||
@@ -4371,7 +4379,7 @@ static bool intrinsic_modf(struct hlsl_ctx *ctx,
|
|||||||
if (!func)
|
if (!func)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return !!add_user_call(ctx, func, params, false, loc);
|
return !!add_user_call(ctx, func, params, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool intrinsic_mul(struct hlsl_ctx *ctx,
|
static bool intrinsic_mul(struct hlsl_ctx *ctx,
|
||||||
@@ -4620,7 +4628,7 @@ static bool intrinsic_refract(struct hlsl_ctx *ctx,
|
|||||||
if (!func)
|
if (!func)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return !!add_user_call(ctx, func, params, false, loc);
|
return !!add_user_call(ctx, func, params, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool intrinsic_round(struct hlsl_ctx *ctx,
|
static bool intrinsic_round(struct hlsl_ctx *ctx,
|
||||||
@@ -4722,7 +4730,7 @@ static bool intrinsic_sincos(struct hlsl_ctx *ctx,
|
|||||||
if (!func)
|
if (!func)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return !!add_user_call(ctx, func, params, false, loc);
|
return !!add_user_call(ctx, func, params, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool intrinsic_sinh(struct hlsl_ctx *ctx,
|
static bool intrinsic_sinh(struct hlsl_ctx *ctx,
|
||||||
@@ -4757,7 +4765,7 @@ static bool intrinsic_smoothstep(struct hlsl_ctx *ctx,
|
|||||||
if (!func)
|
if (!func)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return !!add_user_call(ctx, func, params, false, loc);
|
return !!add_user_call(ctx, func, params, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool intrinsic_sqrt(struct hlsl_ctx *ctx,
|
static bool intrinsic_sqrt(struct hlsl_ctx *ctx,
|
||||||
@@ -4831,7 +4839,7 @@ static bool intrinsic_tanh(struct hlsl_ctx *ctx,
|
|||||||
if (!func)
|
if (!func)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return !!add_user_call(ctx, func, params, false, loc);
|
return !!add_user_call(ctx, func, params, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *params,
|
static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *params,
|
||||||
@@ -5356,17 +5364,109 @@ static bool intrinsic_AllMemoryBarrierWithGroupSync(struct hlsl_ctx *ctx,
|
|||||||
static bool intrinsic_ConstructGSWithSO(struct hlsl_ctx *ctx,
|
static bool intrinsic_ConstructGSWithSO(struct hlsl_ctx *ctx,
|
||||||
const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
|
const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
|
||||||
{
|
{
|
||||||
struct hlsl_ir_node *compile;
|
const char *strings[HLSL_STREAM_OUTPUT_MAX] = {0};
|
||||||
|
size_t string_count = params->args_count - 1;
|
||||||
|
struct hlsl_ir_compile *compile;
|
||||||
|
struct hlsl_ir_node *node;
|
||||||
|
uint32_t stream_index = 0;
|
||||||
|
struct hlsl_ir_var *var;
|
||||||
|
|
||||||
if (params->args_count != 2 && params->args_count != 6)
|
if (params->args_count != 2 && params->args_count != 6)
|
||||||
|
{
|
||||||
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT,
|
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT,
|
||||||
"Wrong number of arguments to ConstructGSWithSO(): expected 2 or 6, but got %u.", params->args_count);
|
"Unexpected number of arguments to ConstructGSWithSO(): expected 2 or 6, but got %u.",
|
||||||
|
params->args_count);
|
||||||
if (!(compile = hlsl_new_compile(ctx, HLSL_COMPILE_TYPE_CONSTRUCTGSWITHSO,
|
|
||||||
NULL, params->args, params->args_count, params->instrs, loc)))
|
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx->profile->type != VKD3D_SHADER_TYPE_EFFECT)
|
||||||
|
{
|
||||||
|
if (!(node = hlsl_new_compile_with_so(ctx, NULL, 0, 0, NULL, loc)))
|
||||||
|
return false;
|
||||||
|
hlsl_block_add_instr(params->instrs, node);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
node = params->args[0];
|
||||||
|
switch (node->type)
|
||||||
|
{
|
||||||
|
case HLSL_IR_COMPILE:
|
||||||
|
compile = hlsl_ir_compile(node);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HLSL_IR_LOAD:
|
||||||
|
var = hlsl_ir_load(node)->src.var;
|
||||||
|
if (var->data_type->class == HLSL_CLASS_ARRAY || !hlsl_type_is_shader(var->data_type))
|
||||||
|
{
|
||||||
|
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
|
||||||
|
"\"%s\" is not a shader compilation.", var->name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
hlsl_fixme(ctx, loc, "Unhandled HLSL_IR_LOAD in ConstructGSWithSO().");
|
||||||
|
return false;
|
||||||
|
|
||||||
|
case HLSL_IR_INDEX:
|
||||||
|
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
|
||||||
|
"Stream output shaders can't be constructed with array indexes.");
|
||||||
|
return false;
|
||||||
|
|
||||||
|
default:
|
||||||
|
hlsl_fixme(ctx, loc, "Unhandled node type in ConstructGSWithSO().");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compile->profile->type != VKD3D_SHADER_TYPE_VERTEX && compile->profile->type != VKD3D_SHADER_TYPE_GEOMETRY)
|
||||||
|
{
|
||||||
|
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
|
||||||
|
"Stream output shaders can only be constructed with vertex or geometry shaders.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params->args_count == 6)
|
||||||
|
{
|
||||||
|
struct hlsl_block stream_index_block;
|
||||||
|
|
||||||
|
--string_count;
|
||||||
|
|
||||||
|
if (!(node = hlsl_clone_instr(ctx, params->args[5])))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
hlsl_block_init(&stream_index_block);
|
||||||
|
hlsl_block_add_instr(&stream_index_block, node);
|
||||||
|
|
||||||
|
stream_index = evaluate_static_expression_as_uint(ctx, &stream_index_block, loc);
|
||||||
|
|
||||||
|
hlsl_block_cleanup(&stream_index_block);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < string_count; ++i)
|
||||||
|
{
|
||||||
|
struct hlsl_ir_node *stream_node = params->args[i + 1];
|
||||||
|
|
||||||
|
switch (stream_node->type)
|
||||||
|
{
|
||||||
|
case HLSL_IR_STRING_CONSTANT:
|
||||||
|
strings[i] = hlsl_ir_string_constant(stream_node)->string;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HLSL_IR_CONSTANT:
|
||||||
|
if (stream_node->data_type->class == HLSL_CLASS_NULL)
|
||||||
|
continue;
|
||||||
|
/* fall-through */
|
||||||
|
default:
|
||||||
|
hlsl_error(ctx, &stream_node->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
|
||||||
|
"Stream Output declarations must be a literal string.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VKD3D_ASSERT(string_count <= ARRAY_SIZE(strings));
|
||||||
|
|
||||||
|
if (!(node = hlsl_new_compile_with_so(ctx, compile, stream_index, string_count, strings, loc)))
|
||||||
|
return false;
|
||||||
|
hlsl_block_add_instr(params->instrs, node);
|
||||||
|
|
||||||
hlsl_block_add_instr(params->instrs, compile);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5549,7 +5649,7 @@ static struct hlsl_block *add_call(struct hlsl_ctx *ctx, const char *name,
|
|||||||
|
|
||||||
if ((decl = find_function_call(ctx, name, args, false, loc)))
|
if ((decl = find_function_call(ctx, name, args, false, loc)))
|
||||||
{
|
{
|
||||||
if (!add_user_call(ctx, decl, args, false, loc))
|
if (!add_user_call(ctx, decl, args, loc))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
else if ((intrinsic = bsearch(name, intrinsic_functions, ARRAY_SIZE(intrinsic_functions),
|
else if ((intrinsic = bsearch(name, intrinsic_functions, ARRAY_SIZE(intrinsic_functions),
|
||||||
@@ -5608,9 +5708,10 @@ fail:
|
|||||||
static struct hlsl_block *add_shader_compilation(struct hlsl_ctx *ctx, const char *profile_name,
|
static struct hlsl_block *add_shader_compilation(struct hlsl_ctx *ctx, const char *profile_name,
|
||||||
const char *function_name, struct parse_initializer *args, const struct vkd3d_shader_location *loc)
|
const char *function_name, struct parse_initializer *args, const struct vkd3d_shader_location *loc)
|
||||||
{
|
{
|
||||||
struct hlsl_ir_node *compile, *call_to_compile = NULL;
|
const struct hlsl_profile_info *profile_info;
|
||||||
struct hlsl_ir_function_decl *decl;
|
struct hlsl_ir_function_decl *decl;
|
||||||
struct hlsl_block *block = NULL;
|
struct hlsl_block *block = NULL;
|
||||||
|
struct hlsl_ir_node *compile;
|
||||||
|
|
||||||
if (!ctx->in_state_block && ctx->cur_scope != ctx->globals)
|
if (!ctx->in_state_block && ctx->cur_scope != ctx->globals)
|
||||||
{
|
{
|
||||||
@@ -5635,6 +5736,12 @@ static struct hlsl_block *add_shader_compilation(struct hlsl_ctx *ctx, const cha
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(profile_info = hlsl_get_target_info(profile_name)))
|
||||||
|
{
|
||||||
|
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_PROFILE, "Unknown profile \"%s\".", profile_name);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < args->args_count; ++i)
|
for (unsigned int i = 0; i < args->args_count; ++i)
|
||||||
{
|
{
|
||||||
if (args->args[i]->data_type->class == HLSL_CLASS_ERROR)
|
if (args->args[i]->data_type->class == HLSL_CLASS_ERROR)
|
||||||
@@ -5645,11 +5752,10 @@ static struct hlsl_block *add_shader_compilation(struct hlsl_ctx *ctx, const cha
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(call_to_compile = add_user_call(ctx, decl, args, true, loc)))
|
if (!parse_function_call_arguments(ctx, decl, args, true, loc))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!(compile = hlsl_new_compile(ctx, HLSL_COMPILE_TYPE_COMPILE,
|
if (!(compile = hlsl_new_compile(ctx, profile_info, decl, args->instrs, loc)))
|
||||||
profile_name, &call_to_compile, 1, args->instrs, loc)))
|
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
block = make_block(ctx, compile);
|
block = make_block(ctx, compile);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
[pixel shader todo]
|
[pixel shader]
|
||||||
float4 main() : sv_target { return 0; }
|
float4 main() : sv_target { return 0; }
|
||||||
|
|
||||||
GeometryShader gs1 = CompileShader(gs_5_0, main());
|
GeometryShader gs1 = CompileShader(gs_5_0, main());
|
||||||
|
|||||||
Reference in New Issue
Block a user