Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • wine/vkd3d
  • stefan/vkd3d
  • cmccarthy/vkd3d
  • giomasce/vkd3d
  • fcasas/vkd3d
  • jactry/vkd3d
  • ReDress/vkd3d
  • mstorsjo/vkd3d
  • huw/vkd3d
  • julliard/vkd3d
  • bshanks/vkd3d
  • zfigura/vkd3d
  • hverbeet/vkd3d
  • DarkShadow44/vkd3d
  • nsivov/vkd3d
  • dhary686/vkd3d
  • Mystral/vkd3d
  • maljaf/vkd3d
  • smcv/vkd3d
  • flibitijibibo/vkd3d
  • q4a/vkd3d
  • jsikorski/vkd3d
  • alesliehughes/vkd3d-alesliehughes
  • vitorhnn/vkd3d
  • agusev/vkd3d
  • etang-cw/vkd3d
  • petrathekat/vkd3d
  • simon.mr995/vkd3d
  • sgwaki/vkd3d
  • jacek/vkd3d
  • fweimer/vkd3d
  • Clara/vkd3d
  • disini/vkd3d
  • antenabr2/vkd3d
  • gilvbp/vkd3d
  • yshui/vkd3d
  • shaunren/vkd3d
  • jennetsaryyewa96/vkd3d
  • Jamesattay/vkd3d
  • zacemmneeto77/vkd3d
  • GermanAizek/vkd3d
  • opespinach/vkd3d
  • ruslanboyka201/vkd3d
  • navi/vkd3d
  • Feifan/vkd3d
  • yashmhmdly172/vkd3d
  • Sec32fun32/vkd3d
  • ritalat/vkd3d
  • ivyl/vkd3d
  • baikaishiuc/vkd3d
  • austin987/vkd3d
  • TornadoCookie/vkd3d
52 results
Show changes
Commits on Source (16)
Showing
with 513 additions and 98 deletions
......@@ -294,6 +294,7 @@ libvkd3d_shader_la_SOURCES = \
libs/vkd3d-shader/d3dbc.c \
libs/vkd3d-shader/dxbc.c \
libs/vkd3d-shader/dxil.c \
libs/vkd3d-shader/fx.c \
libs/vkd3d-shader/glsl.c \
libs/vkd3d-shader/hlsl.c \
libs/vkd3d-shader/hlsl.h \
......
......@@ -52,6 +52,7 @@
#define TAG_AON9 VKD3D_MAKE_TAG('A', 'o', 'n', '9')
#define TAG_DXBC VKD3D_MAKE_TAG('D', 'X', 'B', 'C')
#define TAG_DXIL VKD3D_MAKE_TAG('D', 'X', 'I', 'L')
#define TAG_FX10 VKD3D_MAKE_TAG('F', 'X', '1', '0')
#define TAG_ISG1 VKD3D_MAKE_TAG('I', 'S', 'G', '1')
#define TAG_ISGN VKD3D_MAKE_TAG('I', 'S', 'G', 'N')
#define TAG_OSG1 VKD3D_MAKE_TAG('O', 'S', 'G', '1')
......
......@@ -785,6 +785,11 @@ enum vkd3d_shader_target_type
* An 'OpenGL Shading Language' shader. \since 1.3
*/
VKD3D_SHADER_TARGET_GLSL,
/**
* Binary format used by Direct3D 9/10.x/11 effects profiles.
* Output is a raw FX section without container. \since 1.11
*/
VKD3D_SHADER_TARGET_FX,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_TARGET_TYPE),
};
......@@ -1270,6 +1275,8 @@ enum vkd3d_shader_descriptor_range_flags
VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE = 0x2,
VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE = 0x4,
VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DATA_STATIC = 0x8,
/** \since 1.11 */
VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS = 0x10000,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_DESCRIPTOR_RANGE_FLAGS),
};
......
......@@ -365,6 +365,7 @@ struct vkd3d_d3d_asm_compiler
struct vkd3d_shader_version shader_version;
struct vkd3d_d3d_asm_colours colours;
enum vsir_asm_dialect dialect;
const struct vkd3d_shader_instruction *current;
};
static int VKD3D_PRINTF_FUNC(2, 3) shader_addline(struct vkd3d_string_buffer *buffer, const char *format, ...)
......@@ -841,6 +842,27 @@ static void shader_print_bool_literal(struct vkd3d_d3d_asm_compiler *compiler,
compiler->colours.literal, b ? "true" : "false", compiler->colours.reset, suffix);
}
static void shader_print_untyped_literal(struct vkd3d_d3d_asm_compiler *compiler,
const char *prefix, uint32_t u, const char *suffix)
{
union
{
uint32_t u;
float f;
} value;
unsigned int exponent = (u >> 23) & 0xff;
value.u = u;
if (exponent != 0 && exponent != 0xff)
return shader_print_float_literal(compiler, prefix, value.f, suffix);
if (u <= 10000)
return shader_print_uint_literal(compiler, prefix, value.u, suffix);
return shader_print_hex_literal(compiler, prefix, value.u, suffix);
}
static void shader_print_subscript(struct vkd3d_d3d_asm_compiler *compiler,
unsigned int offset, const struct vkd3d_shader_src_param *rel_addr)
{
......@@ -1102,6 +1124,19 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const
if (reg->type == VKD3DSPR_IMMCONST)
{
bool untyped = false;
switch (compiler->current->handler_idx)
{
case VKD3DSIH_MOV:
case VKD3DSIH_MOVC:
untyped = true;
break;
default:
break;
}
shader_addline(buffer, "%s(", compiler->colours.reset);
switch (reg->dimension)
{
......@@ -1109,7 +1144,10 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const
switch (reg->data_type)
{
case VKD3D_DATA_FLOAT:
shader_print_float_literal(compiler, "", reg->u.immconst_f32[0], "");
if (untyped)
shader_print_untyped_literal(compiler, "", reg->u.immconst_u32[0], "");
else
shader_print_float_literal(compiler, "", reg->u.immconst_f32[0], "");
break;
case VKD3D_DATA_INT:
shader_print_int_literal(compiler, "", reg->u.immconst_u32[0], "");
......@@ -1129,10 +1167,20 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const
switch (reg->data_type)
{
case VKD3D_DATA_FLOAT:
shader_print_float_literal(compiler, "", reg->u.immconst_f32[0], "");
shader_print_float_literal(compiler, ", ", reg->u.immconst_f32[1], "");
shader_print_float_literal(compiler, ", ", reg->u.immconst_f32[2], "");
shader_print_float_literal(compiler, ", ", reg->u.immconst_f32[3], "");
if (untyped)
{
shader_print_untyped_literal(compiler, "", reg->u.immconst_u32[0], "");
shader_print_untyped_literal(compiler, ", ", reg->u.immconst_u32[1], "");
shader_print_untyped_literal(compiler, ", ", reg->u.immconst_u32[2], "");
shader_print_untyped_literal(compiler, ", ", reg->u.immconst_u32[3], "");
}
else
{
shader_print_float_literal(compiler, "", reg->u.immconst_f32[0], "");
shader_print_float_literal(compiler, ", ", reg->u.immconst_f32[1], "");
shader_print_float_literal(compiler, ", ", reg->u.immconst_f32[2], "");
shader_print_float_literal(compiler, ", ", reg->u.immconst_f32[3], "");
}
break;
case VKD3D_DATA_INT:
shader_print_int_literal(compiler, "", reg->u.immconst_u32[0], "");
......@@ -1678,6 +1726,8 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
struct vkd3d_string_buffer *buffer = &compiler->buffer;
unsigned int i;
compiler->current = ins;
if (ins->predicate)
{
vkd3d_string_buffer_printf(buffer, "(");
......
......@@ -623,7 +623,8 @@ static void shader_validate_descriptor_range1(const struct vkd3d_shader_descript
| VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_VOLATILE
| VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE
| VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE
| VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DATA_STATIC);
| VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DATA_STATIC
| VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS);
if (unknown_flags)
FIXME("Unknown descriptor range flags %#x.\n", unknown_flags);
......
......@@ -2331,8 +2331,8 @@ static const struct sm6_value *sm6_parser_get_value_by_ref(struct sm6_parser *sm
static bool sm6_parser_declare_function(struct sm6_parser *sm6, const struct dxil_record *record)
{
const struct sm6_type *type, *ret_type;
const unsigned int max_count = 15;
const struct sm6_type *ret_type;
struct sm6_value *fn;
unsigned int i, j;
......@@ -2347,18 +2347,18 @@ static bool sm6_parser_declare_function(struct sm6_parser *sm6, const struct dxi
fn->u.function.name = "";
}
if (!(fn->type = sm6_parser_get_type(sm6, record->operands[0])))
if (!(type = sm6_parser_get_type(sm6, record->operands[0])))
return false;
if (!sm6_type_is_function(fn->type))
if (!sm6_type_is_function(type))
{
WARN("Type is not a function.\n");
return false;
}
ret_type = fn->type->u.function->ret_type;
ret_type = type->u.function->ret_type;
if (!(fn->type = sm6_type_get_pointer_to_type(fn->type, ADDRESS_SPACE_DEFAULT, sm6)))
if (!(fn->type = sm6_type_get_pointer_to_type(type, ADDRESS_SPACE_DEFAULT, sm6)))
{
WARN("Failed to get pointer type for type %u.\n", fn->type->class);
WARN("Failed to get pointer type for type %u.\n", type->class);
return false;
}
......
/*
* FX (Direct3D 9/10/11 effect) support
*
* Copyright 2023 Nikolay Sivov for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "hlsl.h"
struct fx_write_context
{
struct vkd3d_bytecode_buffer unstructured;
struct vkd3d_bytecode_buffer structured;
uint32_t technique_count;
int status;
};
static uint32_t fx_put_raw_string(struct fx_write_context *fx, const char *string)
{
/* NULLs are emitted as empty strings using the same 4 bytes at the start of the section. */
return string ? put_string(&fx->unstructured, string) : 0;
}
static void write_technique(struct hlsl_ir_var *var, struct fx_write_context *fx)
{
struct vkd3d_bytecode_buffer *buffer = &fx->structured;
uint32_t name_offset;
name_offset = fx_put_raw_string(fx, var->name);
put_u32(buffer, name_offset);
put_u32(buffer, 0); /* Pass count. */
put_u32(buffer, 0); /* Annotation count. */
/* TODO: passes */
}
static void set_status(struct fx_write_context *fx, int status)
{
if (fx->status < 0)
return;
if (status < 0)
fx->status = status;
}
static void write_techniques(struct hlsl_scope *scope, struct fx_write_context *fx)
{
struct hlsl_ir_var *var;
LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry)
{
const struct hlsl_type *type = var->data_type;
if (type->base_type == HLSL_TYPE_TECHNIQUE && type->e.version == 10)
{
write_technique(var, fx);
++fx->technique_count;
}
}
set_status(fx, fx->unstructured.status);
set_status(fx, fx->structured.status);
}
static int hlsl_fx_4_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out)
{
struct vkd3d_bytecode_buffer buffer = { 0 };
struct fx_write_context fx;
uint32_t size_offset, size;
memset(&fx, 0, sizeof(fx));
put_u32(&fx.unstructured, 0); /* Empty string placeholder. */
/* TODO: buffers */
/* TODO: objects */
/* TODO: shared buffers */
/* TODO: shared objects */
write_techniques(ctx->globals, &fx);
put_u32(&buffer, ctx->profile->minor_version == 0 ? 0xfeff1001 : 0xfeff1011); /* Version. */
put_u32(&buffer, 0); /* Buffer count. */
put_u32(&buffer, 0); /* Variable count. */
put_u32(&buffer, 0); /* Object count. */
put_u32(&buffer, 0); /* Pool buffer count. */
put_u32(&buffer, 0); /* Pool variable count. */
put_u32(&buffer, 0); /* Pool object count. */
put_u32(&buffer, fx.technique_count);
size_offset = put_u32(&buffer, 0); /* Unstructured size. */
put_u32(&buffer, 0); /* String count. */
put_u32(&buffer, 0); /* Texture object count. */
put_u32(&buffer, 0); /* Depth stencil state count. */
put_u32(&buffer, 0); /* Blend state count. */
put_u32(&buffer, 0); /* Rasterizer state count. */
put_u32(&buffer, 0); /* Sampler state count. */
put_u32(&buffer, 0); /* Rendertarget view count. */
put_u32(&buffer, 0); /* Depth stencil view count. */
put_u32(&buffer, 0); /* Shader count. */
put_u32(&buffer, 0); /* Inline shader count. */
size = align(fx.unstructured.size, 4);
set_u32(&buffer, size_offset, size);
bytecode_put_bytes(&buffer, fx.unstructured.data, fx.unstructured.size);
bytecode_put_bytes(&buffer, fx.structured.data, fx.structured.size);
vkd3d_free(fx.unstructured.data);
vkd3d_free(fx.structured.data);
set_status(&fx, buffer.status);
if (!fx.status)
{
out->code = buffer.data;
out->size = buffer.size;
}
if (fx.status < 0)
ctx->result = fx.status;
return fx.status;
}
int hlsl_emit_effect_binary(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out)
{
if (ctx->profile->major_version == 2)
{
hlsl_fixme(ctx, &ctx->location, "Writing fx_2_0 binaries is not implemented.");
return VKD3D_ERROR_NOT_IMPLEMENTED;
}
else if (ctx->profile->major_version == 4)
{
return hlsl_fx_4_write(ctx, out);
}
else if (ctx->profile->major_version == 5)
{
hlsl_fixme(ctx, &ctx->location, "Writing fx_5_0 binaries is not implemented.");
return VKD3D_ERROR_NOT_IMPLEMENTED;
}
else
{
vkd3d_unreachable();
}
}
......@@ -98,19 +98,22 @@ bool hlsl_add_var(struct hlsl_ctx *ctx, struct hlsl_ir_var *decl, bool local_var
struct hlsl_scope *scope = ctx->cur_scope;
struct hlsl_ir_var *var;
LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry)
if (decl->name)
{
if (!strcmp(decl->name, var->name))
return false;
}
if (local_var && scope->upper->upper == ctx->globals)
{
/* Check whether the variable redefines a function parameter. */
LIST_FOR_EACH_ENTRY(var, &scope->upper->vars, struct hlsl_ir_var, scope_entry)
LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry)
{
if (!strcmp(decl->name, var->name))
if (var->name && !strcmp(decl->name, var->name))
return false;
}
if (local_var && scope->upper->upper == ctx->globals)
{
/* Check whether the variable redefines a function parameter. */
LIST_FOR_EACH_ENTRY(var, &scope->upper->vars, struct hlsl_ir_var, scope_entry)
{
if (var->name && !strcmp(decl->name, var->name))
return false;
}
}
}
list_add_tail(&scope->vars, &decl->scope_entry);
......@@ -123,7 +126,7 @@ struct hlsl_ir_var *hlsl_get_var(struct hlsl_scope *scope, const char *name)
LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry)
{
if (!strcmp(name, var->name))
if (var->name && !strcmp(name, var->name))
return var;
}
if (!scope->upper)
......@@ -915,6 +918,11 @@ bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2
if (t1->class == HLSL_CLASS_ARRAY)
return t1->e.array.elements_count == t2->e.array.elements_count
&& hlsl_types_are_equal(t1->e.array.type, t2->e.array.type);
if (t1->class == HLSL_CLASS_OBJECT)
{
if (t1->base_type == HLSL_TYPE_TECHNIQUE && t1->e.version != t2->e.version)
return false;
}
return true;
}
......@@ -993,6 +1001,13 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old,
break;
}
case HLSL_CLASS_OBJECT:
{
if (type->base_type == HLSL_TYPE_TECHNIQUE)
type->e.version = old->e.version;
break;
}
default:
break;
}
......@@ -3351,12 +3366,25 @@ static void declare_predefined_types(struct hlsl_ctx *ctx)
{"float", HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1},
{"vector", HLSL_CLASS_VECTOR, HLSL_TYPE_FLOAT, 4, 1},
{"matrix", HLSL_CLASS_MATRIX, HLSL_TYPE_FLOAT, 4, 4},
{"fxgroup", HLSL_CLASS_OBJECT, HLSL_TYPE_EFFECT_GROUP, 1, 1},
{"STRING", HLSL_CLASS_OBJECT, HLSL_TYPE_STRING, 1, 1},
{"TEXTURE", HLSL_CLASS_OBJECT, HLSL_TYPE_TEXTURE, 1, 1},
{"PIXELSHADER", HLSL_CLASS_OBJECT, HLSL_TYPE_PIXELSHADER, 1, 1},
{"VERTEXSHADER", HLSL_CLASS_OBJECT, HLSL_TYPE_VERTEXSHADER, 1, 1},
};
static const struct
{
char *name;
unsigned int version;
}
technique_types[] =
{
{"technique", 9},
{"technique10", 10},
{"technique11", 11},
};
for (bt = 0; bt <= HLSL_TYPE_LAST_SCALAR; ++bt)
{
for (y = 1; y <= 4; ++y)
......@@ -3461,6 +3489,13 @@ static void declare_predefined_types(struct hlsl_ctx *ctx)
effect_types[i].base_type, effect_types[i].dimx, effect_types[i].dimy);
hlsl_scope_add_type(ctx->globals, type);
}
for (i = 0; i < ARRAY_SIZE(technique_types); ++i)
{
type = hlsl_new_type(ctx, technique_types[i].name, HLSL_CLASS_OBJECT, HLSL_TYPE_TECHNIQUE, 1, 1);
type->e.version = technique_types[i].version;
hlsl_scope_add_type(ctx->globals, type);
}
}
static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info,
......@@ -3596,7 +3631,13 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d
return VKD3D_ERROR_NOT_IMPLEMENTED;
}
if (compile_info->target_type == VKD3D_SHADER_TARGET_D3D_BYTECODE && profile->major_version > 3)
if (compile_info->target_type != VKD3D_SHADER_TARGET_FX && profile->type == VKD3D_SHADER_TYPE_EFFECT)
{
vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE,
"The '%s' target profile is only compatible with the 'fx' target type.", profile->name);
return VKD3D_ERROR_INVALID_ARGUMENT;
}
else if (compile_info->target_type == VKD3D_SHADER_TARGET_D3D_BYTECODE && profile->major_version > 3)
{
vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE,
"The '%s' target profile is incompatible with the 'd3dbc' target type.", profile->name);
......@@ -3608,6 +3649,12 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d
"The '%s' target profile is incompatible with the 'dxbc-tpf' target type.", profile->name);
return VKD3D_ERROR_INVALID_ARGUMENT;
}
else if (compile_info->target_type == VKD3D_SHADER_TARGET_FX && profile->type != VKD3D_SHADER_TYPE_EFFECT)
{
vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE,
"The '%s' target profile is incompatible with the 'fx' target type.", profile->name);
return VKD3D_ERROR_INVALID_ARGUMENT;
}
if (!hlsl_ctx_init(&ctx, compile_info, profile, message_context))
return VKD3D_ERROR_OUT_OF_MEMORY;
......@@ -3632,6 +3679,14 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d
return VKD3D_ERROR_NOT_IMPLEMENTED;
}
if (ctx.profile->type == VKD3D_SHADER_TYPE_EFFECT)
{
ret = hlsl_emit_effect_binary(&ctx, out);
hlsl_ctx_cleanup(&ctx);
return ret;
}
if ((func = hlsl_get_function(&ctx, entry_point)))
{
LIST_FOR_EACH_ENTRY(decl, &func->overloads, struct hlsl_ir_function_decl, entry)
......
......@@ -95,6 +95,8 @@ enum hlsl_base_type
HLSL_TYPE_UAV,
HLSL_TYPE_PIXELSHADER,
HLSL_TYPE_VERTEXSHADER,
HLSL_TYPE_TECHNIQUE,
HLSL_TYPE_EFFECT_GROUP,
HLSL_TYPE_STRING,
HLSL_TYPE_VOID,
};
......@@ -138,8 +140,10 @@ struct hlsl_type
struct rb_entry scope_entry;
enum hlsl_type_class class;
/* If type is <= HLSL_CLASS_LAST_NUMERIC, then base_type is <= HLSL_TYPE_LAST_SCALAR.
* If type is HLSL_CLASS_OBJECT, then base_type is > HLSL_TYPE_LAST_SCALAR.
/* If class is <= HLSL_CLASS_LAST_NUMERIC, then base_type is <= HLSL_TYPE_LAST_SCALAR.
* If class is HLSL_CLASS_OBJECT, then base_type is > HLSL_TYPE_LAST_SCALAR.
* If class is HLSL_CLASS_OBJECT and base_type is HLSL_TYPE_TECHNIQUE, additional version
* field is used to distinguish between technique types.
* Otherwise, base_type is not used. */
enum hlsl_base_type base_type;
......@@ -191,6 +195,8 @@ struct hlsl_type
/* Format of the data contained within the type if the base_type is HLSL_TYPE_TEXTURE or
* HLSL_TYPE_UAV. */
struct hlsl_type *resource_format;
/* Additional field to distinguish object types. Currently used only for technique types. */
unsigned int version;
} e;
/* Number of numeric register components used by one value of this type, for each regset.
......@@ -400,6 +406,8 @@ struct hlsl_ir_var
struct list scope_entry;
/* Item entry in hlsl_ctx.extern_vars, if the variable is extern. */
struct list extern_entry;
/* Scope that variable itself defines, used to provide a container for techniques and passes. */
struct hlsl_scope *scope;
/* Indexes of the IR instructions where the variable is first written and last read (liveness
* range). The IR instructions are numerated starting from 2, because 0 means unused, and 1
......@@ -1160,6 +1168,7 @@ void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl
int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func,
enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out);
int hlsl_emit_effect_binary(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out);
bool hlsl_init_deref_from_index_chain(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_node *chain);
bool hlsl_copy_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, const struct hlsl_deref *other);
......
......@@ -89,6 +89,7 @@ else {return KW_ELSE; }
extern {return KW_EXTERN; }
false {return KW_FALSE; }
for {return KW_FOR; }
fxgroup {return KW_FXGROUP; }
GeometryShader {return KW_GEOMETRYSHADER; }
groupshared {return KW_GROUPSHARED; }
if {return KW_IF; }
......
......@@ -1096,6 +1096,55 @@ static bool add_func_parameter(struct hlsl_ctx *ctx, struct hlsl_func_parameters
return true;
}
static bool add_technique(struct hlsl_ctx *ctx, const char *name, const char *typename,
const struct vkd3d_shader_location *loc)
{
struct hlsl_ir_var *var;
struct hlsl_type *type;
type = hlsl_get_type(ctx->globals, typename, false, false);
if (!(var = hlsl_new_var(ctx, name, type, loc, NULL, 0, NULL)))
return false;
if (!hlsl_add_var(ctx, var, false))
{
struct hlsl_ir_var *old = hlsl_get_var(ctx->cur_scope, var->name);
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED,
"Identifier \"%s\" was already declared in this scope.", var->name);
hlsl_note(ctx, &old->loc, VKD3D_SHADER_LOG_ERROR, "\"%s\" was previously declared here.", old->name);
hlsl_free_var(var);
return false;
}
return true;
}
static bool add_effect_group(struct hlsl_ctx *ctx, const char *name, struct hlsl_scope *scope,
const struct vkd3d_shader_location *loc)
{
struct hlsl_ir_var *var;
struct hlsl_type *type;
type = hlsl_get_type(ctx->globals, "fxgroup", false, false);
if (!(var = hlsl_new_var(ctx, name, type, loc, NULL, 0, NULL)))
return false;
var->scope = scope;
if (!hlsl_add_var(ctx, var, false))
{
struct hlsl_ir_var *old = hlsl_get_var(ctx->cur_scope, var->name);
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED,
"Identifier \"%s\" was already declared in this scope.", var->name);
hlsl_note(ctx, &old->loc, VKD3D_SHADER_LOG_ERROR, "\"%s\" was previously declared here.", old->name);
hlsl_free_var(var);
return false;
}
return true;
}
static struct hlsl_reg_reservation parse_reg_reservation(const char *reg_string)
{
struct hlsl_reg_reservation reservation = {0};
......@@ -4888,6 +4937,7 @@ static void check_duplicated_switch_cases(struct hlsl_ctx *ctx, const struct hls
%token KW_EXTERN
%token KW_FALSE
%token KW_FOR
%token KW_FXGROUP
%token KW_GEOMETRYSHADER
%token KW_GROUPSHARED
%token KW_IF
......@@ -5094,7 +5144,8 @@ hlsl_prog:
destroy_block($2);
}
| hlsl_prog preproc_directive
| hlsl_prog technique
| hlsl_prog global_technique
| hlsl_prog effect_group
| hlsl_prog ';'
technique_name:
......@@ -5110,7 +5161,8 @@ pass_list:
technique9:
KW_TECHNIQUE technique_name '{' pass_list '}'
{
hlsl_fixme(ctx, &@$, "Unsupported \'technique\' declaration.");
if (!add_technique(ctx, $2, "technique", &@1))
YYABORT;
}
technique10:
......@@ -5120,7 +5172,8 @@ technique10:
hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX,
"The 'technique10' keyword is invalid for this profile.");
hlsl_fixme(ctx, &@$, "Unsupported \'technique10\' declaration.");
if (!add_technique(ctx, $2, "technique10", &@1))
YYABORT;
}
technique11:
......@@ -5130,14 +5183,32 @@ technique11:
hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX,
"The 'technique11' keyword is invalid for this profile.");
hlsl_fixme(ctx, &@$, "Unsupported \'technique11\' declaration.");
if (!add_technique(ctx, $2, "technique11", &@1))
YYABORT;
}
technique:
global_technique:
technique9
| technique10
| technique11
group_technique:
technique10
| technique11
group_techniques:
group_technique
| group_techniques group_technique
effect_group:
KW_FXGROUP any_identifier '{' scope_start group_techniques '}'
{
struct hlsl_scope *scope = ctx->cur_scope;
hlsl_pop_scope(ctx);
if (!(add_effect_group(ctx, $2, scope, &@2)))
YYABORT;
}
buffer_declaration:
buffer_type any_identifier colon_attribute
{
......
......@@ -492,7 +492,7 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i
if (shader_instruction_is_dcl(ins))
break;
for (j = 0; j < ins->dst_count; ++j)
shader_dst_param_normalise_outpointid((struct vkd3d_shader_dst_param *)&ins->dst[j], &normaliser);
shader_dst_param_normalise_outpointid(&ins->dst[j], &normaliser);
break;
}
}
......@@ -1116,9 +1116,9 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi
if (shader_instruction_is_dcl(ins))
break;
for (i = 0; i < ins->dst_count; ++i)
shader_dst_param_io_normalise((struct vkd3d_shader_dst_param *)&ins->dst[i], false, normaliser);
shader_dst_param_io_normalise(&ins->dst[i], false, normaliser);
for (i = 0; i < ins->src_count; ++i)
shader_src_param_io_normalise((struct vkd3d_shader_src_param *)&ins->src[i], normaliser);
shader_src_param_io_normalise(&ins->src[i], normaliser);
break;
}
}
......@@ -1310,7 +1310,7 @@ static enum vkd3d_result instruction_array_normalise_flat_constants(struct vkd3d
else
{
for (j = 0; j < ins->src_count; ++j)
shader_register_normalise_flat_constants((struct vkd3d_shader_src_param *)&ins->src[j], &normaliser);
shader_register_normalise_flat_constants(&ins->src[j], &normaliser);
}
}
......
......@@ -2198,7 +2198,7 @@ static void vkd3d_symbol_make_io(struct vkd3d_symbol *symbol,
static void vkd3d_symbol_set_register_info(struct vkd3d_symbol *symbol,
uint32_t val_id, SpvStorageClass storage_class,
enum vkd3d_shader_component_type component_type, DWORD write_mask)
enum vkd3d_shader_component_type component_type, uint32_t write_mask)
{
symbol->id = val_id;
symbol->descriptor_array = NULL;
......@@ -3370,7 +3370,7 @@ static uint32_t spirv_compiler_emit_construct_vector(struct spirv_compiler *comp
}
static uint32_t spirv_compiler_emit_load_src(struct spirv_compiler *compiler,
const struct vkd3d_shader_src_param *src, DWORD write_mask);
const struct vkd3d_shader_src_param *src, uint32_t write_mask);
static uint32_t spirv_compiler_emit_register_addressing(struct spirv_compiler *compiler,
const struct vkd3d_shader_register_index *reg_index)
......@@ -3997,7 +3997,7 @@ static void spirv_compiler_emit_execution_mode1(struct spirv_compiler *compiler,
}
static uint32_t spirv_compiler_emit_abs(struct spirv_compiler *compiler,
const struct vkd3d_shader_register *reg, DWORD write_mask, uint32_t val_id)
const struct vkd3d_shader_register *reg, uint32_t write_mask, uint32_t val_id)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
uint32_t type_id;
......@@ -4011,7 +4011,7 @@ static uint32_t spirv_compiler_emit_abs(struct spirv_compiler *compiler,
}
static uint32_t spirv_compiler_emit_neg(struct spirv_compiler *compiler,
const struct vkd3d_shader_register *reg, DWORD write_mask, uint32_t val_id)
const struct vkd3d_shader_register *reg, uint32_t write_mask, uint32_t val_id)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
uint32_t type_id;
......@@ -4027,7 +4027,7 @@ static uint32_t spirv_compiler_emit_neg(struct spirv_compiler *compiler,
}
static uint32_t spirv_compiler_emit_src_modifier(struct spirv_compiler *compiler,
const struct vkd3d_shader_register *reg, DWORD write_mask,
const struct vkd3d_shader_register *reg, uint32_t write_mask,
enum vkd3d_shader_src_modifier modifier, uint32_t val_id)
{
switch (modifier)
......@@ -4050,7 +4050,7 @@ static uint32_t spirv_compiler_emit_src_modifier(struct spirv_compiler *compiler
}
static uint32_t spirv_compiler_emit_load_src(struct spirv_compiler *compiler,
const struct vkd3d_shader_src_param *src, DWORD write_mask)
const struct vkd3d_shader_src_param *src, uint32_t write_mask)
{
uint32_t val_id;
......@@ -4059,7 +4059,7 @@ static uint32_t spirv_compiler_emit_load_src(struct spirv_compiler *compiler,
}
static uint32_t spirv_compiler_emit_load_src_with_type(struct spirv_compiler *compiler,
const struct vkd3d_shader_src_param *src, DWORD write_mask, enum vkd3d_shader_component_type component_type)
const struct vkd3d_shader_src_param *src, uint32_t write_mask, enum vkd3d_shader_component_type component_type)
{
struct vkd3d_shader_src_param src_param = *src;
......@@ -7068,7 +7068,7 @@ static void spirv_compiler_emit_dot(struct spirv_compiler *compiler,
enum vkd3d_shader_component_type component_type;
uint32_t type_id, val_id, src_ids[2];
unsigned int component_count, i;
DWORD write_mask;
uint32_t write_mask;
component_count = vsir_write_mask_component_count(dst->write_mask);
component_type = vkd3d_component_type_from_data_type(dst->reg.data_type);
......@@ -7370,7 +7370,7 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp
const struct vkd3d_shader_src_param *src = instruction->src;
enum vkd3d_shader_component_type component_type;
unsigned int i, j, k, src_count;
DWORD write_mask;
uint32_t write_mask;
SpvOp op;
src_count = instruction->src_count;
......@@ -7427,8 +7427,8 @@ static void spirv_compiler_emit_f16tof32(struct spirv_compiler *compiler,
const struct vkd3d_shader_dst_param *dst = instruction->dst;
const struct vkd3d_shader_src_param *src = instruction->src;
uint32_t components[VKD3D_VEC4_SIZE];
uint32_t write_mask;
unsigned int i, j;
DWORD write_mask;
instr_set_id = vkd3d_spirv_get_glsl_std450_instr_set(builder);
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2);
......@@ -7460,8 +7460,8 @@ static void spirv_compiler_emit_f32tof16(struct spirv_compiler *compiler,
const struct vkd3d_shader_dst_param *dst = instruction->dst;
const struct vkd3d_shader_src_param *src = instruction->src;
uint32_t components[VKD3D_VEC4_SIZE];
uint32_t write_mask;
unsigned int i, j;
DWORD write_mask;
instr_set_id = vkd3d_spirv_get_glsl_std450_instr_set(builder);
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2);
......@@ -8226,7 +8226,7 @@ static void spirv_compiler_emit_ld(struct spirv_compiler *compiler,
unsigned int image_operand_count = 0;
struct vkd3d_shader_image image;
uint32_t image_operands[2];
DWORD coordinate_mask;
uint32_t coordinate_mask;
bool multisample;
multisample = instruction->handler_idx == VKD3DSIH_LD2DMS;
......@@ -8300,7 +8300,7 @@ static void spirv_compiler_emit_sample(struct spirv_compiler *compiler,
unsigned int image_operand_count = 0;
struct vkd3d_shader_image image;
uint32_t image_operands[3];
DWORD coordinate_mask;
uint32_t coordinate_mask;
SpvOp op;
resource = &src[1];
......@@ -8416,7 +8416,7 @@ static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler,
struct vkd3d_shader_image image;
unsigned int component_idx;
uint32_t image_operands[1];
DWORD coordinate_mask;
uint32_t coordinate_mask;
bool extended_offset;
if (instruction->handler_idx == VKD3DSIH_GATHER4_C
......@@ -8476,13 +8476,13 @@ static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler,
static uint32_t spirv_compiler_emit_raw_structured_addressing(
struct spirv_compiler *compiler, uint32_t type_id, unsigned int stride,
const struct vkd3d_shader_src_param *src0, DWORD src0_mask,
const struct vkd3d_shader_src_param *src1, DWORD src1_mask)
const struct vkd3d_shader_src_param *src0, uint32_t src0_mask,
const struct vkd3d_shader_src_param *src1, uint32_t src1_mask)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
const struct vkd3d_shader_src_param *offset;
uint32_t structure_id = 0, offset_id;
DWORD offset_write_mask;
uint32_t offset_write_mask;
if (stride)
{
......@@ -8791,7 +8791,7 @@ static void spirv_compiler_emit_ld_uav_typed(struct spirv_compiler *compiler,
const struct vkd3d_shader_src_param *src = instruction->src;
const struct vkd3d_symbol *resource_symbol;
struct vkd3d_shader_image image;
DWORD coordinate_mask;
uint32_t coordinate_mask;
uint32_t indices[2];
resource_symbol = spirv_compiler_find_resource(compiler, &src[1].reg);
......@@ -8834,7 +8834,7 @@ static void spirv_compiler_emit_store_uav_typed(struct spirv_compiler *compiler,
const struct vkd3d_shader_src_param *src = instruction->src;
const struct vkd3d_symbol *resource_symbol;
struct vkd3d_shader_image image;
DWORD coordinate_mask;
uint32_t coordinate_mask;
uint32_t indices[2];
resource_symbol = spirv_compiler_find_resource(compiler, &dst->reg);
......@@ -9000,7 +9000,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil
struct vkd3d_shader_register_info reg_info;
struct vkd3d_shader_image image;
unsigned int structure_stride;
DWORD coordinate_mask;
uint32_t coordinate_mask;
uint32_t operands[6];
unsigned int i = 0;
SpvScope scope;
......
......@@ -742,8 +742,7 @@ static bool shader_sm4_read_register_space(struct vkd3d_shader_sm4_parser *priv,
static void shader_sm4_read_conditional_op(struct vkd3d_shader_instruction *ins, uint32_t opcode,
uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv)
{
shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_UINT,
(struct vkd3d_shader_src_param *)&ins->src[0]);
shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_UINT, &ins->src[0]);
ins->flags = (opcode_token & VKD3D_SM4_CONDITIONAL_NZ) ?
VKD3D_SHADER_CONDITIONAL_OP_NZ : VKD3D_SHADER_CONDITIONAL_OP_Z;
}
......@@ -751,8 +750,7 @@ static void shader_sm4_read_conditional_op(struct vkd3d_shader_instruction *ins,
static void shader_sm4_read_case_condition(struct vkd3d_shader_instruction *ins, uint32_t opcode,
uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv)
{
shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_UINT,
(struct vkd3d_shader_src_param *)&ins->src[0]);
shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_UINT, &ins->src[0]);
if (ins->src[0].reg.type != VKD3DSPR_IMMCONST)
{
FIXME("Switch case value is not a 32-bit constant.\n");
......@@ -1130,9 +1128,8 @@ static void shader_sm4_read_dcl_global_flags(struct vkd3d_shader_instruction *in
static void shader_sm5_read_fcall(struct vkd3d_shader_instruction *ins, uint32_t opcode, uint32_t opcode_token,
const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv)
{
struct vkd3d_shader_src_param *src_params = (struct vkd3d_shader_src_param *)ins->src;
src_params[0].reg.u.fp_body_idx = *tokens++;
shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_OPAQUE, &src_params[0]);
ins->src[0].reg.u.fp_body_idx = *tokens++;
shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_OPAQUE, &ins->src[0]);
}
static void shader_sm5_read_dcl_function_body(struct vkd3d_shader_instruction *ins, uint32_t opcode,
......
......@@ -383,13 +383,42 @@ size_t bytecode_put_bytes(struct vkd3d_bytecode_buffer *buffer, const void *byte
return offset;
}
void set_u32(struct vkd3d_bytecode_buffer *buffer, size_t offset, uint32_t value)
size_t bytecode_reserve_bytes(struct vkd3d_bytecode_buffer *buffer, size_t size)
{
size_t offset = bytecode_align(buffer);
if (buffer->status)
return offset;
if (!vkd3d_array_reserve((void **)&buffer->data, &buffer->capacity, offset + size, 1))
{
buffer->status = VKD3D_ERROR_OUT_OF_MEMORY;
return offset;
}
memset(buffer->data + offset, 0, size);
buffer->size = offset + size;
return offset;
}
static void bytecode_set_bytes(struct vkd3d_bytecode_buffer *buffer, size_t offset,
const void *value, size_t size)
{
if (buffer->status)
return;
assert(vkd3d_bound_range(offset, sizeof(value), buffer->size));
memcpy(buffer->data + offset, &value, sizeof(value));
assert(vkd3d_bound_range(offset, size, buffer->size));
memcpy(buffer->data + offset, value, size);
}
void set_u32(struct vkd3d_bytecode_buffer *buffer, size_t offset, uint32_t value)
{
bytecode_set_bytes(buffer, offset, &value, sizeof(value));
}
void set_string(struct vkd3d_bytecode_buffer *buffer, size_t offset, const char *string, size_t length)
{
bytecode_set_bytes(buffer, offset, string, length);
}
static void vkd3d_shader_dump_blob(const char *path, const char *profile,
......@@ -1913,6 +1942,7 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types(
{
VKD3D_SHADER_TARGET_D3D_BYTECODE,
VKD3D_SHADER_TARGET_DXBC_TPF,
VKD3D_SHADER_TARGET_FX,
};
static const enum vkd3d_shader_target_type d3dbc_types[] =
......
......@@ -1126,8 +1126,8 @@ struct vkd3d_shader_instruction
uint32_t flags;
unsigned int dst_count;
unsigned int src_count;
const struct vkd3d_shader_dst_param *dst;
const struct vkd3d_shader_src_param *src;
struct vkd3d_shader_dst_param *dst;
struct vkd3d_shader_src_param *src;
struct vkd3d_shader_texel_offset texel_offset;
enum vkd3d_shader_resource_type resource_type;
unsigned int resource_stride;
......@@ -1357,7 +1357,9 @@ struct vkd3d_bytecode_buffer
/* Align to the next 4-byte offset, and return that offset. */
size_t bytecode_align(struct vkd3d_bytecode_buffer *buffer);
size_t bytecode_put_bytes(struct vkd3d_bytecode_buffer *buffer, const void *bytes, size_t size);
size_t bytecode_reserve_bytes(struct vkd3d_bytecode_buffer *buffer, size_t size);
void set_u32(struct vkd3d_bytecode_buffer *buffer, size_t offset, uint32_t value);
void set_string(struct vkd3d_bytecode_buffer *buffer, size_t offset, const char *string, size_t length);
static inline size_t put_u32(struct vkd3d_bytecode_buffer *buffer, uint32_t value)
{
......
......@@ -185,28 +185,12 @@ static void close_include(const struct vkd3d_shader_code *code, void *context)
ID3DInclude_Close(iface, code->code);
}
HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filename,
const D3D_SHADER_MACRO *macros, ID3DInclude *include, const char *entry_point,
const char *profile, UINT flags, UINT effect_flags, UINT secondary_flags,
const void *secondary_data, SIZE_T secondary_data_size, ID3DBlob **shader_blob,
ID3DBlob **messages_blob)
static enum vkd3d_shader_target_type get_target_for_profile(const char *profile)
{
struct vkd3d_shader_preprocess_info preprocess_info;
struct vkd3d_shader_hlsl_source_info hlsl_info;
struct vkd3d_shader_compile_option options[4];
struct vkd3d_shader_compile_info compile_info;
struct vkd3d_shader_compile_option *option;
struct vkd3d_shader_code byte_code;
const D3D_SHADER_MACRO *macro;
size_t profile_len, i;
char *messages;
HRESULT hr;
int ret;
static const char * const d3dbc_profiles[] =
{
"fx_2_",
"ps.1.",
"ps.2.",
"ps.3.",
......@@ -226,6 +210,49 @@ HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filen
"tx_1_",
};
static const char * const fx_profiles[] =
{
"fx_2_0",
"fx_4_0",
"fx_4_1",
"fx_5_0",
};
profile_len = strlen(profile);
for (i = 0; i < ARRAY_SIZE(d3dbc_profiles); ++i)
{
size_t len = strlen(d3dbc_profiles[i]);
if (len <= profile_len && !memcmp(profile, d3dbc_profiles[i], len))
return VKD3D_SHADER_TARGET_D3D_BYTECODE;
}
for (i = 0; i < ARRAY_SIZE(fx_profiles); ++i)
{
if (!strcmp(profile, fx_profiles[i]))
return VKD3D_SHADER_TARGET_FX;
}
return VKD3D_SHADER_TARGET_DXBC_TPF;
}
HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filename,
const D3D_SHADER_MACRO *macros, ID3DInclude *include, const char *entry_point,
const char *profile, UINT flags, UINT effect_flags, UINT secondary_flags,
const void *secondary_data, SIZE_T secondary_data_size, ID3DBlob **shader_blob,
ID3DBlob **messages_blob)
{
struct vkd3d_shader_preprocess_info preprocess_info;
struct vkd3d_shader_hlsl_source_info hlsl_info;
struct vkd3d_shader_compile_option options[4];
struct vkd3d_shader_compile_info compile_info;
struct vkd3d_shader_compile_option *option;
struct vkd3d_shader_code byte_code;
const D3D_SHADER_MACRO *macro;
char *messages;
HRESULT hr;
int ret;
TRACE("data %p, data_size %lu, filename %s, macros %p, include %p, entry_point %s, "
"profile %s, flags %#x, effect_flags %#x, secondary_flags %#x, secondary_data %p, "
"secondary_data_size %lu, shader_blob %p, messages_blob %p.\n",
......@@ -252,24 +279,12 @@ HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filen
compile_info.source.code = data;
compile_info.source.size = data_size;
compile_info.source_type = VKD3D_SHADER_SOURCE_HLSL;
compile_info.target_type = VKD3D_SHADER_TARGET_DXBC_TPF;
compile_info.target_type = get_target_for_profile(profile);
compile_info.options = options;
compile_info.option_count = 1;
compile_info.log_level = VKD3D_SHADER_LOG_INFO;
compile_info.source_name = filename;
profile_len = strlen(profile);
for (i = 0; i < ARRAY_SIZE(d3dbc_profiles); ++i)
{
size_t len = strlen(d3dbc_profiles[i]);
if (len <= profile_len && !memcmp(profile, d3dbc_profiles[i], len))
{
compile_info.target_type = VKD3D_SHADER_TARGET_D3D_BYTECODE;
break;
}
}
preprocess_info.type = VKD3D_SHADER_STRUCTURE_TYPE_PREPROCESS_INFO;
preprocess_info.next = &hlsl_info;
preprocess_info.macros = (const struct vkd3d_shader_macro *)macros;
......@@ -331,6 +346,20 @@ HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filen
if (!ret)
{
/* Unlike other effect profiles fx_4_x is using DXBC container. */
if (!strcmp(profile, "fx_4_0") || !strcmp(profile, "fx_4_1"))
{
struct vkd3d_shader_dxbc_section_desc section = { .tag = TAG_FX10, .data = byte_code };
struct vkd3d_shader_code dxbc;
ret = vkd3d_shader_serialize_dxbc(1, &section, &dxbc, NULL);
vkd3d_shader_free_shader_code(&byte_code);
if (ret)
return hresult_from_vkd3d_result(ret);
byte_code = dxbc;
}
if (FAILED(hr = vkd3d_blob_create((void *)byte_code.code, byte_code.size, shader_blob)))
{
vkd3d_shader_free_shader_code(&byte_code);
......
......@@ -4551,7 +4551,7 @@ HRESULT vkd3d_create_thread(struct vkd3d_instance *instance,
thread_data->data = data;
if (!(thread->handle = CreateThread(NULL, 0, call_thread_main, thread_data, 0, NULL)))
{
ERR("Failed to create thread, error %d.\n", GetLastError());
ERR("Failed to create thread, error %lu.\n", GetLastError());
vkd3d_free(thread_data);
hr = E_FAIL;
}
......
......@@ -249,7 +249,7 @@ static inline void vkd3d_cond_broadcast(struct vkd3d_cond *cond)
static inline void vkd3d_cond_wait(struct vkd3d_cond *cond, struct vkd3d_mutex *lock)
{
if (!SleepConditionVariableCS(&cond->cond, &lock->lock, INFINITE))
ERR("Could not sleep on the condition variable, error %u.\n", GetLastError());
ERR("Could not sleep on the condition variable, error %lu.\n", GetLastError());
}
static inline void vkd3d_cond_destroy(struct vkd3d_cond *cond)
......
......@@ -106,6 +106,9 @@ target_type_info[] =
"dxbc-tpf", "A 'Tokenized Program Format' shader embedded in a DXBC container.\n"
" This is the format used for Direct3D shader model 4 and 5 shaders.\n",
true},
{VKD3D_SHADER_TARGET_FX,
"fx", "Binary format used by Direct3D 9/10.x/11 effects.\n",
true},
{VKD3D_SHADER_TARGET_GLSL,
"glsl", "An 'OpenGL Shading Language' shader.\n",
false}
......