diff --git a/dlls/d3dcompiler_33/Makefile.in b/dlls/d3dcompiler_33/Makefile.in index 2c0460ea0a4..8bf55af498f 100644 --- a/dlls/d3dcompiler_33/Makefile.in +++ b/dlls/d3dcompiler_33/Makefile.in @@ -16,12 +16,10 @@ C_SRCS = \ LEX_SRCS = \ asmshader.l \ - hlsl.l \ ppl.l BISON_SRCS = \ asmshader.y \ - hlsl.y \ ppy.y RC_SRCS = version.rc diff --git a/dlls/d3dcompiler_34/Makefile.in b/dlls/d3dcompiler_34/Makefile.in index b342df17677..99a909eecde 100644 --- a/dlls/d3dcompiler_34/Makefile.in +++ b/dlls/d3dcompiler_34/Makefile.in @@ -16,12 +16,10 @@ C_SRCS = \ LEX_SRCS = \ asmshader.l \ - hlsl.l \ ppl.l BISON_SRCS = \ asmshader.y \ - hlsl.y \ ppy.y RC_SRCS = version.rc diff --git a/dlls/d3dcompiler_35/Makefile.in b/dlls/d3dcompiler_35/Makefile.in index 43e76ea4a5e..da8549b0fc4 100644 --- a/dlls/d3dcompiler_35/Makefile.in +++ b/dlls/d3dcompiler_35/Makefile.in @@ -16,12 +16,10 @@ C_SRCS = \ LEX_SRCS = \ asmshader.l \ - hlsl.l \ ppl.l BISON_SRCS = \ asmshader.y \ - hlsl.y \ ppy.y RC_SRCS = version.rc diff --git a/dlls/d3dcompiler_36/Makefile.in b/dlls/d3dcompiler_36/Makefile.in index a7f1d2fef8b..775fba08a39 100644 --- a/dlls/d3dcompiler_36/Makefile.in +++ b/dlls/d3dcompiler_36/Makefile.in @@ -16,12 +16,10 @@ C_SRCS = \ LEX_SRCS = \ asmshader.l \ - hlsl.l \ ppl.l BISON_SRCS = \ asmshader.y \ - hlsl.y \ ppy.y RC_SRCS = version.rc diff --git a/dlls/d3dcompiler_37/Makefile.in b/dlls/d3dcompiler_37/Makefile.in index 898e1b0e52e..2f48001056f 100644 --- a/dlls/d3dcompiler_37/Makefile.in +++ b/dlls/d3dcompiler_37/Makefile.in @@ -16,12 +16,10 @@ C_SRCS = \ LEX_SRCS = \ asmshader.l \ - hlsl.l \ ppl.l BISON_SRCS = \ asmshader.y \ - hlsl.y \ ppy.y RC_SRCS = version.rc diff --git a/dlls/d3dcompiler_38/Makefile.in b/dlls/d3dcompiler_38/Makefile.in index 7c8f996db74..52c76e0982d 100644 --- a/dlls/d3dcompiler_38/Makefile.in +++ b/dlls/d3dcompiler_38/Makefile.in @@ -16,12 +16,10 @@ C_SRCS = \ LEX_SRCS = \ asmshader.l \ - hlsl.l \ ppl.l BISON_SRCS = \ asmshader.y \ - hlsl.y \ ppy.y RC_SRCS = version.rc diff --git a/dlls/d3dcompiler_39/Makefile.in b/dlls/d3dcompiler_39/Makefile.in index c0672d72a33..5431581a967 100644 --- a/dlls/d3dcompiler_39/Makefile.in +++ b/dlls/d3dcompiler_39/Makefile.in @@ -16,12 +16,10 @@ C_SRCS = \ LEX_SRCS = \ asmshader.l \ - hlsl.l \ ppl.l BISON_SRCS = \ asmshader.y \ - hlsl.y \ ppy.y RC_SRCS = version.rc diff --git a/dlls/d3dcompiler_40/Makefile.in b/dlls/d3dcompiler_40/Makefile.in index bb8e3387066..b912c6d0191 100644 --- a/dlls/d3dcompiler_40/Makefile.in +++ b/dlls/d3dcompiler_40/Makefile.in @@ -16,12 +16,10 @@ C_SRCS = \ LEX_SRCS = \ asmshader.l \ - hlsl.l \ ppl.l BISON_SRCS = \ asmshader.y \ - hlsl.y \ ppy.y RC_SRCS = version.rc diff --git a/dlls/d3dcompiler_41/Makefile.in b/dlls/d3dcompiler_41/Makefile.in index dd72016c0b9..ecb6f8568f1 100644 --- a/dlls/d3dcompiler_41/Makefile.in +++ b/dlls/d3dcompiler_41/Makefile.in @@ -16,12 +16,10 @@ C_SRCS = \ LEX_SRCS = \ asmshader.l \ - hlsl.l \ ppl.l BISON_SRCS = \ asmshader.y \ - hlsl.y \ ppy.y RC_SRCS = version.rc diff --git a/dlls/d3dcompiler_42/Makefile.in b/dlls/d3dcompiler_42/Makefile.in index 938be9afb4f..2eb8173e01d 100644 --- a/dlls/d3dcompiler_42/Makefile.in +++ b/dlls/d3dcompiler_42/Makefile.in @@ -16,12 +16,10 @@ C_SRCS = \ LEX_SRCS = \ asmshader.l \ - hlsl.l \ ppl.l BISON_SRCS = \ asmshader.y \ - hlsl.y \ ppy.y RC_SRCS = version.rc diff --git a/dlls/d3dcompiler_43/Makefile.in b/dlls/d3dcompiler_43/Makefile.in index 58a17aa6ac4..2172217515b 100644 --- a/dlls/d3dcompiler_43/Makefile.in +++ b/dlls/d3dcompiler_43/Makefile.in @@ -14,12 +14,10 @@ C_SRCS = \ LEX_SRCS = \ asmshader.l \ - hlsl.l \ ppl.l BISON_SRCS = \ asmshader.y \ - hlsl.y \ ppy.y RC_SRCS = version.rc diff --git a/dlls/d3dcompiler_43/compiler.c b/dlls/d3dcompiler_43/compiler.c index f60585a36d1..4fae71d4196 100644 --- a/dlls/d3dcompiler_43/compiler.c +++ b/dlls/d3dcompiler_43/compiler.c @@ -654,181 +654,6 @@ HRESULT WINAPI D3DAssemble(const void *data, SIZE_T datasize, const char *filena return hr; } -struct target_info { - const char *name; - enum shader_type type; - DWORD sm_major; - DWORD sm_minor; - DWORD level_major; - DWORD level_minor; - BOOL sw; - BOOL support; -}; - -/* Must be kept sorted for binary search */ -static const struct target_info targets_info[] = { - { "cs_4_0", ST_UNKNOWN, 4, 0, 0, 0, FALSE, FALSE }, - { "cs_4_1", ST_UNKNOWN, 4, 1, 0, 0, FALSE, FALSE }, - { "cs_5_0", ST_UNKNOWN, 5, 0, 0, 0, FALSE, FALSE }, - { "ds_5_0", ST_UNKNOWN, 5, 0, 0, 0, FALSE, FALSE }, - { "fx_2_0", ST_UNKNOWN, 2, 0, 0, 0, FALSE, FALSE }, - { "fx_4_0", ST_UNKNOWN, 4, 0, 0, 0, FALSE, FALSE }, - { "fx_4_1", ST_UNKNOWN, 4, 1, 0, 0, FALSE, FALSE }, - { "fx_5_0", ST_UNKNOWN, 5, 0, 0, 0, FALSE, FALSE }, - { "gs_4_0", ST_UNKNOWN, 4, 0, 0, 0, FALSE, FALSE }, - { "gs_4_1", ST_UNKNOWN, 4, 1, 0, 0, FALSE, FALSE }, - { "gs_5_0", ST_UNKNOWN, 5, 0, 0, 0, FALSE, FALSE }, - { "hs_5_0", ST_UNKNOWN, 5, 0, 0, 0, FALSE, FALSE }, - { "ps.1.0", ST_PIXEL, 1, 0, 0, 0, FALSE, TRUE }, - { "ps.1.1", ST_PIXEL, 1, 1, 0, 0, FALSE, FALSE }, - { "ps.1.2", ST_PIXEL, 1, 2, 0, 0, FALSE, FALSE }, - { "ps.1.3", ST_PIXEL, 1, 3, 0, 0, FALSE, FALSE }, - { "ps.1.4", ST_PIXEL, 1, 4, 0, 0, FALSE, FALSE }, - { "ps.2.0", ST_PIXEL, 2, 0, 0, 0, FALSE, TRUE }, - { "ps.2.a", ST_PIXEL, 2, 1, 0, 0, FALSE, FALSE }, - { "ps.2.b", ST_PIXEL, 2, 2, 0, 0, FALSE, FALSE }, - { "ps.2.sw", ST_PIXEL, 2, 0, 0, 0, TRUE, FALSE }, - { "ps.3.0", ST_PIXEL, 3, 0, 0, 0, FALSE, TRUE }, - { "ps_1_0", ST_PIXEL, 1, 0, 0, 0, FALSE, TRUE }, - { "ps_1_1", ST_PIXEL, 1, 1, 0, 0, FALSE, FALSE }, - { "ps_1_2", ST_PIXEL, 1, 2, 0, 0, FALSE, FALSE }, - { "ps_1_3", ST_PIXEL, 1, 3, 0, 0, FALSE, FALSE }, - { "ps_1_4", ST_PIXEL, 1, 4, 0, 0, FALSE, FALSE }, - { "ps_2_0", ST_PIXEL, 2, 0, 0, 0, FALSE, TRUE }, - { "ps_2_a", ST_PIXEL, 2, 1, 0, 0, FALSE, FALSE }, - { "ps_2_b", ST_PIXEL, 2, 2, 0, 0, FALSE, FALSE }, - { "ps_2_sw", ST_PIXEL, 2, 0, 0, 0, TRUE, FALSE }, - { "ps_3_0", ST_PIXEL, 3, 0, 0, 0, FALSE, TRUE }, - { "ps_3_sw", ST_PIXEL, 3, 0, 0, 0, TRUE, FALSE }, - { "ps_4_0", ST_PIXEL, 4, 0, 0, 0, FALSE, TRUE }, - { "ps_4_0_level_9_0", ST_PIXEL, 4, 0, 9, 0, FALSE, FALSE }, - { "ps_4_0_level_9_1", ST_PIXEL, 4, 0, 9, 1, FALSE, FALSE }, - { "ps_4_0_level_9_3", ST_PIXEL, 4, 0, 9, 3, FALSE, FALSE }, - { "ps_4_1", ST_PIXEL, 4, 1, 0, 0, FALSE, TRUE }, - { "ps_5_0", ST_PIXEL, 5, 0, 0, 0, FALSE, TRUE }, - { "tx_1_0", ST_UNKNOWN, 1, 0, 0, 0, FALSE, FALSE }, - { "vs.1.0", ST_VERTEX, 1, 0, 0, 0, FALSE, TRUE }, - { "vs.1.1", ST_VERTEX, 1, 1, 0, 0, FALSE, TRUE }, - { "vs.2.0", ST_VERTEX, 2, 0, 0, 0, FALSE, TRUE }, - { "vs.2.a", ST_VERTEX, 2, 1, 0, 0, FALSE, FALSE }, - { "vs.2.sw", ST_VERTEX, 2, 0, 0, 0, TRUE, FALSE }, - { "vs.3.0", ST_VERTEX, 3, 0, 0, 0, FALSE, TRUE }, - { "vs.3.sw", ST_VERTEX, 3, 0, 0, 0, TRUE, FALSE }, - { "vs_1_0", ST_VERTEX, 1, 0, 0, 0, FALSE, TRUE }, - { "vs_1_1", ST_VERTEX, 1, 1, 0, 0, FALSE, TRUE }, - { "vs_2_0", ST_VERTEX, 2, 0, 0, 0, FALSE, TRUE }, - { "vs_2_a", ST_VERTEX, 2, 1, 0, 0, FALSE, FALSE }, - { "vs_2_sw", ST_VERTEX, 2, 0, 0, 0, TRUE, FALSE }, - { "vs_3_0", ST_VERTEX, 3, 0, 0, 0, FALSE, TRUE }, - { "vs_3_sw", ST_VERTEX, 3, 0, 0, 0, TRUE, FALSE }, - { "vs_4_0", ST_VERTEX, 4, 0, 0, 0, FALSE, TRUE }, - { "vs_4_0_level_9_0", ST_VERTEX, 4, 0, 9, 0, FALSE, FALSE }, - { "vs_4_0_level_9_1", ST_VERTEX, 4, 0, 9, 1, FALSE, FALSE }, - { "vs_4_0_level_9_3", ST_VERTEX, 4, 0, 9, 3, FALSE, FALSE }, - { "vs_4_1", ST_VERTEX, 4, 1, 0, 0, FALSE, TRUE }, - { "vs_5_0", ST_VERTEX, 5, 0, 0, 0, FALSE, TRUE }, -}; - -static const struct target_info * get_target_info(const char *target) -{ - LONG min = 0; - LONG max = ARRAY_SIZE(targets_info) - 1; - LONG cur; - int res; - - while (min <= max) - { - cur = (min + max) / 2; - res = strcmp(target, targets_info[cur].name); - if (res < 0) - max = cur - 1; - else if (res > 0) - min = cur + 1; - else - return &targets_info[cur]; - } - - return NULL; -} - -static HRESULT compile_shader(const char *preproc_shader, const char *target, const char *entrypoint, - ID3DBlob **shader, ID3DBlob **error_messages) -{ - DWORD size, major, minor; - char *messages = NULL; - HRESULT hr; - ID3DBlob *buffer; - char *pos; - enum shader_type shader_type; - const struct target_info *info; - - TRACE("Preprocessed shader source: %s\n", debugstr_a(preproc_shader)); - - TRACE("Checking compilation target %s\n", debugstr_a(target)); - info = get_target_info(target); - if (!info) - { - FIXME("Unknown compilation target %s\n", debugstr_a(target)); - return D3DERR_INVALIDCALL; - } - else - { - if (!info->support) - { - FIXME("Compilation target %s not yet supported\n", debugstr_a(target)); - return D3DERR_INVALIDCALL; - } - else - { - shader_type = info->type; - major = info->sm_major; - minor = info->sm_minor; - } - } - - hr = parse_hlsl_shader(preproc_shader, shader_type, major, minor, entrypoint, shader, &messages); - - if (messages) - { - TRACE("Compiler messages:\n"); - TRACE("%s\n", debugstr_a(messages)); - - TRACE("Shader source:\n"); - TRACE("%s\n", debugstr_a(preproc_shader)); - - if (error_messages) - { - const char *preproc_messages = *error_messages ? ID3D10Blob_GetBufferPointer(*error_messages) : NULL; - HRESULT blob_hr; - - size = strlen(messages) + (preproc_messages ? strlen(preproc_messages) : 0) + 1; - if (FAILED(blob_hr = D3DCreateBlob(size, &buffer))) - { - HeapFree(GetProcessHeap(), 0, messages); - if (shader && *shader) - { - ID3D10Blob_Release(*shader); - *shader = NULL; - } - return blob_hr; - } - pos = ID3D10Blob_GetBufferPointer(buffer); - if (preproc_messages) - { - memcpy(pos, preproc_messages, strlen(preproc_messages) + 1); - pos += strlen(preproc_messages); - } - memcpy(pos, messages, strlen(messages) + 1); - - if (*error_messages) ID3D10Blob_Release(*error_messages); - *error_messages = buffer; - } - HeapFree(GetProcessHeap(), 0, messages); - } - - return hr; -} - static HRESULT WINAPI d3dcompiler_include_from_file_open(ID3DInclude *iface, D3D_INCLUDE_TYPE include_type, const char *filename, const void *parent_data, const void **data, UINT *bytes) { @@ -936,7 +761,10 @@ HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filen hr = preprocess_shader(data, data_size, filename, defines, include, error_messages); if (SUCCEEDED(hr)) - hr = compile_shader(wpp_output, target, entrypoint, shader, error_messages); + { + FIXME("HLSL shader compilation is not yet implemented.\n"); + hr = E_NOTIMPL; + } HeapFree(GetProcessHeap(), 0, wpp_output); LeaveCriticalSection(&wpp_mutex); diff --git a/dlls/d3dcompiler_43/d3dcompiler_private.h b/dlls/d3dcompiler_43/d3dcompiler_private.h index 8dd56775f3f..49027d11851 100644 --- a/dlls/d3dcompiler_43/d3dcompiler_private.h +++ b/dlls/d3dcompiler_43/d3dcompiler_private.h @@ -158,21 +158,6 @@ static inline BOOL d3dcompiler_free(void *ptr) return HeapFree(GetProcessHeap(), 0, ptr); } -static inline char *d3dcompiler_strdup(const char *string) -{ - char *copy; - SIZE_T len; - - if (!string) - return NULL; - - len = strlen(string); - copy = d3dcompiler_alloc(len + 1); - if (copy) - memcpy(copy, string, len + 1); - return copy; -} - struct asm_parser; /* This structure is only used in asmshader.y, but since the .l file accesses the semantic types @@ -534,598 +519,6 @@ struct bwriter_shader *SlAssembleShader(const char *text, char **messages) DECLS HRESULT shader_write_bytecode(const struct bwriter_shader *shader, DWORD **result, DWORD *size) DECLSPEC_HIDDEN; void SlDeleteShader(struct bwriter_shader *shader) DECLSPEC_HIDDEN; -/* The general IR structure is inspired by Mesa GLSL hir, even though the code - * ends up being quite different in practice. Anyway, here comes the relevant - * licensing information. - * - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -enum hlsl_type_class -{ - HLSL_CLASS_SCALAR, - HLSL_CLASS_VECTOR, - HLSL_CLASS_MATRIX, - HLSL_CLASS_LAST_NUMERIC = HLSL_CLASS_MATRIX, - HLSL_CLASS_STRUCT, - HLSL_CLASS_ARRAY, - HLSL_CLASS_OBJECT, -}; - -enum hlsl_base_type -{ - HLSL_TYPE_FLOAT, - HLSL_TYPE_HALF, - HLSL_TYPE_DOUBLE, - HLSL_TYPE_INT, - HLSL_TYPE_UINT, - HLSL_TYPE_BOOL, - HLSL_TYPE_LAST_SCALAR = HLSL_TYPE_BOOL, - HLSL_TYPE_SAMPLER, - HLSL_TYPE_TEXTURE, - HLSL_TYPE_PIXELSHADER, - HLSL_TYPE_VERTEXSHADER, - HLSL_TYPE_STRING, - HLSL_TYPE_VOID, -}; - -enum hlsl_sampler_dim -{ - HLSL_SAMPLER_DIM_GENERIC, - HLSL_SAMPLER_DIM_1D, - HLSL_SAMPLER_DIM_2D, - HLSL_SAMPLER_DIM_3D, - HLSL_SAMPLER_DIM_CUBE, - HLSL_SAMPLER_DIM_MAX = HLSL_SAMPLER_DIM_CUBE -}; - -enum hlsl_matrix_majority -{ - HLSL_COLUMN_MAJOR, - HLSL_ROW_MAJOR -}; - -struct hlsl_type -{ - struct list entry; - struct wine_rb_entry scope_entry; - enum hlsl_type_class type; - enum hlsl_base_type base_type; - enum hlsl_sampler_dim sampler_dim; - const char *name; - unsigned int modifiers; - unsigned int dimx; - unsigned int dimy; - unsigned int reg_size; - union - { - struct list *elements; - struct - { - struct hlsl_type *type; - unsigned int elements_count; - } array; - } e; -}; - -struct hlsl_struct_field -{ - struct list entry; - struct hlsl_type *type; - const char *name; - const char *semantic; - DWORD modifiers; - unsigned int reg_offset; -}; - -struct source_location -{ - const char *file; - unsigned int line; - unsigned int col; -}; - -enum hlsl_ir_node_type -{ - HLSL_IR_ASSIGNMENT = 0, - HLSL_IR_CONSTANT, - HLSL_IR_EXPR, - HLSL_IR_IF, - HLSL_IR_LOAD, - HLSL_IR_LOOP, - HLSL_IR_JUMP, - HLSL_IR_SWIZZLE, -}; - -struct hlsl_ir_node -{ - struct list entry; - enum hlsl_ir_node_type type; - struct hlsl_type *data_type; - - struct list uses; - - struct source_location loc; - - /* Liveness ranges. "index" is the index of this instruction. Since this is - * essentially an SSA value, the earliest live point is the index. This is - * true even for loops, since currently we can't have a reference to a - * value generated in an earlier iteration of the loop. */ - unsigned int index, last_read; -}; - -struct hlsl_src -{ - struct hlsl_ir_node *node; - struct list entry; -}; - -#define HLSL_STORAGE_EXTERN 0x00000001 -#define HLSL_STORAGE_NOINTERPOLATION 0x00000002 -#define HLSL_MODIFIER_PRECISE 0x00000004 -#define HLSL_STORAGE_SHARED 0x00000008 -#define HLSL_STORAGE_GROUPSHARED 0x00000010 -#define HLSL_STORAGE_STATIC 0x00000020 -#define HLSL_STORAGE_UNIFORM 0x00000040 -#define HLSL_STORAGE_VOLATILE 0x00000080 -#define HLSL_MODIFIER_CONST 0x00000100 -#define HLSL_MODIFIER_ROW_MAJOR 0x00000200 -#define HLSL_MODIFIER_COLUMN_MAJOR 0x00000400 -#define HLSL_STORAGE_IN 0x00000800 -#define HLSL_STORAGE_OUT 0x00001000 - -#define HLSL_TYPE_MODIFIERS_MASK (HLSL_MODIFIER_PRECISE | HLSL_STORAGE_VOLATILE | \ - HLSL_MODIFIER_CONST | HLSL_MODIFIER_ROW_MAJOR | \ - HLSL_MODIFIER_COLUMN_MAJOR) - -#define HLSL_MODIFIERS_MAJORITY_MASK (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR) - -struct reg_reservation -{ - enum bwritershader_param_register_type type; - DWORD regnum; -}; - -struct hlsl_ir_var -{ - struct hlsl_type *data_type; - struct source_location loc; - const char *name; - const char *semantic; - unsigned int modifiers; - const struct reg_reservation *reg_reservation; - struct list scope_entry, param_entry; - - unsigned int first_write, last_read; -}; - -struct hlsl_ir_function -{ - struct wine_rb_entry entry; - const char *name; - struct wine_rb_tree overloads; - BOOL intrinsic; -}; - -struct hlsl_ir_function_decl -{ - struct hlsl_type *return_type; - struct hlsl_ir_var *return_var; - struct source_location loc; - struct wine_rb_entry entry; - struct hlsl_ir_function *func; - const char *semantic; - struct list *parameters; - struct list *body; -}; - -struct hlsl_ir_if -{ - struct hlsl_ir_node node; - struct hlsl_src condition; - struct list then_instrs; - struct list else_instrs; -}; - -struct hlsl_ir_loop -{ - struct hlsl_ir_node node; - /* loop condition is stored in the body (as "if (!condition) break;") */ - struct list body; - unsigned int next_index; /* liveness index of the end of the loop */ -}; - -enum hlsl_ir_expr_op { - HLSL_IR_UNOP_BIT_NOT = 0, - HLSL_IR_UNOP_LOGIC_NOT, - HLSL_IR_UNOP_NEG, - HLSL_IR_UNOP_ABS, - HLSL_IR_UNOP_SIGN, - HLSL_IR_UNOP_RCP, - HLSL_IR_UNOP_RSQ, - HLSL_IR_UNOP_SQRT, - HLSL_IR_UNOP_NRM, - HLSL_IR_UNOP_EXP2, - HLSL_IR_UNOP_LOG2, - - HLSL_IR_UNOP_CAST, - - HLSL_IR_UNOP_FRACT, - - HLSL_IR_UNOP_SIN, - HLSL_IR_UNOP_COS, - HLSL_IR_UNOP_SIN_REDUCED, /* Reduced range [-pi, pi] */ - HLSL_IR_UNOP_COS_REDUCED, /* Reduced range [-pi, pi] */ - - HLSL_IR_UNOP_DSX, - HLSL_IR_UNOP_DSY, - - HLSL_IR_UNOP_SAT, - - HLSL_IR_UNOP_PREINC, - HLSL_IR_UNOP_PREDEC, - HLSL_IR_UNOP_POSTINC, - HLSL_IR_UNOP_POSTDEC, - - HLSL_IR_BINOP_ADD, - HLSL_IR_BINOP_SUB, - HLSL_IR_BINOP_MUL, - HLSL_IR_BINOP_DIV, - - HLSL_IR_BINOP_MOD, - - HLSL_IR_BINOP_LESS, - HLSL_IR_BINOP_GREATER, - HLSL_IR_BINOP_LEQUAL, - HLSL_IR_BINOP_GEQUAL, - HLSL_IR_BINOP_EQUAL, - HLSL_IR_BINOP_NEQUAL, - - HLSL_IR_BINOP_LOGIC_AND, - HLSL_IR_BINOP_LOGIC_OR, - - HLSL_IR_BINOP_LSHIFT, - HLSL_IR_BINOP_RSHIFT, - HLSL_IR_BINOP_BIT_AND, - HLSL_IR_BINOP_BIT_OR, - HLSL_IR_BINOP_BIT_XOR, - - HLSL_IR_BINOP_DOT, - HLSL_IR_BINOP_CRS, - HLSL_IR_BINOP_MIN, - HLSL_IR_BINOP_MAX, - - HLSL_IR_BINOP_POW, - - HLSL_IR_TEROP_LERP, - - HLSL_IR_SEQUENCE, -}; - -struct hlsl_ir_expr -{ - struct hlsl_ir_node node; - enum hlsl_ir_expr_op op; - struct hlsl_src operands[3]; -}; - -enum hlsl_ir_jump_type -{ - HLSL_IR_JUMP_BREAK, - HLSL_IR_JUMP_CONTINUE, - HLSL_IR_JUMP_DISCARD, - HLSL_IR_JUMP_RETURN, -}; - -struct hlsl_ir_jump -{ - struct hlsl_ir_node node; - enum hlsl_ir_jump_type type; -}; - -struct hlsl_ir_swizzle -{ - struct hlsl_ir_node node; - struct hlsl_src val; - DWORD swizzle; -}; - -struct hlsl_deref -{ - struct hlsl_ir_var *var; - struct hlsl_src offset; -}; - -struct hlsl_ir_load -{ - struct hlsl_ir_node node; - struct hlsl_deref src; -}; - -struct hlsl_ir_assignment -{ - struct hlsl_ir_node node; - struct hlsl_deref lhs; - struct hlsl_src rhs; - unsigned char writemask; -}; - -struct hlsl_ir_constant -{ - struct hlsl_ir_node node; - union - { - unsigned u[4]; - int i[4]; - float f[4]; - double d[4]; - BOOL b[4]; - } value; -}; - -struct hlsl_scope -{ - struct list entry; - struct list vars; - struct wine_rb_tree types; - struct hlsl_scope *upper; -}; - -/* Structures used only during parsing */ -struct parse_parameter -{ - struct hlsl_type *type; - const char *name; - const char *semantic; - const struct reg_reservation *reg_reservation; - unsigned int modifiers; -}; - -struct parse_colon_attribute -{ - const char *semantic; - struct reg_reservation *reg_reservation; -}; - -struct parse_initializer -{ - struct hlsl_ir_node **args; - unsigned int args_count; - struct list *instrs; -}; - -struct parse_variable_def -{ - struct list entry; - struct source_location loc; - - char *name; - unsigned int array_size; - const char *semantic; - struct reg_reservation *reg_reservation; - struct parse_initializer initializer; -}; - -struct parse_function -{ - char *name; - struct hlsl_ir_function_decl *decl; -}; - -struct parse_if_body -{ - struct list *then_instrs; - struct list *else_instrs; -}; - -enum parse_unary_op -{ - UNARY_OP_PLUS, - UNARY_OP_MINUS, - UNARY_OP_LOGICNOT, - UNARY_OP_BITNOT, -}; - -enum parse_assign_op -{ - ASSIGN_OP_ASSIGN, - ASSIGN_OP_ADD, - ASSIGN_OP_SUB, - ASSIGN_OP_MUL, - ASSIGN_OP_DIV, - ASSIGN_OP_MOD, - ASSIGN_OP_LSHIFT, - ASSIGN_OP_RSHIFT, - ASSIGN_OP_AND, - ASSIGN_OP_OR, - ASSIGN_OP_XOR, -}; - -struct hlsl_parse_ctx -{ - const char **source_files; - unsigned int source_files_count; - const char *source_file; - unsigned int line_no; - unsigned int column; - enum parse_status status; - struct compilation_messages messages; - - struct hlsl_scope *cur_scope; - struct hlsl_scope *globals; - struct list scopes; - - struct list types; - struct wine_rb_tree functions; - const struct hlsl_ir_function_decl *cur_function; - - enum hlsl_matrix_majority matrix_majority; - - struct - { - struct hlsl_type *scalar[HLSL_TYPE_LAST_SCALAR + 1]; - struct hlsl_type *vector[HLSL_TYPE_LAST_SCALAR + 1][4]; - struct hlsl_type *sampler[HLSL_SAMPLER_DIM_MAX + 1]; - struct hlsl_type *Void; - } builtin_types; - - struct list static_initializers; -}; - -extern struct hlsl_parse_ctx hlsl_ctx DECLSPEC_HIDDEN; - -enum hlsl_error_level -{ - HLSL_LEVEL_ERROR = 0, - HLSL_LEVEL_WARNING, - HLSL_LEVEL_NOTE, -}; - -void WINAPIV hlsl_message(const char *fmt, ...) PRINTF_ATTR(1,2) DECLSPEC_HIDDEN; -void WINAPIV hlsl_report_message(const struct source_location loc, - enum hlsl_error_level level, const char *fmt, ...) PRINTF_ATTR(3,4) DECLSPEC_HIDDEN; - -static inline struct hlsl_ir_expr *expr_from_node(const struct hlsl_ir_node *node) -{ - assert(node->type == HLSL_IR_EXPR); - return CONTAINING_RECORD(node, struct hlsl_ir_expr, node); -} - -static inline struct hlsl_ir_load *load_from_node(const struct hlsl_ir_node *node) -{ - assert(node->type == HLSL_IR_LOAD); - return CONTAINING_RECORD(node, struct hlsl_ir_load, node); -} - -static inline struct hlsl_ir_constant *constant_from_node(const struct hlsl_ir_node *node) -{ - assert(node->type == HLSL_IR_CONSTANT); - return CONTAINING_RECORD(node, struct hlsl_ir_constant, node); -} - -static inline struct hlsl_ir_jump *jump_from_node(const struct hlsl_ir_node *node) -{ - assert(node->type == HLSL_IR_JUMP); - return CONTAINING_RECORD(node, struct hlsl_ir_jump, node); -} - -static inline struct hlsl_ir_assignment *assignment_from_node(const struct hlsl_ir_node *node) -{ - assert(node->type == HLSL_IR_ASSIGNMENT); - return CONTAINING_RECORD(node, struct hlsl_ir_assignment, node); -} - -static inline struct hlsl_ir_swizzle *swizzle_from_node(const struct hlsl_ir_node *node) -{ - assert(node->type == HLSL_IR_SWIZZLE); - return CONTAINING_RECORD(node, struct hlsl_ir_swizzle, node); -} - -static inline struct hlsl_ir_if *if_from_node(const struct hlsl_ir_node *node) -{ - assert(node->type == HLSL_IR_IF); - return CONTAINING_RECORD(node, struct hlsl_ir_if, node); -} - -static inline struct hlsl_ir_loop *loop_from_node(const struct hlsl_ir_node *node) -{ - assert(node->type == HLSL_IR_LOOP); - return CONTAINING_RECORD(node, struct hlsl_ir_loop, node); -} - -static inline struct hlsl_ir_node *node_from_list(struct list *list) -{ - return LIST_ENTRY(list_tail(list), struct hlsl_ir_node, entry); -} - -static inline void init_node(struct hlsl_ir_node *node, enum hlsl_ir_node_type type, - struct hlsl_type *data_type, struct source_location loc) -{ - node->type = type; - node->data_type = data_type; - node->loc = loc; - list_init(&node->uses); -} - -static inline void hlsl_src_from_node(struct hlsl_src *src, struct hlsl_ir_node *node) -{ - src->node = node; - if (node) - list_add_tail(&node->uses, &src->entry); -} - -static inline void hlsl_src_remove(struct hlsl_src *src) -{ - if (src->node) - list_remove(&src->entry); - src->node = NULL; -} - -struct hlsl_ir_node *add_assignment(struct list *instrs, struct hlsl_ir_node *lhs, - enum parse_assign_op assign_op, struct hlsl_ir_node *rhs) DECLSPEC_HIDDEN; -struct hlsl_ir_expr *add_expr(struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *operands[3], - struct source_location *loc) DECLSPEC_HIDDEN; -struct hlsl_ir_node *add_implicit_conversion(struct list *instrs, struct hlsl_ir_node *node, struct hlsl_type *type, - struct source_location *loc) DECLSPEC_HIDDEN; - -struct hlsl_ir_expr *new_cast(struct hlsl_ir_node *node, struct hlsl_type *type, - struct source_location *loc) DECLSPEC_HIDDEN; -struct hlsl_ir_node *new_binary_expr(enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, - struct hlsl_ir_node *arg2) DECLSPEC_HIDDEN; -struct hlsl_ir_node *new_unary_expr(enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, - struct source_location loc) DECLSPEC_HIDDEN; - -BOOL add_declaration(struct hlsl_scope *scope, struct hlsl_ir_var *decl, BOOL local_var) DECLSPEC_HIDDEN; -struct hlsl_ir_var *get_variable(struct hlsl_scope *scope, const char *name) DECLSPEC_HIDDEN; -void free_declaration(struct hlsl_ir_var *decl) DECLSPEC_HIDDEN; -struct hlsl_type *new_hlsl_type(const char *name, enum hlsl_type_class type_class, - enum hlsl_base_type base_type, unsigned dimx, unsigned dimy) DECLSPEC_HIDDEN; -struct hlsl_type *new_array_type(struct hlsl_type *basic_type, unsigned int array_size) DECLSPEC_HIDDEN; -struct hlsl_type *clone_hlsl_type(struct hlsl_type *old, unsigned int default_majority) DECLSPEC_HIDDEN; -struct hlsl_type *get_type(struct hlsl_scope *scope, const char *name, BOOL recursive) DECLSPEC_HIDDEN; -BOOL is_row_major(const struct hlsl_type *type) DECLSPEC_HIDDEN; -BOOL find_function(const char *name) DECLSPEC_HIDDEN; -unsigned int components_count_type(struct hlsl_type *type) DECLSPEC_HIDDEN; -BOOL compare_hlsl_types(const struct hlsl_type *t1, const struct hlsl_type *t2) DECLSPEC_HIDDEN; -BOOL compatible_data_types(struct hlsl_type *s1, struct hlsl_type *s2) DECLSPEC_HIDDEN; -void push_scope(struct hlsl_parse_ctx *ctx) DECLSPEC_HIDDEN; -BOOL pop_scope(struct hlsl_parse_ctx *ctx) DECLSPEC_HIDDEN; -void init_functions_tree(struct wine_rb_tree *funcs) DECLSPEC_HIDDEN; -void add_function_decl(struct wine_rb_tree *funcs, char *name, struct hlsl_ir_function_decl *decl, - BOOL intrinsic) DECLSPEC_HIDDEN; -HRESULT parse_hlsl_shader(const char *text, enum shader_type type, DWORD major, DWORD minor, - const char *entrypoint, ID3D10Blob **shader, char **messages) DECLSPEC_HIDDEN; - -const char *debug_base_type(const struct hlsl_type *type) DECLSPEC_HIDDEN; -const char *debug_hlsl_type(const struct hlsl_type *type) DECLSPEC_HIDDEN; -const char *debug_modifiers(DWORD modifiers) DECLSPEC_HIDDEN; -const char *debug_node_type(enum hlsl_ir_node_type type) DECLSPEC_HIDDEN; -void debug_dump_ir_function_decl(const struct hlsl_ir_function_decl *func) DECLSPEC_HIDDEN; - -void free_hlsl_type(struct hlsl_type *type) DECLSPEC_HIDDEN; -void free_instr(struct hlsl_ir_node *node) DECLSPEC_HIDDEN; -void free_instr_list(struct list *list) DECLSPEC_HIDDEN; -void free_function_rb(struct wine_rb_entry *entry, void *context) DECLSPEC_HIDDEN; - #define MAKE_TAG(ch0, ch1, ch2, ch3) \ ((DWORD)(ch0) | ((DWORD)(ch1) << 8) | \ ((DWORD)(ch2) << 16) | ((DWORD)(ch3) << 24 )) diff --git a/dlls/d3dcompiler_43/hlsl.l b/dlls/d3dcompiler_43/hlsl.l deleted file mode 100644 index 6ffd1375970..00000000000 --- a/dlls/d3dcompiler_43/hlsl.l +++ /dev/null @@ -1,292 +0,0 @@ -/* - * HLSL parser - * - * Copyright 2008 Stefan Dösinger - * Copyright 2012 Matteo Bruni 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 "wine/debug.h" - -#define YY_NO_UNISTD_H -#include "d3dcompiler_private.h" -#include "hlsl.tab.h" - -WINE_DEFAULT_DEBUG_CHANNEL(hlsl_parser); - -#define YY_USER_ACTION \ - do { \ - hlsl_lloc.first_column = hlsl_ctx.column; \ - hlsl_lloc.first_line = hlsl_ctx.line_no; \ - hlsl_ctx.column += yyleng; \ - } while(0); - -%} - -%option noyywrap nounput noinput never-interactive -%option prefix="hlsl_" - -%x pp pp_line pp_pragma pp_ignore - -RESERVED1 auto|case|catch|char|class|const_cast|default|delete|dynamic_cast|enum -RESERVED2 explicit|friend|goto|long|mutable|new|operator|private|protected|public -RESERVED3 reinterpret_cast|short|signed|sizeof|static_cast|template|this|throw|try -RESERVED4 typename|union|unsigned|using|virtual - -WS [ \t] -NEWLINE (\n)|(\r\n) -DOUBLESLASHCOMMENT "//"[^\n]* -STRING \"[^\"]*\" -IDENTIFIER [A-Za-z_][A-Za-z0-9_]* - -ANY (.) - -%% -{RESERVED1} { - hlsl_message("Line %u: Reserved keyword \"%s\" used.\n", hlsl_ctx.line_no, yytext); - set_parse_status(&hlsl_ctx.status, PARSE_ERR); - } -{RESERVED2} { - hlsl_message("Line %u: Reserved keyword \"%s\" used.\n", hlsl_ctx.line_no, yytext); - set_parse_status(&hlsl_ctx.status, PARSE_ERR); - } -{RESERVED3} { - hlsl_message("Line %u: Reserved keyword \"%s\" used.\n", hlsl_ctx.line_no, yytext); - set_parse_status(&hlsl_ctx.status, PARSE_ERR); - } -{RESERVED4} { - hlsl_message("Line %u: Reserved keyword \"%s\" used.\n", hlsl_ctx.line_no, yytext); - set_parse_status(&hlsl_ctx.status, PARSE_ERR); - } - -BlendState {return KW_BLENDSTATE; } -break {return KW_BREAK; } -Buffer {return KW_BUFFER; } -cbuffer {return KW_CBUFFER; } -compile {return KW_COMPILE; } -const {return KW_CONST; } -continue {return KW_CONTINUE; } -DepthStencilState {return KW_DEPTHSTENCILSTATE; } -DepthStencilView {return KW_DEPTHSTENCILVIEW; } -discard {return KW_DISCARD; } -do {return KW_DO; } -double {return KW_DOUBLE; } -else {return KW_ELSE; } -extern {return KW_EXTERN; } -false {return KW_FALSE; } -for {return KW_FOR; } -GeometryShader {return KW_GEOMETRYSHADER; } -groupshared {return KW_GROUPSHARED; } -if {return KW_IF; } -in {return KW_IN; } -inline {return KW_INLINE; } -inout {return KW_INOUT; } -matrix {return KW_MATRIX; } -namespace {return KW_NAMESPACE; } -nointerpolation {return KW_NOINTERPOLATION; } -out {return KW_OUT; } -pass {return KW_PASS; } -PixelShader {return KW_PIXELSHADER; } -precise {return KW_PRECISE; } -RasterizerState {return KW_RASTERIZERSTATE; } -RenderTargetView {return KW_RENDERTARGETVIEW; } -return {return KW_RETURN; } -register {return KW_REGISTER; } -sampler {return KW_SAMPLER; } -sampler1D {return KW_SAMPLER1D; } -sampler2D {return KW_SAMPLER2D; } -sampler3D {return KW_SAMPLER3D; } -samplerCUBE {return KW_SAMPLERCUBE; } -sampler_state {return KW_SAMPLER_STATE; } -SamplerComparisonState {return KW_SAMPLERCOMPARISONSTATE;} -shared {return KW_SHARED; } -stateblock {return KW_STATEBLOCK; } -stateblock_state {return KW_STATEBLOCK_STATE; } -static {return KW_STATIC; } -string {return KW_STRING; } -struct {return KW_STRUCT; } -switch {return KW_SWITCH; } -tbuffer {return KW_TBUFFER; } -technique {return KW_TECHNIQUE; } -technique10 {return KW_TECHNIQUE10; } -texture {return KW_TEXTURE; } -texture1D {return KW_TEXTURE1D; } -Texture1DArray {return KW_TEXTURE1DARRAY; } -texture2D {return KW_TEXTURE2D; } -Texture2DArray {return KW_TEXTURE2DARRAY; } -Texture2DMS {return KW_TEXTURE2DMS; } -Texture2DMSArray {return KW_TEXTURE2DMSARRAY; } -texture3D {return KW_TEXTURE3D; } -Texture3DArray {return KW_TEXTURE3DARRAY; } -textureCUBE {return KW_TEXTURECUBE; } -true {return KW_TRUE; } -typedef {return KW_TYPEDEF; } -uniform {return KW_UNIFORM; } -vector {return KW_VECTOR; } -VertexShader {return KW_VERTEXSHADER; } -void {return KW_VOID; } -volatile {return KW_VOLATILE; } -while {return KW_WHILE; } - -\+\+ {return OP_INC; } -\-\- {return OP_DEC; } -&& {return OP_AND; } -\|\| {return OP_OR; } -== {return OP_EQ; } -\<\< {return OP_LEFTSHIFT; } -\<\<= {return OP_LEFTSHIFTASSIGN; } -\>\> {return OP_RIGHTSHIFT; } -\>\>= {return OP_RIGHTSHIFTASSIGN; } -\.\.\. {return OP_ELLIPSIS; } -\<= {return OP_LE; } -\>= {return OP_GE; } -!= {return OP_NE; } -\+= {return OP_ADDASSIGN; } -\-= {return OP_SUBASSIGN; } -\*= {return OP_MULASSIGN; } -\/= {return OP_DIVASSIGN; } -%= {return OP_MODASSIGN; } -&= {return OP_ANDASSIGN; } -\|= {return OP_ORASSIGN; } -^= {return OP_XORASSIGN; } -## {return OP_UNKNOWN1; } -#@ {return OP_UNKNOWN2; } -:: {return OP_UNKNOWN3; } -\-\> {return OP_UNKNOWN4; } - -column_major {return KW_COLUMN_MAJOR; } -row_major {return KW_ROW_MAJOR; } - -{IDENTIFIER} { - hlsl_lval.name = d3dcompiler_strdup(yytext); - if (get_variable(hlsl_ctx.cur_scope, yytext) - || find_function(yytext)) - return VAR_IDENTIFIER; - else if (get_type(hlsl_ctx.cur_scope, yytext, TRUE)) - return TYPE_IDENTIFIER; - else - return NEW_IDENTIFIER; - } - -[0-9]*\.[0-9]+([eE][+-]?[0-9]+)?[h|H|f|F]? { - hlsl_lval.floatval = atof(yytext); - return C_FLOAT; - } -[0-9]+\.([eE][+-]?[0-9]+)?[h|H|f|F]? { - hlsl_lval.floatval = atof(yytext); - return C_FLOAT; - } -[0-9]+([eE][+-]?[0-9]+)?[h|H|f|F] { - hlsl_lval.floatval = atof(yytext); - return C_FLOAT; - } -0x[0-9a-fA-F]+ { - sscanf(yytext, "0x%x", &hlsl_lval.intval); - return C_INTEGER; - } -0[0-7]+ { - sscanf(yytext, "0%o", &hlsl_lval.intval); - return C_INTEGER; - } -[0-9]+ { - hlsl_lval.intval = (atoi(yytext)); - return C_INTEGER; - } - -{DOUBLESLASHCOMMENT} {} - -{WS}+ {} -{NEWLINE} { - hlsl_ctx.line_no++; - hlsl_ctx.column = 1; - } - -^# { - BEGIN pp; - } - -pragma{WS}+ { - TRACE("Got a #pragma.\n"); - BEGIN pp_pragma; - } -pack_matrix{WS}*\({WS}*row_major{WS}*\) { - TRACE("#pragma setting row_major mode.\n"); - hlsl_ctx.matrix_majority = HLSL_ROW_MAJOR; - BEGIN pp_ignore; - } -pack_matrix{WS}*\({WS}*column_major{WS}*\) { - TRACE("#pragma setting column_major mode.\n"); - hlsl_ctx.matrix_majority = HLSL_COLUMN_MAJOR; - BEGIN pp_ignore; - } -{NEWLINE} { - FIXME("Unsupported preprocessor #pragma directive at line %u.\n", hlsl_ctx.line_no); - BEGIN INITIAL; - } -{ANY} {} -[0-9]+ { - TRACE("Preprocessor line info.\n"); - BEGIN pp_line; - hlsl_lval.intval = (atoi(yytext)); - return PRE_LINE; - } -{STRING} { - char *string = d3dcompiler_strdup(yytext + 1); - - BEGIN pp_ignore; - string[strlen(string) - 1] = 0; - hlsl_lval.name = string; - return STRING; - } -{WS}+ {} -{NEWLINE} { - FIXME("Malformed preprocessor line directive?\n"); - BEGIN INITIAL; - } -{NEWLINE} { - BEGIN INITIAL; - } -{ANY} {} -{NEWLINE} { - FIXME("Unexpected preprocessor directive.\n"); - BEGIN INITIAL; - } -{ANY} {} - -{ANY} { - return yytext[0]; - } - -%% - -HRESULT parse_hlsl(enum shader_type type, DWORD major, DWORD minor, - const char *entrypoint, ID3D10Blob **shader, char **messages); - -HRESULT parse_hlsl_shader(const char *text, enum shader_type type, DWORD major, DWORD minor, - const char *entrypoint, ID3D10Blob **shader, char **messages) -{ - YY_BUFFER_STATE buffer; - HRESULT hr; - - buffer = hlsl__scan_string(text); - hlsl__switch_to_buffer(buffer); - - hr = parse_hlsl(type, major, minor, entrypoint, shader, messages); - - hlsl__delete_buffer(buffer); - return hr; -} diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y deleted file mode 100644 index b0270b6ba2c..00000000000 --- a/dlls/d3dcompiler_43/hlsl.y +++ /dev/null @@ -1,3059 +0,0 @@ -/* - * HLSL parser - * - * Copyright 2008 Stefan Dösinger - * Copyright 2012 Matteo Bruni 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 "wine/debug.h" - -#include -#include - -#include "d3dcompiler_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(hlsl_parser); - -int hlsl_lex(void); - -struct hlsl_parse_ctx hlsl_ctx; - -struct YYLTYPE; -static struct source_location get_location(const struct YYLTYPE *l); - -void WINAPIV hlsl_message(const char *fmt, ...) -{ - __ms_va_list args; - - __ms_va_start(args, fmt); - compilation_message(&hlsl_ctx.messages, fmt, args); - __ms_va_end(args); -} - -static const char *hlsl_get_error_level_name(enum hlsl_error_level level) -{ - static const char * const names[] = - { - "error", - "warning", - "note", - }; - return names[level]; -} - -void WINAPIV hlsl_report_message(const struct source_location loc, - enum hlsl_error_level level, const char *fmt, ...) -{ - __ms_va_list args; - char *string = NULL; - int rc, size = 0; - - while (1) - { - __ms_va_start(args, fmt); - rc = vsnprintf(string, size, fmt, args); - __ms_va_end(args); - - if (rc >= 0 && rc < size) - break; - - if (rc >= size) - size = rc + 1; - else - size = size ? size * 2 : 32; - - if (!string) - string = d3dcompiler_alloc(size); - else - string = d3dcompiler_realloc(string, size); - if (!string) - { - ERR("Error reallocating memory for a string.\n"); - return; - } - } - - hlsl_message("%s:%u:%u: %s: %s\n", loc.file, loc.line, loc.col, - hlsl_get_error_level_name(level), string); - d3dcompiler_free(string); - - if (level == HLSL_LEVEL_ERROR) - set_parse_status(&hlsl_ctx.status, PARSE_ERR); - else if (level == HLSL_LEVEL_WARNING) - set_parse_status(&hlsl_ctx.status, PARSE_WARN); -} - -static void hlsl_error(const char *s) -{ - const struct source_location loc = - { - .file = hlsl_ctx.source_file, - .line = hlsl_ctx.line_no, - .col = hlsl_ctx.column, - }; - hlsl_report_message(loc, HLSL_LEVEL_ERROR, "%s", s); -} - -static void debug_dump_decl(struct hlsl_type *type, DWORD modifiers, const char *declname, unsigned int line_no) -{ - TRACE("Line %u: ", line_no); - if (modifiers) - TRACE("%s ", debug_modifiers(modifiers)); - TRACE("%s %s;\n", debug_hlsl_type(type), declname); -} - -static void check_invalid_matrix_modifiers(DWORD modifiers, struct source_location loc) -{ - if (modifiers & HLSL_MODIFIERS_MAJORITY_MASK) - { - hlsl_report_message(loc, HLSL_LEVEL_ERROR, - "'row_major' or 'column_major' modifiers are only allowed for matrices"); - } -} - -static BOOL type_is_single_reg(const struct hlsl_type *type) -{ - return type->type == HLSL_CLASS_SCALAR || type->type == HLSL_CLASS_VECTOR; -} - -static BOOL declare_variable(struct hlsl_ir_var *decl, BOOL local) -{ - BOOL ret; - - TRACE("Declaring variable %s.\n", decl->name); - if (decl->data_type->type != HLSL_CLASS_MATRIX) - check_invalid_matrix_modifiers(decl->modifiers, decl->loc); - - if (local) - { - DWORD invalid = decl->modifiers & (HLSL_STORAGE_EXTERN | HLSL_STORAGE_SHARED - | HLSL_STORAGE_GROUPSHARED | HLSL_STORAGE_UNIFORM); - if (invalid) - { - hlsl_report_message(decl->loc, HLSL_LEVEL_ERROR, - "modifier '%s' invalid for local variables", debug_modifiers(invalid)); - } - if (decl->semantic) - { - hlsl_report_message(decl->loc, HLSL_LEVEL_ERROR, - "semantics are not allowed on local variables"); - return FALSE; - } - } - else - { - if (find_function(decl->name)) - { - hlsl_report_message(decl->loc, HLSL_LEVEL_ERROR, "redefinition of '%s'", decl->name); - return FALSE; - } - } - ret = add_declaration(hlsl_ctx.cur_scope, decl, local); - if (!ret) - { - struct hlsl_ir_var *old = get_variable(hlsl_ctx.cur_scope, decl->name); - - hlsl_report_message(decl->loc, HLSL_LEVEL_ERROR, "\"%s\" already declared", decl->name); - hlsl_report_message(old->loc, HLSL_LEVEL_NOTE, "\"%s\" was previously declared here", old->name); - return FALSE; - } - return TRUE; -} - -static DWORD add_modifiers(DWORD modifiers, DWORD mod, const struct source_location loc) -{ - if (modifiers & mod) - { - hlsl_report_message(loc, HLSL_LEVEL_ERROR, "modifier '%s' already specified", debug_modifiers(mod)); - return modifiers; - } - if ((mod & HLSL_MODIFIERS_MAJORITY_MASK) && (modifiers & HLSL_MODIFIERS_MAJORITY_MASK)) - { - hlsl_report_message(loc, HLSL_LEVEL_ERROR, "more than one matrix majority keyword"); - return modifiers; - } - return modifiers | mod; -} - -static BOOL add_type_to_scope(struct hlsl_scope *scope, struct hlsl_type *def) -{ - if (get_type(scope, def->name, FALSE)) - return FALSE; - - wine_rb_put(&scope->types, def->name, &def->scope_entry); - return TRUE; -} - -static void declare_predefined_types(struct hlsl_scope *scope) -{ - struct hlsl_type *type; - unsigned int x, y, bt; - static const char * const names[] = - { - "float", - "half", - "double", - "int", - "uint", - "bool", - }; - char name[10]; - - static const char *const sampler_names[] = - { - "sampler", - "sampler1D", - "sampler2D", - "sampler3D", - "samplerCUBE" - }; - - for (bt = 0; bt <= HLSL_TYPE_LAST_SCALAR; ++bt) - { - for (y = 1; y <= 4; ++y) - { - for (x = 1; x <= 4; ++x) - { - sprintf(name, "%s%ux%u", names[bt], y, x); - type = new_hlsl_type(d3dcompiler_strdup(name), HLSL_CLASS_MATRIX, bt, x, y); - add_type_to_scope(scope, type); - - if (y == 1) - { - sprintf(name, "%s%u", names[bt], x); - type = new_hlsl_type(d3dcompiler_strdup(name), HLSL_CLASS_VECTOR, bt, x, y); - add_type_to_scope(scope, type); - hlsl_ctx.builtin_types.vector[bt][x - 1] = type; - - if (x == 1) - { - sprintf(name, "%s", names[bt]); - type = new_hlsl_type(d3dcompiler_strdup(name), HLSL_CLASS_SCALAR, bt, x, y); - add_type_to_scope(scope, type); - hlsl_ctx.builtin_types.scalar[bt] = type; - } - } - } - } - } - - for (bt = 0; bt <= HLSL_SAMPLER_DIM_MAX; ++bt) - { - type = new_hlsl_type(d3dcompiler_strdup(sampler_names[bt]), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1); - type->sampler_dim = bt; - hlsl_ctx.builtin_types.sampler[bt] = type; - } - - hlsl_ctx.builtin_types.Void = new_hlsl_type(d3dcompiler_strdup("void"), HLSL_CLASS_OBJECT, HLSL_TYPE_VOID, 1, 1); - - /* DX8 effects predefined types */ - type = new_hlsl_type(d3dcompiler_strdup("DWORD"), HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1); - add_type_to_scope(scope, type); - type = new_hlsl_type(d3dcompiler_strdup("FLOAT"), HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1); - add_type_to_scope(scope, type); - type = new_hlsl_type(d3dcompiler_strdup("VECTOR"), HLSL_CLASS_VECTOR, HLSL_TYPE_FLOAT, 4, 1); - add_type_to_scope(scope, type); - type = new_hlsl_type(d3dcompiler_strdup("MATRIX"), HLSL_CLASS_MATRIX, HLSL_TYPE_FLOAT, 4, 4); - add_type_to_scope(scope, type); - type = new_hlsl_type(d3dcompiler_strdup("STRING"), HLSL_CLASS_OBJECT, HLSL_TYPE_STRING, 1, 1); - add_type_to_scope(scope, type); - type = new_hlsl_type(d3dcompiler_strdup("TEXTURE"), HLSL_CLASS_OBJECT, HLSL_TYPE_TEXTURE, 1, 1); - add_type_to_scope(scope, type); - type = new_hlsl_type(d3dcompiler_strdup("PIXELSHADER"), HLSL_CLASS_OBJECT, HLSL_TYPE_PIXELSHADER, 1, 1); - add_type_to_scope(scope, type); - type = new_hlsl_type(d3dcompiler_strdup("VERTEXSHADER"), HLSL_CLASS_OBJECT, HLSL_TYPE_VERTEXSHADER, 1, 1); - add_type_to_scope(scope, type); -} - -static BOOL type_is_void(const struct hlsl_type *type) -{ - return type->type == HLSL_CLASS_OBJECT && type->base_type == HLSL_TYPE_VOID; -} - -static struct hlsl_ir_if *new_if(struct hlsl_ir_node *condition, struct source_location loc) -{ - struct hlsl_ir_if *iff; - - if (!(iff = d3dcompiler_alloc(sizeof(*iff)))) - return NULL; - init_node(&iff->node, HLSL_IR_IF, NULL, loc); - hlsl_src_from_node(&iff->condition, condition); - list_init(&iff->then_instrs); - list_init(&iff->else_instrs); - return iff; -} - -static BOOL append_conditional_break(struct list *cond_list) -{ - struct hlsl_ir_node *condition, *not; - struct hlsl_ir_jump *jump; - struct hlsl_ir_if *iff; - - /* E.g. "for (i = 0; ; ++i)". */ - if (!list_count(cond_list)) - return TRUE; - - condition = node_from_list(cond_list); - if (!(not = new_unary_expr(HLSL_IR_UNOP_LOGIC_NOT, condition, condition->loc))) - { - ERR("Out of memory.\n"); - return FALSE; - } - list_add_tail(cond_list, ¬->entry); - - if (!(iff = new_if(not, condition->loc))) - { - ERR("Out of memory.\n"); - return FALSE; - } - list_add_tail(cond_list, &iff->node.entry); - - if (!(jump = d3dcompiler_alloc(sizeof(*jump)))) - { - ERR("Out of memory.\n"); - return FALSE; - } - init_node(&jump->node, HLSL_IR_JUMP, NULL, condition->loc); - jump->type = HLSL_IR_JUMP_BREAK; - list_add_head(&iff->then_instrs, &jump->node.entry); - return TRUE; -} - -enum loop_type -{ - LOOP_FOR, - LOOP_WHILE, - LOOP_DO_WHILE -}; - -static struct list *create_loop(enum loop_type type, struct list *init, struct list *cond, - struct list *iter, struct list *body, struct source_location loc) -{ - struct list *list = NULL; - struct hlsl_ir_loop *loop = NULL; - struct hlsl_ir_if *cond_jump = NULL; - - list = d3dcompiler_alloc(sizeof(*list)); - if (!list) - goto oom; - list_init(list); - - if (init) - list_move_head(list, init); - - loop = d3dcompiler_alloc(sizeof(*loop)); - if (!loop) - goto oom; - init_node(&loop->node, HLSL_IR_LOOP, NULL, loc); - list_add_tail(list, &loop->node.entry); - list_init(&loop->body); - - if (!append_conditional_break(cond)) - goto oom; - - if (type != LOOP_DO_WHILE) - list_move_tail(&loop->body, cond); - - list_move_tail(&loop->body, body); - - if (iter) - list_move_tail(&loop->body, iter); - - if (type == LOOP_DO_WHILE) - list_move_tail(&loop->body, cond); - - d3dcompiler_free(init); - d3dcompiler_free(cond); - d3dcompiler_free(body); - return list; - -oom: - ERR("Out of memory.\n"); - d3dcompiler_free(loop); - d3dcompiler_free(cond_jump); - d3dcompiler_free(list); - free_instr_list(init); - free_instr_list(cond); - free_instr_list(iter); - free_instr_list(body); - return NULL; -} - -static unsigned int initializer_size(const struct parse_initializer *initializer) -{ - unsigned int count = 0, i; - - for (i = 0; i < initializer->args_count; ++i) - { - count += components_count_type(initializer->args[i]->data_type); - } - TRACE("Initializer size = %u.\n", count); - return count; -} - -static void free_parse_initializer(struct parse_initializer *initializer) -{ - free_instr_list(initializer->instrs); - d3dcompiler_free(initializer->args); -} - -static struct hlsl_ir_swizzle *new_swizzle(DWORD s, unsigned int components, - struct hlsl_ir_node *val, struct source_location *loc) -{ - struct hlsl_ir_swizzle *swizzle = d3dcompiler_alloc(sizeof(*swizzle)); - - if (!swizzle) - return NULL; - init_node(&swizzle->node, HLSL_IR_SWIZZLE, - new_hlsl_type(NULL, HLSL_CLASS_VECTOR, val->data_type->base_type, components, 1), *loc); - hlsl_src_from_node(&swizzle->val, val); - swizzle->swizzle = s; - return swizzle; -} - -static struct hlsl_ir_swizzle *get_swizzle(struct hlsl_ir_node *value, const char *swizzle, - struct source_location *loc) -{ - unsigned int len = strlen(swizzle), component = 0; - unsigned int i, set, swiz = 0; - BOOL valid; - - if (value->data_type->type == HLSL_CLASS_MATRIX) - { - /* Matrix swizzle */ - BOOL m_swizzle; - unsigned int inc, x, y; - - if (len < 3 || swizzle[0] != '_') - return NULL; - m_swizzle = swizzle[1] == 'm'; - inc = m_swizzle ? 4 : 3; - - if (len % inc || len > inc * 4) - return NULL; - - for (i = 0; i < len; i += inc) - { - if (swizzle[i] != '_') - return NULL; - if (m_swizzle) - { - if (swizzle[i + 1] != 'm') - return NULL; - y = swizzle[i + 2] - '0'; - x = swizzle[i + 3] - '0'; - } - else - { - y = swizzle[i + 1] - '1'; - x = swizzle[i + 2] - '1'; - } - - if (x >= value->data_type->dimx || y >= value->data_type->dimy) - return NULL; - swiz |= (y << 4 | x) << component * 8; - component++; - } - return new_swizzle(swiz, component, value, loc); - } - - /* Vector swizzle */ - if (len > 4) - return NULL; - - for (set = 0; set < 2; ++set) - { - valid = TRUE; - component = 0; - for (i = 0; i < len; ++i) - { - char c[2][4] = {{'x', 'y', 'z', 'w'}, {'r', 'g', 'b', 'a'}}; - unsigned int s = 0; - - for (s = 0; s < 4; ++s) - { - if (swizzle[i] == c[set][s]) - break; - } - if (s == 4) - { - valid = FALSE; - break; - } - - if (s >= value->data_type->dimx) - return NULL; - swiz |= s << component * 2; - component++; - } - if (valid) - return new_swizzle(swiz, component, value, loc); - } - - return NULL; -} - -static struct hlsl_ir_var *new_var(const char *name, struct hlsl_type *type, const struct source_location loc, - const char *semantic, unsigned int modifiers, const struct reg_reservation *reg_reservation) -{ - struct hlsl_ir_var *var; - - if (!(var = d3dcompiler_alloc(sizeof(*var)))) - { - hlsl_ctx.status = PARSE_ERR; - return NULL; - } - - var->name = name; - var->data_type = type; - var->loc = loc; - var->semantic = semantic; - var->modifiers = modifiers; - var->reg_reservation = reg_reservation; - return var; -} - -static struct hlsl_ir_var *new_synthetic_var(const char *name, struct hlsl_type *type, - const struct source_location loc) -{ - struct hlsl_ir_var *var = new_var(strdup(name), type, loc, NULL, 0, NULL); - - if (var) - list_add_tail(&hlsl_ctx.globals->vars, &var->scope_entry); - return var; -} - -static struct hlsl_ir_assignment *new_assignment(struct hlsl_ir_var *var, struct hlsl_ir_node *offset, - struct hlsl_ir_node *rhs, unsigned int writemask, struct source_location loc) -{ - struct hlsl_ir_assignment *assign; - - if (!writemask && type_is_single_reg(rhs->data_type)) - writemask = (1 << rhs->data_type->dimx) - 1; - - if (!(assign = d3dcompiler_alloc(sizeof(*assign)))) - return NULL; - - init_node(&assign->node, HLSL_IR_ASSIGNMENT, NULL, loc); - assign->lhs.var = var; - hlsl_src_from_node(&assign->lhs.offset, offset); - hlsl_src_from_node(&assign->rhs, rhs); - assign->writemask = writemask; - return assign; -} - -static struct hlsl_ir_assignment *new_simple_assignment(struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs) -{ - return new_assignment(lhs, NULL, rhs, 0, rhs->loc); -} - -static struct hlsl_ir_jump *add_return(struct list *instrs, - struct hlsl_ir_node *return_value, struct source_location loc) -{ - struct hlsl_type *return_type = hlsl_ctx.cur_function->return_type; - struct hlsl_ir_jump *jump; - - if (return_value) - { - struct hlsl_ir_assignment *assignment; - - if (!(return_value = add_implicit_conversion(instrs, return_value, return_type, &loc))) - return NULL; - - if (!(assignment = new_simple_assignment(hlsl_ctx.cur_function->return_var, return_value))) - return NULL; - list_add_after(&return_value->entry, &assignment->node.entry); - } - else if (!type_is_void(return_type)) - { - hlsl_report_message(loc, HLSL_LEVEL_ERROR, "non-void function must return a value"); - return NULL; - } - - if (!(jump = d3dcompiler_alloc(sizeof(*jump)))) - { - ERR("Out of memory\n"); - return NULL; - } - init_node(&jump->node, HLSL_IR_JUMP, NULL, loc); - jump->type = HLSL_IR_JUMP_RETURN; - list_add_tail(instrs, &jump->node.entry); - - return jump; -} - -static struct hlsl_ir_constant *new_uint_constant(unsigned int n, const struct source_location loc) -{ - struct hlsl_ir_constant *c; - - if (!(c = d3dcompiler_alloc(sizeof(*c)))) - return NULL; - init_node(&c->node, HLSL_IR_CONSTANT, hlsl_ctx.builtin_types.scalar[HLSL_TYPE_UINT], loc); - c->value.u[0] = n; - return c; -} - -struct hlsl_ir_node *new_unary_expr(enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, struct source_location loc) -{ - struct hlsl_ir_expr *expr; - - if (!(expr = d3dcompiler_alloc(sizeof(*expr)))) - return NULL; - init_node(&expr->node, HLSL_IR_EXPR, arg->data_type, loc); - expr->op = op; - hlsl_src_from_node(&expr->operands[0], arg); - return &expr->node; -} - -struct hlsl_ir_node *new_binary_expr(enum hlsl_ir_expr_op op, - struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2) -{ - struct hlsl_ir_expr *expr; - - assert(compare_hlsl_types(arg1->data_type, arg2->data_type)); - - if (!(expr = d3dcompiler_alloc(sizeof(*expr)))) - return NULL; - init_node(&expr->node, HLSL_IR_EXPR, arg1->data_type, arg1->loc); - expr->op = op; - hlsl_src_from_node(&expr->operands[0], arg1); - hlsl_src_from_node(&expr->operands[1], arg2); - return &expr->node; -} - -static struct hlsl_ir_load *new_var_load(struct hlsl_ir_var *var, const struct source_location loc) -{ - struct hlsl_ir_load *load = d3dcompiler_alloc(sizeof(*load)); - - if (!load) - { - ERR("Out of memory.\n"); - return NULL; - } - init_node(&load->node, HLSL_IR_LOAD, var->data_type, loc); - load->src.var = var; - return load; -} - -static struct hlsl_ir_load *add_load(struct list *instrs, struct hlsl_ir_node *var_node, struct hlsl_ir_node *offset, - struct hlsl_type *data_type, const struct source_location loc) -{ - struct hlsl_ir_node *add = NULL; - struct hlsl_ir_load *load; - struct hlsl_ir_var *var; - - if (var_node->type == HLSL_IR_LOAD) - { - const struct hlsl_deref *src = &load_from_node(var_node)->src; - - var = src->var; - if (src->offset.node) - { - if (!(add = new_binary_expr(HLSL_IR_BINOP_ADD, src->offset.node, offset))) - return NULL; - list_add_tail(instrs, &add->entry); - offset = add; - } - } - else - { - struct hlsl_ir_assignment *assign; - char name[27]; - - sprintf(name, "", var_node); - if (!(var = new_synthetic_var(name, var_node->data_type, var_node->loc))) - return NULL; - - TRACE("Synthesized variable %p for %s node.\n", var, debug_node_type(var_node->type)); - - if (!(assign = new_simple_assignment(var, var_node))) - return NULL; - - list_add_tail(instrs, &assign->node.entry); - } - - if (!(load = d3dcompiler_alloc(sizeof(*load)))) - return NULL; - init_node(&load->node, HLSL_IR_LOAD, data_type, loc); - load->src.var = var; - hlsl_src_from_node(&load->src.offset, offset); - list_add_tail(instrs, &load->node.entry); - return load; -} - -static struct hlsl_ir_load *add_record_load(struct list *instrs, struct hlsl_ir_node *record, - const struct hlsl_struct_field *field, const struct source_location loc) -{ - struct hlsl_ir_constant *c; - - if (!(c = new_uint_constant(field->reg_offset * 4, loc))) - return NULL; - list_add_tail(instrs, &c->node.entry); - - return add_load(instrs, record, &c->node, field->type, loc); -} - -static struct hlsl_ir_load *add_array_load(struct list *instrs, struct hlsl_ir_node *array, - struct hlsl_ir_node *index, const struct source_location loc) -{ - const struct hlsl_type *expr_type = array->data_type; - struct hlsl_type *data_type; - struct hlsl_ir_constant *c; - struct hlsl_ir_node *mul; - - TRACE("Array load from type %s.\n", debug_hlsl_type(expr_type)); - - if (expr_type->type == HLSL_CLASS_ARRAY) - { - data_type = expr_type->e.array.type; - } - else if (expr_type->type == HLSL_CLASS_MATRIX || expr_type->type == HLSL_CLASS_VECTOR) - { - /* This needs to be lowered now, while we still have type information. */ - FIXME("Index of matrix or vector type.\n"); - return NULL; - } - else - { - if (expr_type->type == HLSL_CLASS_SCALAR) - hlsl_report_message(loc, HLSL_LEVEL_ERROR, "array-indexed expression is scalar"); - else - hlsl_report_message(loc, HLSL_LEVEL_ERROR, "expression is not array-indexable"); - return NULL; - } - - if (!(c = new_uint_constant(data_type->reg_size * 4, loc))) - return NULL; - list_add_tail(instrs, &c->node.entry); - if (!(mul = new_binary_expr(HLSL_IR_BINOP_MUL, index, &c->node))) - return NULL; - list_add_tail(instrs, &mul->entry); - index = mul; - - return add_load(instrs, array, index, data_type, loc); -} - -static void struct_var_initializer(struct list *list, struct hlsl_ir_var *var, - struct parse_initializer *initializer) -{ - struct hlsl_type *type = var->data_type; - struct hlsl_struct_field *field; - unsigned int i = 0; - - if (initializer_size(initializer) != components_count_type(type)) - { - hlsl_report_message(var->loc, HLSL_LEVEL_ERROR, "structure initializer mismatch"); - free_parse_initializer(initializer); - return; - } - - list_move_tail(list, initializer->instrs); - d3dcompiler_free(initializer->instrs); - - LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry) - { - struct hlsl_ir_node *node = initializer->args[i]; - struct hlsl_ir_assignment *assign; - struct hlsl_ir_constant *c; - - if (i++ >= initializer->args_count) - break; - - if (components_count_type(field->type) == components_count_type(node->data_type)) - { - if (!(c = new_uint_constant(field->reg_offset * 4, node->loc))) - break; - list_add_tail(list, &c->node.entry); - - if (!(assign = new_assignment(var, &c->node, node, 0, node->loc))) - break; - list_add_tail(list, &assign->node.entry); - } - else - FIXME("Initializing with \"mismatched\" fields is not supported yet.\n"); - } - - d3dcompiler_free(initializer->args); -} - -static void free_parse_variable_def(struct parse_variable_def *v) -{ - free_parse_initializer(&v->initializer); - d3dcompiler_free(v->name); - d3dcompiler_free((void *)v->semantic); - d3dcompiler_free(v->reg_reservation); - d3dcompiler_free(v); -} - -static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers, struct list *var_list) -{ - struct hlsl_type *type; - struct parse_variable_def *v, *v_next; - struct hlsl_ir_var *var; - BOOL ret, local = TRUE; - struct list *statements_list = d3dcompiler_alloc(sizeof(*statements_list)); - - if (basic_type->type == HLSL_CLASS_MATRIX) - assert(basic_type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK); - - if (!statements_list) - { - ERR("Out of memory.\n"); - LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry) - free_parse_variable_def(v); - d3dcompiler_free(var_list); - return NULL; - } - list_init(statements_list); - - if (!var_list) - return statements_list; - - LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry) - { - if (v->array_size) - type = new_array_type(basic_type, v->array_size); - else - type = basic_type; - - if (!(var = new_var(v->name, type, v->loc, v->semantic, modifiers, v->reg_reservation))) - { - free_parse_variable_def(v); - continue; - } - debug_dump_decl(type, modifiers, v->name, v->loc.line); - - if (hlsl_ctx.cur_scope == hlsl_ctx.globals) - { - var->modifiers |= HLSL_STORAGE_UNIFORM; - local = FALSE; - } - - if (type->modifiers & HLSL_MODIFIER_CONST && !(var->modifiers & HLSL_STORAGE_UNIFORM) && !v->initializer.args_count) - { - hlsl_report_message(v->loc, HLSL_LEVEL_ERROR, "const variable without initializer"); - free_declaration(var); - d3dcompiler_free(v); - continue; - } - - ret = declare_variable(var, local); - if (!ret) - { - free_declaration(var); - d3dcompiler_free(v); - continue; - } - TRACE("Declared variable %s.\n", var->name); - - if (v->initializer.args_count) - { - unsigned int size = initializer_size(&v->initializer); - struct hlsl_ir_load *load; - - TRACE("Variable with initializer.\n"); - if (type->type <= HLSL_CLASS_LAST_NUMERIC - && type->dimx * type->dimy != size && size != 1) - { - if (size < type->dimx * type->dimy) - { - hlsl_report_message(v->loc, HLSL_LEVEL_ERROR, - "'%s' initializer does not match", v->name); - free_parse_initializer(&v->initializer); - d3dcompiler_free(v); - continue; - } - } - if ((type->type == HLSL_CLASS_STRUCT || type->type == HLSL_CLASS_ARRAY) - && components_count_type(type) != size) - { - hlsl_report_message(v->loc, HLSL_LEVEL_ERROR, - "'%s' initializer does not match", v->name); - free_parse_initializer(&v->initializer); - d3dcompiler_free(v); - continue; - } - - if (type->type == HLSL_CLASS_STRUCT) - { - struct_var_initializer(statements_list, var, &v->initializer); - d3dcompiler_free(v); - continue; - } - if (type->type > HLSL_CLASS_LAST_NUMERIC) - { - FIXME("Initializers for non scalar/struct variables not supported yet.\n"); - free_parse_initializer(&v->initializer); - d3dcompiler_free(v); - continue; - } - if (v->array_size > 0) - { - FIXME("Initializing arrays is not supported yet.\n"); - free_parse_initializer(&v->initializer); - d3dcompiler_free(v); - continue; - } - if (v->initializer.args_count > 1) - { - FIXME("Complex initializers are not supported yet.\n"); - free_parse_initializer(&v->initializer); - d3dcompiler_free(v); - continue; - } - - load = new_var_load(var, var->loc); - list_add_tail(v->initializer.instrs, &load->node.entry); - add_assignment(v->initializer.instrs, &load->node, ASSIGN_OP_ASSIGN, v->initializer.args[0]); - d3dcompiler_free(v->initializer.args); - - if (modifiers & HLSL_STORAGE_STATIC) - list_move_tail(&hlsl_ctx.static_initializers, v->initializer.instrs); - else - list_move_tail(statements_list, v->initializer.instrs); - d3dcompiler_free(v->initializer.instrs); - } - d3dcompiler_free(v); - } - d3dcompiler_free(var_list); - return statements_list; -} - -static BOOL add_struct_field(struct list *fields, struct hlsl_struct_field *field) -{ - struct hlsl_struct_field *f; - - LIST_FOR_EACH_ENTRY(f, fields, struct hlsl_struct_field, entry) - { - if (!strcmp(f->name, field->name)) - return FALSE; - } - list_add_tail(fields, &field->entry); - return TRUE; -} - -BOOL is_row_major(const struct hlsl_type *type) -{ - /* Default to column-major if the majority isn't explicitly set, which can - * happen for anonymous nodes. */ - return !!(type->modifiers & HLSL_MODIFIER_ROW_MAJOR); -} - -static struct hlsl_type *apply_type_modifiers(struct hlsl_type *type, - unsigned int *modifiers, struct source_location loc) -{ - unsigned int default_majority = 0; - struct hlsl_type *new_type; - - /* This function is only used for declarations (i.e. variables and struct - * fields), which should inherit the matrix majority. We only explicitly set - * the default majority for declarations—typedefs depend on this—but we - * want to always set it, so that an hlsl_type object is never used to - * represent two different majorities (and thus can be used to store its - * register size, etc.) */ - if (!(*modifiers & HLSL_MODIFIERS_MAJORITY_MASK) - && !(type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK) - && type->type == HLSL_CLASS_MATRIX) - { - if (hlsl_ctx.matrix_majority == HLSL_COLUMN_MAJOR) - default_majority = HLSL_MODIFIER_COLUMN_MAJOR; - else - default_majority = HLSL_MODIFIER_ROW_MAJOR; - } - - if (!default_majority && !(*modifiers & HLSL_TYPE_MODIFIERS_MASK)) - return type; - - if (!(new_type = clone_hlsl_type(type, default_majority))) - return NULL; - - new_type->modifiers = add_modifiers(new_type->modifiers, *modifiers, loc); - *modifiers &= ~HLSL_TYPE_MODIFIERS_MASK; - - if (new_type->type == HLSL_CLASS_MATRIX) - new_type->reg_size = is_row_major(new_type) ? new_type->dimy : new_type->dimx; - return new_type; -} - -static struct list *gen_struct_fields(struct hlsl_type *type, DWORD modifiers, struct list *fields) -{ - struct parse_variable_def *v, *v_next; - struct hlsl_struct_field *field; - struct list *list; - - if (type->type == HLSL_CLASS_MATRIX) - assert(type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK); - - list = d3dcompiler_alloc(sizeof(*list)); - if (!list) - { - ERR("Out of memory.\n"); - return NULL; - } - list_init(list); - LIST_FOR_EACH_ENTRY_SAFE(v, v_next, fields, struct parse_variable_def, entry) - { - debug_dump_decl(type, 0, v->name, v->loc.line); - field = d3dcompiler_alloc(sizeof(*field)); - if (!field) - { - ERR("Out of memory.\n"); - d3dcompiler_free(v); - return list; - } - if (v->array_size) - field->type = new_array_type(type, v->array_size); - else - field->type = type; - field->name = v->name; - field->modifiers = modifiers; - field->semantic = v->semantic; - if (v->initializer.args_count) - { - hlsl_report_message(v->loc, HLSL_LEVEL_ERROR, "struct field with an initializer.\n"); - free_parse_initializer(&v->initializer); - } - list_add_tail(list, &field->entry); - d3dcompiler_free(v); - } - d3dcompiler_free(fields); - return list; -} - -static DWORD get_array_size(const struct hlsl_type *type) -{ - if (type->type == HLSL_CLASS_ARRAY) - return get_array_size(type->e.array.type) * type->e.array.elements_count; - return 1; -} - -static struct hlsl_type *new_struct_type(const char *name, struct list *fields) -{ - struct hlsl_type *type = d3dcompiler_alloc(sizeof(*type)); - struct hlsl_struct_field *field; - unsigned int reg_size = 0; - - if (!type) - { - ERR("Out of memory.\n"); - return NULL; - } - type->type = HLSL_CLASS_STRUCT; - type->base_type = HLSL_TYPE_VOID; - type->name = name; - type->dimx = 0; - type->dimy = 1; - type->e.elements = fields; - - LIST_FOR_EACH_ENTRY(field, fields, struct hlsl_struct_field, entry) - { - field->reg_offset = reg_size; - reg_size += field->type->reg_size; - type->dimx += field->type->dimx * field->type->dimy * get_array_size(field->type); - } - type->reg_size = reg_size; - - list_add_tail(&hlsl_ctx.types, &type->entry); - - return type; -} - -static BOOL add_typedef(DWORD modifiers, struct hlsl_type *orig_type, struct list *list) -{ - BOOL ret; - struct hlsl_type *type; - struct parse_variable_def *v, *v_next; - - LIST_FOR_EACH_ENTRY_SAFE(v, v_next, list, struct parse_variable_def, entry) - { - if (v->array_size) - type = new_array_type(orig_type, v->array_size); - else - type = clone_hlsl_type(orig_type, 0); - if (!type) - { - ERR("Out of memory\n"); - return FALSE; - } - d3dcompiler_free((void *)type->name); - type->name = v->name; - type->modifiers |= modifiers; - - if (type->type != HLSL_CLASS_MATRIX) - check_invalid_matrix_modifiers(type->modifiers, v->loc); - else - type->reg_size = is_row_major(type) ? type->dimy : type->dimx; - - if ((type->modifiers & HLSL_MODIFIER_COLUMN_MAJOR) - && (type->modifiers & HLSL_MODIFIER_ROW_MAJOR)) - hlsl_report_message(v->loc, HLSL_LEVEL_ERROR, "more than one matrix majority keyword"); - - ret = add_type_to_scope(hlsl_ctx.cur_scope, type); - if (!ret) - { - hlsl_report_message(v->loc, HLSL_LEVEL_ERROR, - "redefinition of custom type '%s'", v->name); - } - d3dcompiler_free(v); - } - d3dcompiler_free(list); - return TRUE; -} - -static BOOL add_func_parameter(struct list *list, struct parse_parameter *param, const struct source_location loc) -{ - struct hlsl_ir_var *var; - - if (param->type->type == HLSL_CLASS_MATRIX) - assert(param->type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK); - - if (!(var = new_var(param->name, param->type, loc, param->semantic, param->modifiers, param->reg_reservation))) - return FALSE; - - if (!add_declaration(hlsl_ctx.cur_scope, var, FALSE)) - { - free_declaration(var); - return FALSE; - } - list_add_tail(list, &var->param_entry); - return TRUE; -} - -static struct reg_reservation *parse_reg_reservation(const char *reg_string) -{ - struct reg_reservation *reg_res; - enum bwritershader_param_register_type type; - DWORD regnum = 0; - - switch (reg_string[0]) - { - case 'c': - type = BWRITERSPR_CONST; - break; - case 'i': - type = BWRITERSPR_CONSTINT; - break; - case 'b': - type = BWRITERSPR_CONSTBOOL; - break; - case 's': - type = BWRITERSPR_SAMPLER; - break; - default: - FIXME("Unsupported register type.\n"); - return NULL; - } - - if (!sscanf(reg_string + 1, "%u", ®num)) - { - FIXME("Unsupported register reservation syntax.\n"); - return NULL; - } - - reg_res = d3dcompiler_alloc(sizeof(*reg_res)); - if (!reg_res) - { - ERR("Out of memory.\n"); - return NULL; - } - reg_res->type = type; - reg_res->regnum = regnum; - return reg_res; -} - -static const struct hlsl_ir_function_decl *get_overloaded_func(struct wine_rb_tree *funcs, char *name, - struct list *params, BOOL exact_signature) -{ - struct hlsl_ir_function *func; - struct wine_rb_entry *entry; - - entry = wine_rb_get(funcs, name); - if (entry) - { - func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry); - - entry = wine_rb_get(&func->overloads, params); - if (!entry) - { - if (!exact_signature) - FIXME("No exact match, search for a compatible overloaded function (if any).\n"); - return NULL; - } - return WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry); - } - return NULL; -} - -static struct hlsl_ir_function_decl *get_func_entry(const char *name) -{ - struct hlsl_ir_function_decl *decl; - struct hlsl_ir_function *func; - struct wine_rb_entry *entry; - - if ((entry = wine_rb_get(&hlsl_ctx.functions, name))) - { - func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry); - WINE_RB_FOR_EACH_ENTRY(decl, &func->overloads, struct hlsl_ir_function_decl, entry) - return decl; - } - - return NULL; -} - -static struct list *append_unop(struct list *list, struct hlsl_ir_node *node) -{ - list_add_tail(list, &node->entry); - return list; -} - -static struct list *add_binary_expr(struct list *list1, struct list *list2, - enum hlsl_ir_expr_op op, struct source_location loc) -{ - struct hlsl_ir_node *args[3] = {node_from_list(list1), node_from_list(list2)}; - list_move_tail(list1, list2); - d3dcompiler_free(list2); - add_expr(list1, op, args, &loc); - return list1; -} - -static struct list *make_list(struct hlsl_ir_node *node) -{ - struct list *list; - - if (!(list = d3dcompiler_alloc(sizeof(*list)))) - { - ERR("Out of memory.\n"); - free_instr(node); - return NULL; - } - list_init(list); - list_add_tail(list, &node->entry); - return list; -} - -static unsigned int evaluate_array_dimension(struct hlsl_ir_node *node) -{ - if (node->data_type->type != HLSL_CLASS_SCALAR) - return 0; - - switch (node->type) - { - case HLSL_IR_CONSTANT: - { - struct hlsl_ir_constant *constant = constant_from_node(node); - - switch (constant->node.data_type->base_type) - { - case HLSL_TYPE_UINT: - return constant->value.u[0]; - case HLSL_TYPE_INT: - return constant->value.i[0]; - case HLSL_TYPE_FLOAT: - return constant->value.f[0]; - case HLSL_TYPE_DOUBLE: - return constant->value.d[0]; - case HLSL_TYPE_BOOL: - return constant->value.b[0]; - default: - WARN("Invalid type %s.\n", debug_base_type(constant->node.data_type)); - return 0; - } - } - case HLSL_IR_EXPR: - case HLSL_IR_LOAD: - case HLSL_IR_SWIZZLE: - FIXME("Unhandled type %s.\n", debug_node_type(node->type)); - return 0; - case HLSL_IR_ASSIGNMENT: - default: - WARN("Invalid node type %s.\n", debug_node_type(node->type)); - return 0; - } -} - -static struct hlsl_ir_function_decl *new_func_decl(struct hlsl_type *return_type, - struct list *parameters, const char *semantic, struct source_location loc) -{ - struct hlsl_ir_function_decl *decl; - - if (!(decl = d3dcompiler_alloc(sizeof(*decl)))) - return NULL; - decl->return_type = return_type; - decl->parameters = parameters; - decl->semantic = semantic; - decl->loc = loc; - - if (!type_is_void(return_type)) - { - struct hlsl_ir_var *return_var; - char name[28]; - - sprintf(name, "", decl); - if (!(return_var = new_synthetic_var(name, return_type, loc))) - { - d3dcompiler_free(decl); - return NULL; - } - decl->return_var = return_var; - } - - return decl; -} - -%} - -%locations -%define parse.error verbose -%expect 1 - -%union -{ - struct hlsl_type *type; - INT intval; - FLOAT floatval; - BOOL boolval; - char *name; - DWORD modifiers; - struct hlsl_ir_node *instr; - struct list *list; - struct parse_function function; - struct parse_parameter parameter; - struct parse_initializer initializer; - struct parse_variable_def *variable_def; - struct parse_if_body if_body; - enum parse_unary_op unary_op; - enum parse_assign_op assign_op; - struct reg_reservation *reg_reservation; - struct parse_colon_attribute colon_attribute; -} - -%token KW_BLENDSTATE -%token KW_BREAK -%token KW_BUFFER -%token KW_CBUFFER -%token KW_COLUMN_MAJOR -%token KW_COMPILE -%token KW_CONST -%token KW_CONTINUE -%token KW_DEPTHSTENCILSTATE -%token KW_DEPTHSTENCILVIEW -%token KW_DISCARD -%token KW_DO -%token KW_DOUBLE -%token KW_ELSE -%token KW_EXTERN -%token KW_FALSE -%token KW_FOR -%token KW_GEOMETRYSHADER -%token KW_GROUPSHARED -%token KW_IF -%token KW_IN -%token KW_INLINE -%token KW_INOUT -%token KW_MATRIX -%token KW_NAMESPACE -%token KW_NOINTERPOLATION -%token KW_OUT -%token KW_PASS -%token KW_PIXELSHADER -%token KW_PRECISE -%token KW_RASTERIZERSTATE -%token KW_RENDERTARGETVIEW -%token KW_RETURN -%token KW_REGISTER -%token KW_ROW_MAJOR -%token KW_SAMPLER -%token KW_SAMPLER1D -%token KW_SAMPLER2D -%token KW_SAMPLER3D -%token KW_SAMPLERCUBE -%token KW_SAMPLER_STATE -%token KW_SAMPLERCOMPARISONSTATE -%token KW_SHARED -%token KW_STATEBLOCK -%token KW_STATEBLOCK_STATE -%token KW_STATIC -%token KW_STRING -%token KW_STRUCT -%token KW_SWITCH -%token KW_TBUFFER -%token KW_TECHNIQUE -%token KW_TECHNIQUE10 -%token KW_TEXTURE -%token KW_TEXTURE1D -%token KW_TEXTURE1DARRAY -%token KW_TEXTURE2D -%token KW_TEXTURE2DARRAY -%token KW_TEXTURE2DMS -%token KW_TEXTURE2DMSARRAY -%token KW_TEXTURE3D -%token KW_TEXTURE3DARRAY -%token KW_TEXTURECUBE -%token KW_TRUE -%token KW_TYPEDEF -%token KW_UNIFORM -%token KW_VECTOR -%token KW_VERTEXSHADER -%token KW_VOID -%token KW_VOLATILE -%token KW_WHILE - -%token OP_INC -%token OP_DEC -%token OP_AND -%token OP_OR -%token OP_EQ -%token OP_LEFTSHIFT -%token OP_LEFTSHIFTASSIGN -%token OP_RIGHTSHIFT -%token OP_RIGHTSHIFTASSIGN -%token OP_ELLIPSIS -%token OP_LE -%token OP_GE -%token OP_NE -%token OP_ADDASSIGN -%token OP_SUBASSIGN -%token OP_MULASSIGN -%token OP_DIVASSIGN -%token OP_MODASSIGN -%token OP_ANDASSIGN -%token OP_ORASSIGN -%token OP_XORASSIGN -%token OP_UNKNOWN1 -%token OP_UNKNOWN2 -%token OP_UNKNOWN3 -%token OP_UNKNOWN4 - -%token PRE_LINE - -%token VAR_IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER -%type any_identifier var_identifier -%token STRING -%token C_FLOAT -%token C_INTEGER -%type boolean -%type base_type -%type type -%type declaration_statement -%type declaration -%type struct_declaration -%type struct_spec -%type named_struct_spec -%type unnamed_struct_spec -%type field_type -%type typedef_type -%type type_specs -%type type_spec -%type complex_initializer -%type initializer_expr_list -%type initializer_expr -%type var_modifiers -%type field -%type parameters -%type param_list -%type expr -%type array -%type statement -%type statement_list -%type compound_statement -%type jump_statement -%type selection_statement -%type loop_statement -%type func_declaration -%type func_prototype -%type fields_list -%type parameter -%type colon_attribute -%type semantic -%type register_opt -%type variable_def -%type variables_def -%type variables_def_optional -%type if_body -%type primary_expr -%type postfix_expr -%type unary_expr -%type mul_expr -%type add_expr -%type shift_expr -%type relational_expr -%type equality_expr -%type bitand_expr -%type bitxor_expr -%type bitor_expr -%type logicand_expr -%type logicor_expr -%type conditional_expr -%type assignment_expr -%type expr_statement -%type unary_op -%type assign_op -%type input_mods -%type input_mod -%% - -hlsl_prog: /* empty */ - { - } - | hlsl_prog func_declaration - { - const struct hlsl_ir_function_decl *decl; - - decl = get_overloaded_func(&hlsl_ctx.functions, $2.name, $2.decl->parameters, TRUE); - if (decl && !decl->func->intrinsic) - { - if (decl->body && $2.decl->body) - { - hlsl_report_message($2.decl->loc, HLSL_LEVEL_ERROR, - "redefinition of function %s", debugstr_a($2.name)); - YYABORT; - } - else if (!compare_hlsl_types(decl->return_type, $2.decl->return_type)) - { - hlsl_report_message($2.decl->loc, HLSL_LEVEL_ERROR, - "redefining function %s with a different return type", - debugstr_a($2.name)); - hlsl_report_message(decl->loc, HLSL_LEVEL_NOTE, - "%s previously declared here", - debugstr_a($2.name)); - YYABORT; - } - } - - if (type_is_void($2.decl->return_type) && $2.decl->semantic) - { - hlsl_report_message($2.decl->loc, HLSL_LEVEL_ERROR, - "void function with a semantic"); - } - - TRACE("Adding function '%s' to the function list.\n", $2.name); - add_function_decl(&hlsl_ctx.functions, $2.name, $2.decl, FALSE); - } - | hlsl_prog declaration_statement - { - TRACE("Declaration statement parsed.\n"); - - if (!list_empty($2)) - FIXME("Uniform initializer.\n"); - free_instr_list($2); - } - | hlsl_prog preproc_directive - { - } - | hlsl_prog ';' - { - TRACE("Skipping stray semicolon.\n"); - } - -preproc_directive: PRE_LINE STRING - { - const char **new_array = NULL; - - TRACE("Updating line information to file %s, line %u\n", debugstr_a($2), $1); - hlsl_ctx.line_no = $1; - if (strcmp($2, hlsl_ctx.source_file)) - new_array = d3dcompiler_realloc(hlsl_ctx.source_files, - sizeof(*hlsl_ctx.source_files) * (hlsl_ctx.source_files_count + 1)); - - if (new_array) - { - hlsl_ctx.source_files = new_array; - hlsl_ctx.source_files[hlsl_ctx.source_files_count++] = $2; - hlsl_ctx.source_file = $2; - } - else - { - d3dcompiler_free($2); - } - } - -struct_declaration: var_modifiers struct_spec variables_def_optional ';' - { - struct hlsl_type *type; - DWORD modifiers = $1; - - if (!$3) - { - if (!$2->name) - { - hlsl_report_message(get_location(&@2), HLSL_LEVEL_ERROR, - "anonymous struct declaration with no variables"); - } - if (modifiers) - { - hlsl_report_message(get_location(&@1), HLSL_LEVEL_ERROR, - "modifier not allowed on struct type declaration"); - } - } - - if (!(type = apply_type_modifiers($2, &modifiers, get_location(&@1)))) - YYABORT; - $$ = declare_vars(type, modifiers, $3); - } - -struct_spec: named_struct_spec - | unnamed_struct_spec - -named_struct_spec: KW_STRUCT any_identifier '{' fields_list '}' - { - BOOL ret; - - TRACE("Structure %s declaration.\n", debugstr_a($2)); - $$ = new_struct_type($2, $4); - - if (get_variable(hlsl_ctx.cur_scope, $2)) - { - hlsl_report_message(get_location(&@2), - HLSL_LEVEL_ERROR, "redefinition of '%s'", $2); - YYABORT; - } - - ret = add_type_to_scope(hlsl_ctx.cur_scope, $$); - if (!ret) - { - hlsl_report_message(get_location(&@2), - HLSL_LEVEL_ERROR, "redefinition of struct '%s'", $2); - YYABORT; - } - } - -unnamed_struct_spec: KW_STRUCT '{' fields_list '}' - { - TRACE("Anonymous structure declaration.\n"); - $$ = new_struct_type(NULL, $3); - } - -any_identifier: VAR_IDENTIFIER - | TYPE_IDENTIFIER - | NEW_IDENTIFIER - -fields_list: /* Empty */ - { - $$ = d3dcompiler_alloc(sizeof(*$$)); - list_init($$); - } - | fields_list field - { - BOOL ret; - struct hlsl_struct_field *field, *next; - - $$ = $1; - LIST_FOR_EACH_ENTRY_SAFE(field, next, $2, struct hlsl_struct_field, entry) - { - ret = add_struct_field($$, field); - if (ret == FALSE) - { - hlsl_report_message(get_location(&@2), - HLSL_LEVEL_ERROR, "redefinition of '%s'", field->name); - d3dcompiler_free(field); - } - } - d3dcompiler_free($2); - } - -field_type: type - | unnamed_struct_spec - -field: var_modifiers field_type variables_def ';' - { - struct hlsl_type *type; - DWORD modifiers = $1; - - if (!(type = apply_type_modifiers($2, &modifiers, get_location(&@1)))) - YYABORT; - $$ = gen_struct_fields(type, modifiers, $3); - } - -func_declaration: func_prototype compound_statement - { - TRACE("Function %s parsed.\n", $1.name); - $$ = $1; - $$.decl->body = $2; - pop_scope(&hlsl_ctx); - } - | func_prototype ';' - { - TRACE("Function prototype for %s.\n", $1.name); - $$ = $1; - pop_scope(&hlsl_ctx); - } - - /* var_modifiers is necessary to avoid shift/reduce conflicts. */ -func_prototype: var_modifiers type var_identifier '(' parameters ')' colon_attribute - { - if ($1) - { - hlsl_report_message(get_location(&@1), HLSL_LEVEL_ERROR, - "unexpected modifiers on a function"); - YYABORT; - } - if (get_variable(hlsl_ctx.globals, $3)) - { - hlsl_report_message(get_location(&@3), - HLSL_LEVEL_ERROR, "redefinition of '%s'\n", $3); - YYABORT; - } - if (type_is_void($2) && $7.semantic) - { - hlsl_report_message(get_location(&@7), - HLSL_LEVEL_ERROR, "void function with a semantic"); - } - - if ($7.reg_reservation) - { - FIXME("Unexpected register reservation for a function.\n"); - d3dcompiler_free($7.reg_reservation); - } - if (!($$.decl = new_func_decl($2, $5, $7.semantic, get_location(&@3)))) - { - ERR("Out of memory.\n"); - YYABORT; - } - $$.name = $3; - hlsl_ctx.cur_function = $$.decl; - } - -compound_statement: '{' '}' - { - $$ = d3dcompiler_alloc(sizeof(*$$)); - list_init($$); - } - | '{' scope_start statement_list '}' - { - pop_scope(&hlsl_ctx); - $$ = $3; - } - -scope_start: /* Empty */ - { - push_scope(&hlsl_ctx); - } - -var_identifier: VAR_IDENTIFIER - | NEW_IDENTIFIER - -colon_attribute: /* Empty */ - { - $$.semantic = NULL; - $$.reg_reservation = NULL; - } - | semantic - { - $$.semantic = $1; - $$.reg_reservation = NULL; - } - | register_opt - { - $$.semantic = NULL; - $$.reg_reservation = $1; - } - -semantic: ':' any_identifier - { - $$ = $2; - } - - /* FIXME: Writemasks */ -register_opt: ':' KW_REGISTER '(' any_identifier ')' - { - $$ = parse_reg_reservation($4); - d3dcompiler_free($4); - } - | ':' KW_REGISTER '(' any_identifier ',' any_identifier ')' - { - FIXME("Ignoring shader target %s in a register reservation.\n", debugstr_a($4)); - d3dcompiler_free($4); - - $$ = parse_reg_reservation($6); - d3dcompiler_free($6); - } - -parameters: scope_start - { - $$ = d3dcompiler_alloc(sizeof(*$$)); - list_init($$); - } - | scope_start param_list - { - $$ = $2; - } - -param_list: parameter - { - $$ = d3dcompiler_alloc(sizeof(*$$)); - list_init($$); - if (!add_func_parameter($$, &$1, get_location(&@1))) - { - ERR("Error adding function parameter %s.\n", $1.name); - set_parse_status(&hlsl_ctx.status, PARSE_ERR); - YYABORT; - } - } - | param_list ',' parameter - { - $$ = $1; - if (!add_func_parameter($$, &$3, get_location(&@3))) - { - hlsl_report_message(get_location(&@3), HLSL_LEVEL_ERROR, - "duplicate parameter %s", $3.name); - YYABORT; - } - } - -parameter: input_mods var_modifiers type any_identifier colon_attribute - { - struct hlsl_type *type; - DWORD modifiers = $2; - - if (!(type = apply_type_modifiers($3, &modifiers, get_location(&@2)))) - YYABORT; - - $$.modifiers = $1 ? $1 : HLSL_STORAGE_IN; - $$.modifiers |= modifiers; - $$.type = type; - $$.name = $4; - $$.semantic = $5.semantic; - $$.reg_reservation = $5.reg_reservation; - } - -input_mods: /* Empty */ - { - $$ = 0; - } - | input_mods input_mod - { - if ($1 & $2) - { - hlsl_report_message(get_location(&@2), HLSL_LEVEL_ERROR, - "duplicate input-output modifiers"); - YYABORT; - } - $$ = $1 | $2; - } - -input_mod: KW_IN - { - $$ = HLSL_STORAGE_IN; - } - | KW_OUT - { - $$ = HLSL_STORAGE_OUT; - } - | KW_INOUT - { - $$ = HLSL_STORAGE_IN | HLSL_STORAGE_OUT; - } - -type: - - base_type - { - $$ = $1; - } - | KW_VECTOR '<' base_type ',' C_INTEGER '>' - { - if ($3->type != HLSL_CLASS_SCALAR) - { - hlsl_report_message(get_location(&@3), HLSL_LEVEL_ERROR, - "vectors of non-scalar types are not allowed\n"); - YYABORT; - } - if ($5 < 1 || $5 > 4) - { - hlsl_report_message(get_location(&@5), HLSL_LEVEL_ERROR, - "vector size must be between 1 and 4\n"); - YYABORT; - } - - $$ = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, $3->base_type, $5, 1); - } - | KW_MATRIX '<' base_type ',' C_INTEGER ',' C_INTEGER '>' - { - if ($3->type != HLSL_CLASS_SCALAR) - { - hlsl_report_message(get_location(&@3), HLSL_LEVEL_ERROR, - "matrices of non-scalar types are not allowed\n"); - YYABORT; - } - if ($5 < 1 || $5 > 4) - { - hlsl_report_message(get_location(&@5), HLSL_LEVEL_ERROR, - "matrix row count must be between 1 and 4\n"); - YYABORT; - } - if ($7 < 1 || $7 > 4) - { - hlsl_report_message(get_location(&@7), HLSL_LEVEL_ERROR, - "matrix column count must be between 1 and 4\n"); - YYABORT; - } - - $$ = new_hlsl_type(NULL, HLSL_CLASS_MATRIX, $3->base_type, $7, $5); - } - -base_type: - - KW_VOID - { - $$ = hlsl_ctx.builtin_types.Void; - } - | KW_SAMPLER - { - $$ = hlsl_ctx.builtin_types.sampler[HLSL_SAMPLER_DIM_GENERIC]; - } - | KW_SAMPLER1D - { - $$ = hlsl_ctx.builtin_types.sampler[HLSL_SAMPLER_DIM_1D]; - } - | KW_SAMPLER2D - { - $$ = hlsl_ctx.builtin_types.sampler[HLSL_SAMPLER_DIM_2D]; - } - | KW_SAMPLER3D - { - $$ = hlsl_ctx.builtin_types.sampler[HLSL_SAMPLER_DIM_3D]; - } - | KW_SAMPLERCUBE - { - $$ = hlsl_ctx.builtin_types.sampler[HLSL_SAMPLER_DIM_3D]; - } - | TYPE_IDENTIFIER - { - $$ = get_type(hlsl_ctx.cur_scope, $1, TRUE); - d3dcompiler_free($1); - } - | KW_STRUCT TYPE_IDENTIFIER - { - $$ = get_type(hlsl_ctx.cur_scope, $2, TRUE); - if ($$->type != HLSL_CLASS_STRUCT) - hlsl_report_message(get_location(&@1), HLSL_LEVEL_ERROR, "'%s' redefined as a structure\n", $2); - d3dcompiler_free($2); - } - -declaration_statement: declaration - | struct_declaration - | typedef - { - $$ = d3dcompiler_alloc(sizeof(*$$)); - if (!$$) - { - ERR("Out of memory\n"); - YYABORT; - } - list_init($$); - } - -typedef_type: type - | struct_spec - -typedef: KW_TYPEDEF var_modifiers typedef_type type_specs ';' - { - if ($2 & ~HLSL_TYPE_MODIFIERS_MASK) - { - struct parse_variable_def *v, *v_next; - hlsl_report_message(get_location(&@1), - HLSL_LEVEL_ERROR, "modifier not allowed on typedefs"); - LIST_FOR_EACH_ENTRY_SAFE(v, v_next, $4, struct parse_variable_def, entry) - d3dcompiler_free(v); - d3dcompiler_free($4); - YYABORT; - } - if (!add_typedef($2, $3, $4)) - YYABORT; - } - -type_specs: type_spec - { - $$ = d3dcompiler_alloc(sizeof(*$$)); - list_init($$); - list_add_head($$, &$1->entry); - } - | type_specs ',' type_spec - { - $$ = $1; - list_add_tail($$, &$3->entry); - } - -type_spec: any_identifier array - { - $$ = d3dcompiler_alloc(sizeof(*$$)); - $$->loc = get_location(&@1); - $$->name = $1; - $$->array_size = $2; - } - -declaration: var_modifiers type variables_def ';' - { - struct hlsl_type *type; - DWORD modifiers = $1; - - if (!(type = apply_type_modifiers($2, &modifiers, get_location(&@1)))) - YYABORT; - $$ = declare_vars(type, modifiers, $3); - } - -variables_def_optional: /* Empty */ - { - $$ = NULL; - } - | variables_def - { - $$ = $1; - } - -variables_def: variable_def - { - $$ = d3dcompiler_alloc(sizeof(*$$)); - list_init($$); - list_add_head($$, &$1->entry); - } - | variables_def ',' variable_def - { - $$ = $1; - list_add_tail($$, &$3->entry); - } - -variable_def: any_identifier array colon_attribute - { - $$ = d3dcompiler_alloc(sizeof(*$$)); - $$->loc = get_location(&@1); - $$->name = $1; - $$->array_size = $2; - $$->semantic = $3.semantic; - $$->reg_reservation = $3.reg_reservation; - } - | any_identifier array colon_attribute '=' complex_initializer - { - TRACE("Declaration with initializer.\n"); - $$ = d3dcompiler_alloc(sizeof(*$$)); - $$->loc = get_location(&@1); - $$->name = $1; - $$->array_size = $2; - $$->semantic = $3.semantic; - $$->reg_reservation = $3.reg_reservation; - $$->initializer = $5; - } - -array: /* Empty */ - { - $$ = 0; - } - | '[' expr ']' - { - unsigned int size = evaluate_array_dimension(node_from_list($2)); - - free_instr_list($2); - - if (!size) - { - hlsl_report_message(get_location(&@2), HLSL_LEVEL_ERROR, - "array size is not a positive integer constant\n"); - YYABORT; - } - TRACE("Array size %u.\n", size); - - if (size > 65536) - { - hlsl_report_message(get_location(&@2), HLSL_LEVEL_ERROR, - "array size must be between 1 and 65536"); - YYABORT; - } - $$ = size; - } - -var_modifiers: /* Empty */ - { - $$ = 0; - } - | KW_EXTERN var_modifiers - { - $$ = add_modifiers($2, HLSL_STORAGE_EXTERN, get_location(&@1)); - } - | KW_NOINTERPOLATION var_modifiers - { - $$ = add_modifiers($2, HLSL_STORAGE_NOINTERPOLATION, get_location(&@1)); - } - | KW_PRECISE var_modifiers - { - $$ = add_modifiers($2, HLSL_MODIFIER_PRECISE, get_location(&@1)); - } - | KW_SHARED var_modifiers - { - $$ = add_modifiers($2, HLSL_STORAGE_SHARED, get_location(&@1)); - } - | KW_GROUPSHARED var_modifiers - { - $$ = add_modifiers($2, HLSL_STORAGE_GROUPSHARED, get_location(&@1)); - } - | KW_STATIC var_modifiers - { - $$ = add_modifiers($2, HLSL_STORAGE_STATIC, get_location(&@1)); - } - | KW_UNIFORM var_modifiers - { - $$ = add_modifiers($2, HLSL_STORAGE_UNIFORM, get_location(&@1)); - } - | KW_VOLATILE var_modifiers - { - $$ = add_modifiers($2, HLSL_STORAGE_VOLATILE, get_location(&@1)); - } - | KW_CONST var_modifiers - { - $$ = add_modifiers($2, HLSL_MODIFIER_CONST, get_location(&@1)); - } - | KW_ROW_MAJOR var_modifiers - { - $$ = add_modifiers($2, HLSL_MODIFIER_ROW_MAJOR, get_location(&@1)); - } - | KW_COLUMN_MAJOR var_modifiers - { - $$ = add_modifiers($2, HLSL_MODIFIER_COLUMN_MAJOR, get_location(&@1)); - } - -complex_initializer: initializer_expr - { - $$.args_count = 1; - if (!($$.args = d3dcompiler_alloc(sizeof(*$$.args)))) - YYABORT; - $$.args[0] = node_from_list($1); - $$.instrs = $1; - } - | '{' initializer_expr_list '}' - { - $$ = $2; - } - | '{' initializer_expr_list ',' '}' - { - $$ = $2; - } - -initializer_expr: assignment_expr - { - $$ = $1; - } - -initializer_expr_list: initializer_expr - { - $$.args_count = 1; - if (!($$.args = d3dcompiler_alloc(sizeof(*$$.args)))) - YYABORT; - $$.args[0] = node_from_list($1); - $$.instrs = $1; - } - | initializer_expr_list ',' initializer_expr - { - $$ = $1; - if (!($$.args = d3dcompiler_realloc($$.args, ($$.args_count + 1) * sizeof(*$$.args)))) - YYABORT; - $$.args[$$.args_count++] = node_from_list($3); - list_move_tail($$.instrs, $3); - d3dcompiler_free($3); - } - -boolean: KW_TRUE - { - $$ = TRUE; - } - | KW_FALSE - { - $$ = FALSE; - } - -statement_list: statement - { - $$ = $1; - } - | statement_list statement - { - $$ = $1; - list_move_tail($$, $2); - d3dcompiler_free($2); - } - -statement: declaration_statement - | expr_statement - | compound_statement - | jump_statement - | selection_statement - | loop_statement - -jump_statement: - - KW_RETURN expr ';' - { - if (!add_return($2, node_from_list($2), get_location(&@1))) - YYABORT; - $$ = $2; - } - | KW_RETURN ';' - { - if (!($$ = d3dcompiler_alloc(sizeof(*$$)))) - YYABORT; - list_init($$); - if (!add_return($$, NULL, get_location(&@1))) - YYABORT; - } - -selection_statement: KW_IF '(' expr ')' if_body - { - struct hlsl_ir_node *condition = node_from_list($3); - struct hlsl_ir_if *instr; - - if (!(instr = new_if(condition, get_location(&@1)))) - YYABORT; - list_move_tail(&instr->then_instrs, $5.then_instrs); - list_move_tail(&instr->else_instrs, $5.else_instrs); - d3dcompiler_free($5.then_instrs); - d3dcompiler_free($5.else_instrs); - if (condition->data_type->dimx > 1 || condition->data_type->dimy > 1) - { - hlsl_report_message(instr->node.loc, HLSL_LEVEL_ERROR, - "if condition requires a scalar"); - } - $$ = $3; - list_add_tail($$, &instr->node.entry); - } - -if_body: statement - { - $$.then_instrs = $1; - $$.else_instrs = NULL; - } - | statement KW_ELSE statement - { - $$.then_instrs = $1; - $$.else_instrs = $3; - } - -loop_statement: KW_WHILE '(' expr ')' statement - { - $$ = create_loop(LOOP_WHILE, NULL, $3, NULL, $5, get_location(&@1)); - } - | KW_DO statement KW_WHILE '(' expr ')' ';' - { - $$ = create_loop(LOOP_DO_WHILE, NULL, $5, NULL, $2, get_location(&@1)); - } - | KW_FOR '(' scope_start expr_statement expr_statement expr ')' statement - { - $$ = create_loop(LOOP_FOR, $4, $5, $6, $8, get_location(&@1)); - pop_scope(&hlsl_ctx); - } - | KW_FOR '(' scope_start declaration expr_statement expr ')' statement - { - if (!$4) - hlsl_report_message(get_location(&@4), HLSL_LEVEL_WARNING, - "no expressions in for loop initializer"); - $$ = create_loop(LOOP_FOR, $4, $5, $6, $8, get_location(&@1)); - pop_scope(&hlsl_ctx); - } - -expr_statement: ';' - { - $$ = d3dcompiler_alloc(sizeof(*$$)); - list_init($$); - } - | expr ';' - { - $$ = $1; - } - -primary_expr: C_FLOAT - { - struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c)); - if (!c) - { - ERR("Out of memory.\n"); - YYABORT; - } - init_node(&c->node, HLSL_IR_CONSTANT, - hlsl_ctx.builtin_types.scalar[HLSL_TYPE_FLOAT], get_location(&@1)); - c->value.f[0] = $1; - if (!($$ = make_list(&c->node))) - YYABORT; - } - | C_INTEGER - { - struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c)); - if (!c) - { - ERR("Out of memory.\n"); - YYABORT; - } - init_node(&c->node, HLSL_IR_CONSTANT, - hlsl_ctx.builtin_types.scalar[HLSL_TYPE_INT], get_location(&@1)); - c->value.i[0] = $1; - if (!($$ = make_list(&c->node))) - YYABORT; - } - | boolean - { - struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c)); - if (!c) - { - ERR("Out of memory.\n"); - YYABORT; - } - init_node(&c->node, HLSL_IR_CONSTANT, - hlsl_ctx.builtin_types.scalar[HLSL_TYPE_BOOL], get_location(&@1)); - c->value.b[0] = $1; - if (!($$ = make_list(&c->node))) - YYABORT; - } - | VAR_IDENTIFIER - { - struct hlsl_ir_load *load; - struct hlsl_ir_var *var; - - if (!(var = get_variable(hlsl_ctx.cur_scope, $1))) - { - hlsl_report_message(get_location(&@1), HLSL_LEVEL_ERROR, - "variable '%s' is not declared\n", $1); - YYABORT; - } - if ((load = new_var_load(var, get_location(&@1)))) - { - if (!($$ = make_list(&load->node))) - YYABORT; - } - else - $$ = NULL; - } - | '(' expr ')' - { - $$ = $2; - } - -postfix_expr: primary_expr - { - $$ = $1; - } - | postfix_expr OP_INC - { - struct source_location loc; - struct hlsl_ir_node *inc; - - loc = get_location(&@2); - if (node_from_list($1)->data_type->modifiers & HLSL_MODIFIER_CONST) - { - hlsl_report_message(loc, HLSL_LEVEL_ERROR, "modifying a const expression"); - YYABORT; - } - inc = new_unary_expr(HLSL_IR_UNOP_POSTINC, node_from_list($1), loc); - /* Post increment/decrement expressions are considered const */ - inc->data_type = clone_hlsl_type(inc->data_type, 0); - inc->data_type->modifiers |= HLSL_MODIFIER_CONST; - $$ = append_unop($1, inc); - } - | postfix_expr OP_DEC - { - struct source_location loc; - struct hlsl_ir_node *inc; - - loc = get_location(&@2); - if (node_from_list($1)->data_type->modifiers & HLSL_MODIFIER_CONST) - { - hlsl_report_message(loc, HLSL_LEVEL_ERROR, "modifying a const expression"); - YYABORT; - } - inc = new_unary_expr(HLSL_IR_UNOP_POSTDEC, node_from_list($1), loc); - /* Post increment/decrement expressions are considered const */ - inc->data_type = clone_hlsl_type(inc->data_type, 0); - inc->data_type->modifiers |= HLSL_MODIFIER_CONST; - $$ = append_unop($1, inc); - } - | postfix_expr '.' any_identifier - { - struct hlsl_ir_node *node = node_from_list($1); - struct source_location loc; - - loc = get_location(&@2); - if (node->data_type->type == HLSL_CLASS_STRUCT) - { - struct hlsl_type *type = node->data_type; - struct hlsl_struct_field *field; - - $$ = NULL; - LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry) - { - if (!strcmp($3, field->name)) - { - if (!add_record_load($1, node, field, loc)) - YYABORT; - $$ = $1; - break; - } - } - if (!$$) - { - hlsl_report_message(loc, HLSL_LEVEL_ERROR, - "invalid subscript %s", debugstr_a($3)); - YYABORT; - } - } - else if (node->data_type->type <= HLSL_CLASS_LAST_NUMERIC) - { - struct hlsl_ir_swizzle *swizzle; - - swizzle = get_swizzle(node, $3, &loc); - if (!swizzle) - { - hlsl_report_message(loc, HLSL_LEVEL_ERROR, - "invalid swizzle %s", debugstr_a($3)); - YYABORT; - } - $$ = append_unop($1, &swizzle->node); - } - else - { - hlsl_report_message(loc, HLSL_LEVEL_ERROR, - "invalid subscript %s", debugstr_a($3)); - YYABORT; - } - } - | postfix_expr '[' expr ']' - { - struct hlsl_ir_node *array = node_from_list($1), *index = node_from_list($3); - - list_move_tail($1, $3); - d3dcompiler_free($3); - - if (index->data_type->type != HLSL_CLASS_SCALAR) - { - hlsl_report_message(get_location(&@3), HLSL_LEVEL_ERROR, "array index is not scalar"); - free_instr_list($1); - YYABORT; - } - - if (!add_array_load($1, array, index, get_location(&@2))) - { - free_instr_list($1); - YYABORT; - } - $$ = $1; - } - - /* "var_modifiers" doesn't make sense in this case, but it's needed - in the grammar to avoid shift/reduce conflicts. */ - | var_modifiers type '(' initializer_expr_list ')' - { - struct hlsl_ir_assignment *assignment; - unsigned int i, writemask_offset = 0; - static unsigned int counter; - struct hlsl_ir_load *load; - struct hlsl_ir_var *var; - char name[23]; - - if ($1) - { - hlsl_report_message(get_location(&@1), HLSL_LEVEL_ERROR, - "unexpected modifier on a constructor\n"); - YYABORT; - } - if ($2->type > HLSL_CLASS_LAST_NUMERIC) - { - hlsl_report_message(get_location(&@2), HLSL_LEVEL_ERROR, - "constructors may only be used with numeric data types\n"); - YYABORT; - } - if ($2->dimx * $2->dimy != initializer_size(&$4)) - { - hlsl_report_message(get_location(&@4), HLSL_LEVEL_ERROR, - "expected %u components in constructor, but got %u\n", - $2->dimx * $2->dimy, initializer_size(&$4)); - YYABORT; - } - - if ($2->type == HLSL_CLASS_MATRIX) - FIXME("Matrix constructors are not supported yet.\n"); - - sprintf(name, "", counter++); - if (!(var = new_synthetic_var(name, $2, get_location(&@2)))) - YYABORT; - for (i = 0; i < $4.args_count; ++i) - { - struct hlsl_ir_node *arg = $4.args[i]; - unsigned int width; - - if (arg->data_type->type == HLSL_CLASS_OBJECT) - { - hlsl_report_message(arg->loc, HLSL_LEVEL_ERROR, - "invalid constructor argument"); - continue; - } - width = components_count_type(arg->data_type); - - if (width > 4) - { - FIXME("Constructor argument with %u components.\n", width); - continue; - } - - if (!(arg = add_implicit_conversion($4.instrs, arg, - hlsl_ctx.builtin_types.vector[$2->base_type][width - 1], &arg->loc))) - continue; - - if (!(assignment = new_assignment(var, NULL, arg, - ((1 << width) - 1) << writemask_offset, arg->loc))) - YYABORT; - writemask_offset += width; - list_add_tail($4.instrs, &assignment->node.entry); - } - d3dcompiler_free($4.args); - if (!(load = new_var_load(var, get_location(&@2)))) - YYABORT; - $$ = append_unop($4.instrs, &load->node); - } - -unary_expr: postfix_expr - { - $$ = $1; - } - | OP_INC unary_expr - { - struct source_location loc; - - loc = get_location(&@1); - if (node_from_list($2)->data_type->modifiers & HLSL_MODIFIER_CONST) - { - hlsl_report_message(loc, HLSL_LEVEL_ERROR, "modifying a const expression"); - YYABORT; - } - $$ = append_unop($2, new_unary_expr(HLSL_IR_UNOP_PREINC, node_from_list($2), loc)); - } - | OP_DEC unary_expr - { - struct source_location loc; - - loc = get_location(&@1); - if (node_from_list($2)->data_type->modifiers & HLSL_MODIFIER_CONST) - { - hlsl_report_message(loc, HLSL_LEVEL_ERROR, "modifying a const expression"); - YYABORT; - } - $$ = append_unop($2, new_unary_expr(HLSL_IR_UNOP_PREDEC, node_from_list($2), loc)); - } - | unary_op unary_expr - { - enum hlsl_ir_expr_op ops[] = {0, HLSL_IR_UNOP_NEG, - HLSL_IR_UNOP_LOGIC_NOT, HLSL_IR_UNOP_BIT_NOT}; - - if ($1 == UNARY_OP_PLUS) - { - $$ = $2; - } - else - { - $$ = append_unop($2, new_unary_expr(ops[$1], node_from_list($2), get_location(&@1))); - } - } - /* var_modifiers just to avoid shift/reduce conflicts */ - | '(' var_modifiers type array ')' unary_expr - { - struct hlsl_type *src_type = node_from_list($6)->data_type; - struct hlsl_type *dst_type; - struct source_location loc; - - loc = get_location(&@3); - if ($2) - { - hlsl_report_message(loc, HLSL_LEVEL_ERROR, "unexpected modifier in a cast"); - YYABORT; - } - - if ($4) - dst_type = new_array_type($3, $4); - else - dst_type = $3; - - if (!compatible_data_types(src_type, dst_type)) - { - hlsl_report_message(loc, HLSL_LEVEL_ERROR, "can't cast from %s to %s", - debug_hlsl_type(src_type), debug_hlsl_type(dst_type)); - YYABORT; - } - - $$ = append_unop($6, &new_cast(node_from_list($6), dst_type, &loc)->node); - } - -unary_op: '+' - { - $$ = UNARY_OP_PLUS; - } - | '-' - { - $$ = UNARY_OP_MINUS; - } - | '!' - { - $$ = UNARY_OP_LOGICNOT; - } - | '~' - { - $$ = UNARY_OP_BITNOT; - } - -mul_expr: - - unary_expr - | mul_expr '*' unary_expr - { - $$ = add_binary_expr($1, $3, HLSL_IR_BINOP_MUL, get_location(&@2)); - } - | mul_expr '/' unary_expr - { - $$ = add_binary_expr($1, $3, HLSL_IR_BINOP_DIV, get_location(&@2)); - } - | mul_expr '%' unary_expr - { - $$ = add_binary_expr($1, $3, HLSL_IR_BINOP_MOD, get_location(&@2)); - } - -add_expr: - - mul_expr - | add_expr '+' mul_expr - { - $$ = add_binary_expr($1, $3, HLSL_IR_BINOP_ADD, get_location(&@2)); - } - | add_expr '-' mul_expr - { - $$ = add_binary_expr($1, $3, HLSL_IR_BINOP_SUB, get_location(&@2)); - } - -shift_expr: add_expr - { - $$ = $1; - } - | shift_expr OP_LEFTSHIFT add_expr - { - FIXME("Left shift\n"); - } - | shift_expr OP_RIGHTSHIFT add_expr - { - FIXME("Right shift\n"); - } - -relational_expr: - - shift_expr - | relational_expr '<' shift_expr - { - $$ = add_binary_expr($1, $3, HLSL_IR_BINOP_LESS, get_location(&@2)); - } - | relational_expr '>' shift_expr - { - $$ = add_binary_expr($1, $3, HLSL_IR_BINOP_GREATER, get_location(&@2)); - } - | relational_expr OP_LE shift_expr - { - $$ = add_binary_expr($1, $3, HLSL_IR_BINOP_LEQUAL, get_location(&@2)); - } - | relational_expr OP_GE shift_expr - { - $$ = add_binary_expr($1, $3, HLSL_IR_BINOP_GEQUAL, get_location(&@2)); - } - -equality_expr: - - relational_expr - | equality_expr OP_EQ relational_expr - { - $$ = add_binary_expr($1, $3, HLSL_IR_BINOP_EQUAL, get_location(&@2)); - } - | equality_expr OP_NE relational_expr - { - $$ = add_binary_expr($1, $3, HLSL_IR_BINOP_NEQUAL, get_location(&@2)); - } - -bitand_expr: equality_expr - { - $$ = $1; - } - | bitand_expr '&' equality_expr - { - FIXME("bitwise AND\n"); - } - -bitxor_expr: bitand_expr - { - $$ = $1; - } - | bitxor_expr '^' bitand_expr - { - FIXME("bitwise XOR\n"); - } - -bitor_expr: bitxor_expr - { - $$ = $1; - } - | bitor_expr '|' bitxor_expr - { - FIXME("bitwise OR\n"); - } - -logicand_expr: bitor_expr - { - $$ = $1; - } - | logicand_expr OP_AND bitor_expr - { - FIXME("logic AND\n"); - } - -logicor_expr: logicand_expr - { - $$ = $1; - } - | logicor_expr OP_OR logicand_expr - { - FIXME("logic OR\n"); - } - -conditional_expr: logicor_expr - { - $$ = $1; - } - | logicor_expr '?' expr ':' assignment_expr - { - FIXME("ternary operator\n"); - } - -assignment_expr: - - conditional_expr - | unary_expr assign_op assignment_expr - { - struct hlsl_ir_node *lhs = node_from_list($1), *rhs = node_from_list($3); - - if (lhs->data_type->modifiers & HLSL_MODIFIER_CONST) - { - hlsl_report_message(get_location(&@2), HLSL_LEVEL_ERROR, "l-value is const"); - YYABORT; - } - list_move_tail($3, $1); - d3dcompiler_free($1); - if (!add_assignment($3, lhs, $2, rhs)) - YYABORT; - $$ = $3; - } - -assign_op: '=' - { - $$ = ASSIGN_OP_ASSIGN; - } - | OP_ADDASSIGN - { - $$ = ASSIGN_OP_ADD; - } - | OP_SUBASSIGN - { - $$ = ASSIGN_OP_SUB; - } - | OP_MULASSIGN - { - $$ = ASSIGN_OP_MUL; - } - | OP_DIVASSIGN - { - $$ = ASSIGN_OP_DIV; - } - | OP_MODASSIGN - { - $$ = ASSIGN_OP_MOD; - } - | OP_LEFTSHIFTASSIGN - { - $$ = ASSIGN_OP_LSHIFT; - } - | OP_RIGHTSHIFTASSIGN - { - $$ = ASSIGN_OP_RSHIFT; - } - | OP_ANDASSIGN - { - $$ = ASSIGN_OP_AND; - } - | OP_ORASSIGN - { - $$ = ASSIGN_OP_OR; - } - | OP_XORASSIGN - { - $$ = ASSIGN_OP_XOR; - } - -expr: assignment_expr - { - $$ = $1; - } - | expr ',' assignment_expr - { - $$ = $1; - list_move_tail($$, $3); - d3dcompiler_free($3); - } - -%% - -static struct source_location get_location(const struct YYLTYPE *l) -{ - const struct source_location loc = - { - .file = hlsl_ctx.source_file, - .line = l->first_line, - .col = l->first_column, - }; - return loc; -} - -static void dump_function_decl(struct wine_rb_entry *entry, void *context) -{ - struct hlsl_ir_function_decl *func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry); - if (func->body) - debug_dump_ir_function_decl(func); -} - -static void dump_function(struct wine_rb_entry *entry, void *context) -{ - struct hlsl_ir_function *func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry); - wine_rb_for_each_entry(&func->overloads, dump_function_decl, NULL); -} - -/* Allocate a unique, ordered index to each instruction, which will be used for - * computing liveness ranges. */ -static unsigned int index_instructions(struct list *instrs, unsigned int index) -{ - struct hlsl_ir_node *instr; - - LIST_FOR_EACH_ENTRY(instr, instrs, struct hlsl_ir_node, entry) - { - instr->index = index++; - - if (instr->type == HLSL_IR_IF) - { - struct hlsl_ir_if *iff = if_from_node(instr); - index = index_instructions(&iff->then_instrs, index); - index = index_instructions(&iff->else_instrs, index); - } - else if (instr->type == HLSL_IR_LOOP) - { - index = index_instructions(&loop_from_node(instr)->body, index); - loop_from_node(instr)->next_index = index; - } - } - - return index; -} - -/* Compute the earliest and latest liveness for each variable. In the case that - * a variable is accessed inside of a loop, we promote its liveness to extend - * to at least the range of the entire loop. Note that we don't need to do this - * for anonymous nodes, since there's currently no way to use a node which was - * calculated in an earlier iteration of the loop. */ -static void compute_liveness_recurse(struct list *instrs, unsigned int loop_first, unsigned int loop_last) -{ - struct hlsl_ir_node *instr; - struct hlsl_ir_var *var; - - LIST_FOR_EACH_ENTRY(instr, instrs, struct hlsl_ir_node, entry) - { - switch (instr->type) - { - case HLSL_IR_ASSIGNMENT: - { - struct hlsl_ir_assignment *assignment = assignment_from_node(instr); - var = assignment->lhs.var; - if (!var->first_write) - var->first_write = loop_first ? min(instr->index, loop_first) : instr->index; - assignment->rhs.node->last_read = instr->index; - if (assignment->lhs.offset.node) - assignment->lhs.offset.node->last_read = instr->index; - break; - } - case HLSL_IR_EXPR: - { - struct hlsl_ir_expr *expr = expr_from_node(instr); - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(expr->operands) && expr->operands[i].node; ++i) - expr->operands[i].node->last_read = instr->index; - break; - } - case HLSL_IR_IF: - { - struct hlsl_ir_if *iff = if_from_node(instr); - compute_liveness_recurse(&iff->then_instrs, loop_first, loop_last); - compute_liveness_recurse(&iff->else_instrs, loop_first, loop_last); - iff->condition.node->last_read = instr->index; - break; - } - case HLSL_IR_LOAD: - { - struct hlsl_ir_load *load = load_from_node(instr); - var = load->src.var; - var->last_read = loop_last ? max(instr->index, loop_last) : instr->index; - if (load->src.offset.node) - load->src.offset.node->last_read = instr->index; - break; - } - case HLSL_IR_LOOP: - { - struct hlsl_ir_loop *loop = loop_from_node(instr); - compute_liveness_recurse(&loop->body, loop_first ? loop_first : instr->index, - loop_last ? loop_last : loop->next_index); - break; - } - case HLSL_IR_SWIZZLE: - { - struct hlsl_ir_swizzle *swizzle = swizzle_from_node(instr); - swizzle->val.node->last_read = instr->index; - break; - } - case HLSL_IR_CONSTANT: - case HLSL_IR_JUMP: - break; - } - } -} - -static void compute_liveness(struct hlsl_ir_function_decl *entry_func) -{ - struct hlsl_ir_var *var; - - LIST_FOR_EACH_ENTRY(var, &hlsl_ctx.globals->vars, struct hlsl_ir_var, scope_entry) - { - var->first_write = 1; - } - - LIST_FOR_EACH_ENTRY(var, entry_func->parameters, struct hlsl_ir_var, param_entry) - { - if (var->modifiers & HLSL_STORAGE_IN) - var->first_write = 1; - if (var->modifiers & HLSL_STORAGE_OUT) - var->last_read = UINT_MAX; - } - - if (entry_func->return_var) - entry_func->return_var->last_read = UINT_MAX; - - compute_liveness_recurse(entry_func->body, 0, 0); -} - -HRESULT parse_hlsl(enum shader_type type, DWORD major, DWORD minor, - const char *entrypoint, ID3D10Blob **shader_blob, char **messages) -{ - struct hlsl_ir_function_decl *entry_func; - struct hlsl_scope *scope, *next_scope; - struct hlsl_type *hlsl_type, *next_type; - struct hlsl_ir_var *var, *next_var; - HRESULT hr = E_FAIL; - unsigned int i; - - hlsl_ctx.status = PARSE_SUCCESS; - hlsl_ctx.messages.size = hlsl_ctx.messages.capacity = 0; - hlsl_ctx.line_no = hlsl_ctx.column = 1; - hlsl_ctx.source_file = d3dcompiler_strdup(""); - hlsl_ctx.source_files = d3dcompiler_alloc(sizeof(*hlsl_ctx.source_files)); - if (hlsl_ctx.source_files) - hlsl_ctx.source_files[0] = hlsl_ctx.source_file; - hlsl_ctx.source_files_count = 1; - hlsl_ctx.cur_scope = NULL; - hlsl_ctx.matrix_majority = HLSL_COLUMN_MAJOR; - list_init(&hlsl_ctx.scopes); - list_init(&hlsl_ctx.types); - init_functions_tree(&hlsl_ctx.functions); - list_init(&hlsl_ctx.static_initializers); - - push_scope(&hlsl_ctx); - hlsl_ctx.globals = hlsl_ctx.cur_scope; - declare_predefined_types(hlsl_ctx.globals); - - hlsl_parse(); - - if (hlsl_ctx.status == PARSE_ERR) - goto out; - - if (!(entry_func = get_func_entry(entrypoint))) - { - hlsl_message("error: entry point %s is not defined\n", debugstr_a(entrypoint)); - goto out; - } - - if (!type_is_void(entry_func->return_type) - && entry_func->return_type->type != HLSL_CLASS_STRUCT && !entry_func->semantic) - { - hlsl_report_message(entry_func->loc, HLSL_LEVEL_ERROR, - "entry point \"%s\" is missing a return value semantic", entry_func->func->name); - } - - list_move_head(entry_func->body, &hlsl_ctx.static_initializers); - - /* Index 0 means unused; index 1 means function entry, so start at 2. */ - index_instructions(entry_func->body, 2); - - if (TRACE_ON(hlsl_parser)) - { - TRACE("IR dump.\n"); - wine_rb_for_each_entry(&hlsl_ctx.functions, dump_function, NULL); - } - - compute_liveness(entry_func); - - if (hlsl_ctx.status != PARSE_ERR) - hr = E_NOTIMPL; - -out: - if (messages) - { - if (hlsl_ctx.messages.size) - *messages = hlsl_ctx.messages.string; - else - *messages = NULL; - } - else - { - if (hlsl_ctx.messages.capacity) - d3dcompiler_free(hlsl_ctx.messages.string); - } - - for (i = 0; i < hlsl_ctx.source_files_count; ++i) - d3dcompiler_free((void *)hlsl_ctx.source_files[i]); - d3dcompiler_free(hlsl_ctx.source_files); - - TRACE("Freeing functions IR.\n"); - wine_rb_destroy(&hlsl_ctx.functions, free_function_rb, NULL); - - TRACE("Freeing variables.\n"); - LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &hlsl_ctx.scopes, struct hlsl_scope, entry) - { - LIST_FOR_EACH_ENTRY_SAFE(var, next_var, &scope->vars, struct hlsl_ir_var, scope_entry) - { - free_declaration(var); - } - wine_rb_destroy(&scope->types, NULL, NULL); - d3dcompiler_free(scope); - } - - TRACE("Freeing types.\n"); - LIST_FOR_EACH_ENTRY_SAFE(hlsl_type, next_type, &hlsl_ctx.types, struct hlsl_type, entry) - { - free_hlsl_type(hlsl_type); - } - - return hr; -} diff --git a/dlls/d3dcompiler_43/tests/hlsl_d3d9.c b/dlls/d3dcompiler_43/tests/hlsl_d3d9.c index 03ded640e8f..a950fa83d89 100644 --- a/dlls/d3dcompiler_43/tests/hlsl_d3d9.c +++ b/dlls/d3dcompiler_43/tests/hlsl_d3d9.c @@ -1436,10 +1436,13 @@ static void test_fail(void) { compiled = errors = NULL; hr = ppD3DCompile(tests[i], strlen(tests[i]), NULL, NULL, NULL, "test", targets[j], 0, 0, &compiled, &errors); - ok(hr == E_FAIL, "Test %u, target %s, got unexpected hr %#x.\n", i, targets[j], hr); - ok(!!errors, "Test %u, target %s, expected non-NULL error blob.\n", i, targets[j]); + todo_wine ok(hr == E_FAIL, "Test %u, target %s, got unexpected hr %#x.\n", i, targets[j], hr); + if (hr == E_FAIL) + { + ok(!!errors, "Test %u, target %s, expected non-NULL error blob.\n", i, targets[j]); + ID3D10Blob_Release(errors); + } ok(!compiled, "Test %u, target %s, expected no compiled shader blob.\n", i, targets[j]); - ID3D10Blob_Release(errors); } } } diff --git a/dlls/d3dcompiler_43/utils.c b/dlls/d3dcompiler_43/utils.c index f464b7d56fc..0d20a85458e 100644 --- a/dlls/d3dcompiler_43/utils.c +++ b/dlls/d3dcompiler_43/utils.c @@ -757,1533 +757,3 @@ void compilation_message(struct compilation_messages *msg, const char *fmt, __ms } } } - -#if D3D_COMPILER_VERSION -BOOL add_declaration(struct hlsl_scope *scope, struct hlsl_ir_var *decl, BOOL local_var) -{ - struct hlsl_ir_var *var; - - LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry) - { - if (!strcmp(decl->name, var->name)) - return FALSE; - } - if (local_var && scope->upper->upper == hlsl_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 (!strcmp(decl->name, var->name)) - return FALSE; - } - } - - list_add_tail(&scope->vars, &decl->scope_entry); - return TRUE; -} - -struct hlsl_ir_var *get_variable(struct hlsl_scope *scope, const char *name) -{ - struct hlsl_ir_var *var; - - LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry) - { - if (!strcmp(name, var->name)) - return var; - } - if (!scope->upper) - return NULL; - return get_variable(scope->upper, name); -} - -void free_declaration(struct hlsl_ir_var *decl) -{ - d3dcompiler_free((void *)decl->name); - d3dcompiler_free((void *)decl->semantic); - d3dcompiler_free((void *)decl->reg_reservation); - d3dcompiler_free(decl); -} - -struct hlsl_type *new_hlsl_type(const char *name, enum hlsl_type_class type_class, - enum hlsl_base_type base_type, unsigned dimx, unsigned dimy) -{ - struct hlsl_type *type; - - type = d3dcompiler_alloc(sizeof(*type)); - if (!type) - { - ERR("Out of memory\n"); - return NULL; - } - type->name = name; - type->type = type_class; - type->base_type = base_type; - type->dimx = dimx; - type->dimy = dimy; - if (type_class == HLSL_CLASS_MATRIX) - type->reg_size = is_row_major(type) ? dimy : dimx; - else - type->reg_size = 1; - - list_add_tail(&hlsl_ctx.types, &type->entry); - - return type; -} - -struct hlsl_type *new_array_type(struct hlsl_type *basic_type, unsigned int array_size) -{ - struct hlsl_type *type = new_hlsl_type(NULL, HLSL_CLASS_ARRAY, HLSL_TYPE_FLOAT, 1, 1); - - if (!type) - return NULL; - - type->modifiers = basic_type->modifiers; - type->e.array.elements_count = array_size; - type->e.array.type = basic_type; - type->reg_size = basic_type->reg_size * array_size; - type->dimx = basic_type->dimx; - type->dimy = basic_type->dimy; - return type; -} - -struct hlsl_type *get_type(struct hlsl_scope *scope, const char *name, BOOL recursive) -{ - struct wine_rb_entry *entry = wine_rb_get(&scope->types, name); - if (entry) - return WINE_RB_ENTRY_VALUE(entry, struct hlsl_type, scope_entry); - - if (recursive && scope->upper) - return get_type(scope->upper, name, recursive); - return NULL; -} - -BOOL find_function(const char *name) -{ - return wine_rb_get(&hlsl_ctx.functions, name) != NULL; -} - -unsigned int components_count_type(struct hlsl_type *type) -{ - unsigned int count = 0; - struct hlsl_struct_field *field; - - if (type->type <= HLSL_CLASS_LAST_NUMERIC) - { - return type->dimx * type->dimy; - } - if (type->type == HLSL_CLASS_ARRAY) - { - return components_count_type(type->e.array.type) * type->e.array.elements_count; - } - if (type->type != HLSL_CLASS_STRUCT) - { - ERR("Unexpected data type %s.\n", debug_hlsl_type(type)); - return 0; - } - - LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry) - { - count += components_count_type(field->type); - } - return count; -} - -BOOL compare_hlsl_types(const struct hlsl_type *t1, const struct hlsl_type *t2) -{ - if (t1 == t2) - return TRUE; - - if (t1->type != t2->type) - return FALSE; - if (t1->base_type != t2->base_type) - return FALSE; - if (t1->base_type == HLSL_TYPE_SAMPLER && t1->sampler_dim != t2->sampler_dim) - return FALSE; - if ((t1->modifiers & HLSL_MODIFIERS_MAJORITY_MASK) - != (t2->modifiers & HLSL_MODIFIERS_MAJORITY_MASK)) - return FALSE; - if (t1->dimx != t2->dimx) - return FALSE; - if (t1->dimy != t2->dimy) - return FALSE; - if (t1->type == HLSL_CLASS_STRUCT) - { - struct list *t1cur, *t2cur; - struct hlsl_struct_field *t1field, *t2field; - - t1cur = list_head(t1->e.elements); - t2cur = list_head(t2->e.elements); - while (t1cur && t2cur) - { - t1field = LIST_ENTRY(t1cur, struct hlsl_struct_field, entry); - t2field = LIST_ENTRY(t2cur, struct hlsl_struct_field, entry); - if (!compare_hlsl_types(t1field->type, t2field->type)) - return FALSE; - if (strcmp(t1field->name, t2field->name)) - return FALSE; - t1cur = list_next(t1->e.elements, t1cur); - t2cur = list_next(t2->e.elements, t2cur); - } - if (t1cur != t2cur) - return FALSE; - } - if (t1->type == HLSL_CLASS_ARRAY) - return t1->e.array.elements_count == t2->e.array.elements_count - && compare_hlsl_types(t1->e.array.type, t2->e.array.type); - - return TRUE; -} - -struct hlsl_type *clone_hlsl_type(struct hlsl_type *old, unsigned int default_majority) -{ - struct hlsl_type *type; - struct hlsl_struct_field *old_field, *field; - - type = d3dcompiler_alloc(sizeof(*type)); - if (!type) - { - ERR("Out of memory\n"); - return NULL; - } - if (old->name) - { - type->name = d3dcompiler_strdup(old->name); - if (!type->name) - { - d3dcompiler_free(type); - return NULL; - } - } - type->type = old->type; - type->base_type = old->base_type; - type->dimx = old->dimx; - type->dimy = old->dimy; - type->modifiers = old->modifiers; - if (!(type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK)) - type->modifiers |= default_majority; - type->sampler_dim = old->sampler_dim; - switch (old->type) - { - case HLSL_CLASS_ARRAY: - type->e.array.type = clone_hlsl_type(old->e.array.type, default_majority); - type->e.array.elements_count = old->e.array.elements_count; - type->reg_size = type->e.array.elements_count * type->e.array.type->reg_size; - break; - - case HLSL_CLASS_STRUCT: - { - unsigned int reg_size = 0; - - type->e.elements = d3dcompiler_alloc(sizeof(*type->e.elements)); - if (!type->e.elements) - { - d3dcompiler_free((void *)type->name); - d3dcompiler_free(type); - return NULL; - } - list_init(type->e.elements); - LIST_FOR_EACH_ENTRY(old_field, old->e.elements, struct hlsl_struct_field, entry) - { - field = d3dcompiler_alloc(sizeof(*field)); - if (!field) - { - LIST_FOR_EACH_ENTRY_SAFE(field, old_field, type->e.elements, struct hlsl_struct_field, entry) - { - d3dcompiler_free((void *)field->semantic); - d3dcompiler_free((void *)field->name); - d3dcompiler_free(field); - } - d3dcompiler_free(type->e.elements); - d3dcompiler_free((void *)type->name); - d3dcompiler_free(type); - return NULL; - } - field->type = clone_hlsl_type(old_field->type, default_majority); - field->name = d3dcompiler_strdup(old_field->name); - if (old_field->semantic) - field->semantic = d3dcompiler_strdup(old_field->semantic); - field->modifiers = old_field->modifiers; - field->reg_offset = reg_size; - reg_size += field->type->reg_size; - list_add_tail(type->e.elements, &field->entry); - } - type->reg_size = reg_size; - break; - } - - case HLSL_CLASS_MATRIX: - type->reg_size = is_row_major(type) ? type->dimy : type->dimx; - break; - - default: - type->reg_size = 1; - break; - } - - list_add_tail(&hlsl_ctx.types, &type->entry); - return type; -} - -static BOOL convertible_data_type(struct hlsl_type *type) -{ - return type->type != HLSL_CLASS_OBJECT; -} - -BOOL compatible_data_types(struct hlsl_type *t1, struct hlsl_type *t2) -{ - if (!convertible_data_type(t1) || !convertible_data_type(t2)) - return FALSE; - - if (t1->type <= HLSL_CLASS_LAST_NUMERIC) - { - /* Scalar vars can be cast to pretty much everything */ - if (t1->dimx == 1 && t1->dimy == 1) - return TRUE; - - if (t1->type == HLSL_CLASS_VECTOR && t2->type == HLSL_CLASS_VECTOR) - return t1->dimx >= t2->dimx; - } - - /* The other way around is true too i.e. whatever to scalar */ - if (t2->type <= HLSL_CLASS_LAST_NUMERIC && t2->dimx == 1 && t2->dimy == 1) - return TRUE; - - if (t1->type == HLSL_CLASS_ARRAY) - { - if (compare_hlsl_types(t1->e.array.type, t2)) - /* e.g. float4[3] to float4 is allowed */ - return TRUE; - - if (t2->type == HLSL_CLASS_ARRAY || t2->type == HLSL_CLASS_STRUCT) - return components_count_type(t1) >= components_count_type(t2); - else - return components_count_type(t1) == components_count_type(t2); - } - - if (t1->type == HLSL_CLASS_STRUCT) - return components_count_type(t1) >= components_count_type(t2); - - if (t2->type == HLSL_CLASS_ARRAY || t2->type == HLSL_CLASS_STRUCT) - return components_count_type(t1) == components_count_type(t2); - - if (t1->type == HLSL_CLASS_MATRIX || t2->type == HLSL_CLASS_MATRIX) - { - if (t1->type == HLSL_CLASS_MATRIX && t2->type == HLSL_CLASS_MATRIX && t1->dimx >= t2->dimx && t1->dimy >= t2->dimy) - return TRUE; - - /* Matrix-vector conversion is apparently allowed if they have the same components count */ - if ((t1->type == HLSL_CLASS_VECTOR || t2->type == HLSL_CLASS_VECTOR) - && components_count_type(t1) == components_count_type(t2)) - return TRUE; - return FALSE; - } - - if (components_count_type(t1) >= components_count_type(t2)) - return TRUE; - return FALSE; -} - -static BOOL implicit_compatible_data_types(struct hlsl_type *t1, struct hlsl_type *t2) -{ - if (!convertible_data_type(t1) || !convertible_data_type(t2)) - return FALSE; - - if (t1->type <= HLSL_CLASS_LAST_NUMERIC) - { - /* Scalar vars can be converted to any other numeric data type */ - if (t1->dimx == 1 && t1->dimy == 1 && t2->type <= HLSL_CLASS_LAST_NUMERIC) - return TRUE; - /* The other way around is true too */ - if (t2->dimx == 1 && t2->dimy == 1 && t2->type <= HLSL_CLASS_LAST_NUMERIC) - return TRUE; - } - - if (t1->type == HLSL_CLASS_ARRAY && t2->type == HLSL_CLASS_ARRAY) - { - return components_count_type(t1) == components_count_type(t2); - } - - if ((t1->type == HLSL_CLASS_ARRAY && t2->type <= HLSL_CLASS_LAST_NUMERIC) - || (t1->type <= HLSL_CLASS_LAST_NUMERIC && t2->type == HLSL_CLASS_ARRAY)) - { - /* e.g. float4[3] to float4 is allowed */ - if (t1->type == HLSL_CLASS_ARRAY && compare_hlsl_types(t1->e.array.type, t2)) - return TRUE; - if (components_count_type(t1) == components_count_type(t2)) - return TRUE; - return FALSE; - } - - if (t1->type <= HLSL_CLASS_VECTOR && t2->type <= HLSL_CLASS_VECTOR) - { - if (t1->dimx >= t2->dimx) - return TRUE; - return FALSE; - } - - if (t1->type == HLSL_CLASS_MATRIX || t2->type == HLSL_CLASS_MATRIX) - { - if (t1->type == HLSL_CLASS_MATRIX && t2->type == HLSL_CLASS_MATRIX - && t1->dimx >= t2->dimx && t1->dimy >= t2->dimy) - return TRUE; - - /* Matrix-vector conversion is apparently allowed if they have the same components count */ - if ((t1->type == HLSL_CLASS_VECTOR || t2->type == HLSL_CLASS_VECTOR) - && components_count_type(t1) == components_count_type(t2)) - return TRUE; - return FALSE; - } - - if (t1->type == HLSL_CLASS_STRUCT && t2->type == HLSL_CLASS_STRUCT) - return compare_hlsl_types(t1, t2); - - return FALSE; -} - -static BOOL expr_compatible_data_types(struct hlsl_type *t1, struct hlsl_type *t2) -{ - if (t1->base_type > HLSL_TYPE_LAST_SCALAR || t2->base_type > HLSL_TYPE_LAST_SCALAR) - return FALSE; - - /* Scalar vars can be converted to pretty much everything */ - if ((t1->dimx == 1 && t1->dimy == 1) || (t2->dimx == 1 && t2->dimy == 1)) - return TRUE; - - if (t1->type == HLSL_CLASS_VECTOR && t2->type == HLSL_CLASS_VECTOR) - return TRUE; - - if (t1->type == HLSL_CLASS_MATRIX || t2->type == HLSL_CLASS_MATRIX) - { - /* Matrix-vector conversion is apparently allowed if either they have the same components - count or the matrix is nx1 or 1xn */ - if (t1->type == HLSL_CLASS_VECTOR || t2->type == HLSL_CLASS_VECTOR) - { - if (components_count_type(t1) == components_count_type(t2)) - return TRUE; - - return (t1->type == HLSL_CLASS_MATRIX && (t1->dimx == 1 || t1->dimy == 1)) - || (t2->type == HLSL_CLASS_MATRIX && (t2->dimx == 1 || t2->dimy == 1)); - } - - /* Both matrices */ - if ((t1->dimx >= t2->dimx && t1->dimy >= t2->dimy) - || (t1->dimx <= t2->dimx && t1->dimy <= t2->dimy)) - return TRUE; - } - - return FALSE; -} - -static enum hlsl_base_type expr_common_base_type(enum hlsl_base_type t1, enum hlsl_base_type t2) -{ - static const enum hlsl_base_type types[] = - { - HLSL_TYPE_BOOL, - HLSL_TYPE_INT, - HLSL_TYPE_UINT, - HLSL_TYPE_HALF, - HLSL_TYPE_FLOAT, - HLSL_TYPE_DOUBLE, - }; - int t1_idx = -1, t2_idx = -1, i; - - for (i = 0; i < ARRAY_SIZE(types); ++i) - { - /* Always convert away from HLSL_TYPE_HALF */ - if (t1 == types[i]) - t1_idx = t1 == HLSL_TYPE_HALF ? i + 1 : i; - if (t2 == types[i]) - t2_idx = t2 == HLSL_TYPE_HALF ? i + 1 : i; - - if (t1_idx != -1 && t2_idx != -1) - break; - } - if (t1_idx == -1 || t2_idx == -1) - { - FIXME("Unexpected base type.\n"); - return HLSL_TYPE_FLOAT; - } - return t1_idx >= t2_idx ? t1 : t2; -} - -static struct hlsl_type *expr_common_type(struct hlsl_type *t1, struct hlsl_type *t2, - struct source_location *loc) -{ - enum hlsl_type_class type; - enum hlsl_base_type base; - unsigned int dimx, dimy; - - if (t1->type > HLSL_CLASS_LAST_NUMERIC || t2->type > HLSL_CLASS_LAST_NUMERIC) - { - hlsl_report_message(*loc, HLSL_LEVEL_ERROR, "non scalar/vector/matrix data type in expression"); - return NULL; - } - - if (compare_hlsl_types(t1, t2)) - return t1; - - if (!expr_compatible_data_types(t1, t2)) - { - hlsl_report_message(*loc, HLSL_LEVEL_ERROR, "expression data types are incompatible"); - return NULL; - } - - if (t1->base_type == t2->base_type) - base = t1->base_type; - else - base = expr_common_base_type(t1->base_type, t2->base_type); - - if (t1->dimx == 1 && t1->dimy == 1) - { - type = t2->type; - dimx = t2->dimx; - dimy = t2->dimy; - } - else if (t2->dimx == 1 && t2->dimy == 1) - { - type = t1->type; - dimx = t1->dimx; - dimy = t1->dimy; - } - else if (t1->type == HLSL_CLASS_MATRIX && t2->type == HLSL_CLASS_MATRIX) - { - type = HLSL_CLASS_MATRIX; - dimx = min(t1->dimx, t2->dimx); - dimy = min(t1->dimy, t2->dimy); - } - else - { - /* Two vectors or a vector and a matrix (matrix must be 1xn or nx1) */ - unsigned int max_dim_1, max_dim_2; - - max_dim_1 = max(t1->dimx, t1->dimy); - max_dim_2 = max(t2->dimx, t2->dimy); - if (t1->dimx * t1->dimy == t2->dimx * t2->dimy) - { - type = HLSL_CLASS_VECTOR; - dimx = max(t1->dimx, t2->dimx); - dimy = 1; - } - else if (max_dim_1 <= max_dim_2) - { - type = t1->type; - if (type == HLSL_CLASS_VECTOR) - { - dimx = max_dim_1; - dimy = 1; - } - else - { - dimx = t1->dimx; - dimy = t1->dimy; - } - } - else - { - type = t2->type; - if (type == HLSL_CLASS_VECTOR) - { - dimx = max_dim_2; - dimy = 1; - } - else - { - dimx = t2->dimx; - dimy = t2->dimy; - } - } - } - - if (type == HLSL_CLASS_SCALAR) - return hlsl_ctx.builtin_types.scalar[base]; - if (type == HLSL_CLASS_VECTOR) - return hlsl_ctx.builtin_types.vector[base][dimx - 1]; - return new_hlsl_type(NULL, type, base, dimx, dimy); -} - -struct hlsl_ir_node *add_implicit_conversion(struct list *instrs, struct hlsl_ir_node *node, - struct hlsl_type *dst_type, struct source_location *loc) -{ - struct hlsl_type *src_type = node->data_type; - struct hlsl_ir_expr *cast; - - if (compare_hlsl_types(src_type, dst_type)) - return node; - - if (!implicit_compatible_data_types(src_type, dst_type)) - { - hlsl_report_message(*loc, HLSL_LEVEL_ERROR, "can't implicitly convert %s to %s", - debug_hlsl_type(src_type), debug_hlsl_type(dst_type)); - return NULL; - } - - if (dst_type->dimx * dst_type->dimy < src_type->dimx * src_type->dimy) - hlsl_report_message(*loc, HLSL_LEVEL_WARNING, "implicit truncation of vector type"); - - TRACE("Implicit conversion from %s to %s.\n", debug_hlsl_type(src_type), debug_hlsl_type(dst_type)); - - if (!(cast = new_cast(node, dst_type, loc))) - return NULL; - list_add_tail(instrs, &cast->node.entry); - return &cast->node; -} - -struct hlsl_ir_expr *add_expr(struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *operands[3], - struct source_location *loc) -{ - struct hlsl_ir_expr *expr; - struct hlsl_type *type; - unsigned int i; - - type = operands[0]->data_type; - for (i = 1; i <= 2; ++i) - { - if (!operands[i]) - break; - type = expr_common_type(type, operands[i]->data_type, loc); - if (!type) - return NULL; - } - for (i = 0; i <= 2; ++i) - { - struct hlsl_ir_expr *cast; - - if (!operands[i]) - break; - if (compare_hlsl_types(operands[i]->data_type, type)) - continue; - TRACE("Implicitly converting %s into %s in an expression\n", debug_hlsl_type(operands[i]->data_type), debug_hlsl_type(type)); - if (operands[i]->data_type->dimx * operands[i]->data_type->dimy != 1 - && operands[i]->data_type->dimx * operands[i]->data_type->dimy != type->dimx * type->dimy) - { - hlsl_report_message(operands[i]->loc, HLSL_LEVEL_WARNING, "implicit truncation of vector/matrix type"); - } - - if (!(cast = new_cast(operands[i], type, &operands[i]->loc))) - return NULL; - list_add_after(&operands[i]->entry, &cast->node.entry); - operands[i] = &cast->node; - } - - if (!(expr = d3dcompiler_alloc(sizeof(*expr)))) - return NULL; - init_node(&expr->node, HLSL_IR_EXPR, type, *loc); - expr->op = op; - for (i = 0; i <= 2; ++i) - hlsl_src_from_node(&expr->operands[i], operands[i]); - list_add_tail(instrs, &expr->node.entry); - - return expr; -} - -struct hlsl_ir_expr *new_cast(struct hlsl_ir_node *node, struct hlsl_type *type, - struct source_location *loc) -{ - struct hlsl_ir_node *cast; - - cast = new_unary_expr(HLSL_IR_UNOP_CAST, node, *loc); - if (cast) - cast->data_type = type; - return expr_from_node(cast); -} - -static enum hlsl_ir_expr_op op_from_assignment(enum parse_assign_op op) -{ - static const enum hlsl_ir_expr_op ops[] = - { - 0, - HLSL_IR_BINOP_ADD, - HLSL_IR_BINOP_SUB, - HLSL_IR_BINOP_MUL, - HLSL_IR_BINOP_DIV, - HLSL_IR_BINOP_MOD, - HLSL_IR_BINOP_LSHIFT, - HLSL_IR_BINOP_RSHIFT, - HLSL_IR_BINOP_BIT_AND, - HLSL_IR_BINOP_BIT_OR, - HLSL_IR_BINOP_BIT_XOR, - }; - - return ops[op]; -} - -static BOOL invert_swizzle(unsigned int *swizzle, unsigned int *writemask, unsigned int *ret_width) -{ - unsigned int i, j, bit = 0, inverted = 0, width, new_writemask = 0, new_swizzle = 0; - - /* Apply the writemask to the swizzle to get a new writemask and swizzle. */ - for (i = 0; i < 4; ++i) - { - if (*writemask & (1 << i)) - { - unsigned int s = (*swizzle >> (i * 2)) & 3; - new_swizzle |= s << (bit++ * 2); - if (new_writemask & (1 << s)) - return FALSE; - new_writemask |= 1 << s; - } - } - width = bit; - - /* Invert the swizzle. */ - bit = 0; - for (i = 0; i < 4; ++i) - { - for (j = 0; j < width; ++j) - { - unsigned int s = (new_swizzle >> (j * 2)) & 3; - if (s == i) - inverted |= j << (bit++ * 2); - } - } - - *swizzle = inverted; - *writemask = new_writemask; - *ret_width = width; - return TRUE; -} - -struct hlsl_ir_node *add_assignment(struct list *instrs, struct hlsl_ir_node *lhs, - enum parse_assign_op assign_op, struct hlsl_ir_node *rhs) -{ - struct hlsl_ir_assignment *assign; - struct hlsl_type *lhs_type; - DWORD writemask = 0; - - lhs_type = lhs->data_type; - if (lhs_type->type <= HLSL_CLASS_LAST_NUMERIC) - { - writemask = (1 << lhs_type->dimx) - 1; - - if (!(rhs = add_implicit_conversion(instrs, rhs, lhs_type, &rhs->loc))) - return NULL; - } - - assign = d3dcompiler_alloc(sizeof(*assign)); - if (!assign) - { - ERR("Out of memory\n"); - return NULL; - } - - while (lhs->type != HLSL_IR_LOAD) - { - struct hlsl_ir_node *lhs_inner; - - if (lhs->type == HLSL_IR_EXPR && expr_from_node(lhs)->op == HLSL_IR_UNOP_CAST) - { - FIXME("Cast on the lhs.\n"); - d3dcompiler_free(assign); - return NULL; - } - else if (lhs->type == HLSL_IR_SWIZZLE) - { - struct hlsl_ir_swizzle *swizzle = swizzle_from_node(lhs); - const struct hlsl_type *swizzle_type = swizzle->node.data_type; - unsigned int width; - - if (lhs->data_type->type == HLSL_CLASS_MATRIX) - FIXME("Assignments with writemasks and matrices on lhs are not supported yet.\n"); - - lhs_inner = swizzle->val.node; - hlsl_src_remove(&swizzle->val); - list_remove(&lhs->entry); - - list_add_after(&rhs->entry, &lhs->entry); - hlsl_src_from_node(&swizzle->val, rhs); - if (!invert_swizzle(&swizzle->swizzle, &writemask, &width)) - { - hlsl_report_message(lhs->loc, HLSL_LEVEL_ERROR, "invalid writemask"); - d3dcompiler_free(assign); - return NULL; - } - assert(swizzle_type->type == HLSL_CLASS_VECTOR); - if (swizzle_type->dimx != width) - swizzle->node.data_type = hlsl_ctx.builtin_types.vector[swizzle_type->base_type][width - 1]; - rhs = &swizzle->node; - } - else - { - hlsl_report_message(lhs->loc, HLSL_LEVEL_ERROR, "invalid lvalue"); - d3dcompiler_free(assign); - return NULL; - } - - lhs = lhs_inner; - } - - init_node(&assign->node, HLSL_IR_ASSIGNMENT, lhs_type, lhs->loc); - assign->writemask = writemask; - assign->lhs.var = load_from_node(lhs)->src.var; - hlsl_src_from_node(&assign->lhs.offset, load_from_node(lhs)->src.offset.node); - if (assign_op != ASSIGN_OP_ASSIGN) - { - enum hlsl_ir_expr_op op = op_from_assignment(assign_op); - struct hlsl_ir_node *expr; - - TRACE("Adding an expression for the compound assignment.\n"); - expr = new_binary_expr(op, lhs, rhs); - list_add_after(&rhs->entry, &expr->entry); - rhs = expr; - } - hlsl_src_from_node(&assign->rhs, rhs); - list_add_tail(instrs, &assign->node.entry); - - return &assign->node; -} - -static int compare_hlsl_types_rb(const void *key, const struct wine_rb_entry *entry) -{ - const char *name = key; - const struct hlsl_type *type = WINE_RB_ENTRY_VALUE(entry, const struct hlsl_type, scope_entry); - - if (name == type->name) - return 0; - - if (!name || !type->name) - { - ERR("hlsl_type without a name in a scope?\n"); - return -1; - } - return strcmp(name, type->name); -} - -void push_scope(struct hlsl_parse_ctx *ctx) -{ - struct hlsl_scope *new_scope = d3dcompiler_alloc(sizeof(*new_scope)); - - if (!new_scope) - { - ERR("Out of memory!\n"); - return; - } - TRACE("Pushing a new scope\n"); - list_init(&new_scope->vars); - wine_rb_init(&new_scope->types, compare_hlsl_types_rb); - new_scope->upper = ctx->cur_scope; - ctx->cur_scope = new_scope; - list_add_tail(&ctx->scopes, &new_scope->entry); -} - -BOOL pop_scope(struct hlsl_parse_ctx *ctx) -{ - struct hlsl_scope *prev_scope = ctx->cur_scope->upper; - if (!prev_scope) - return FALSE; - - TRACE("Popping current scope\n"); - ctx->cur_scope = prev_scope; - return TRUE; -} - -static int compare_param_hlsl_types(const struct hlsl_type *t1, const struct hlsl_type *t2) -{ - if (t1->type != t2->type) - { - if (!((t1->type == HLSL_CLASS_SCALAR && t2->type == HLSL_CLASS_VECTOR) - || (t1->type == HLSL_CLASS_VECTOR && t2->type == HLSL_CLASS_SCALAR))) - return t1->type - t2->type; - } - if (t1->base_type != t2->base_type) - return t1->base_type - t2->base_type; - if (t1->base_type == HLSL_TYPE_SAMPLER && t1->sampler_dim != t2->sampler_dim) - return t1->sampler_dim - t2->sampler_dim; - if (t1->dimx != t2->dimx) - return t1->dimx - t2->dimx; - if (t1->dimy != t2->dimy) - return t1->dimx - t2->dimx; - if (t1->type == HLSL_CLASS_STRUCT) - { - struct list *t1cur, *t2cur; - struct hlsl_struct_field *t1field, *t2field; - int r; - - t1cur = list_head(t1->e.elements); - t2cur = list_head(t2->e.elements); - while (t1cur && t2cur) - { - t1field = LIST_ENTRY(t1cur, struct hlsl_struct_field, entry); - t2field = LIST_ENTRY(t2cur, struct hlsl_struct_field, entry); - if ((r = compare_param_hlsl_types(t1field->type, t2field->type))) - return r; - if ((r = strcmp(t1field->name, t2field->name))) - return r; - t1cur = list_next(t1->e.elements, t1cur); - t2cur = list_next(t2->e.elements, t2cur); - } - if (t1cur != t2cur) - return t1cur ? 1 : -1; - return 0; - } - if (t1->type == HLSL_CLASS_ARRAY) - { - if (t1->e.array.elements_count != t2->e.array.elements_count) - return t1->e.array.elements_count - t2->e.array.elements_count; - return compare_param_hlsl_types(t1->e.array.type, t2->e.array.type); - } - - return 0; -} - -static int compare_function_decl_rb(const void *key, const struct wine_rb_entry *entry) -{ - const struct list *params = key; - const struct hlsl_ir_function_decl *decl = WINE_RB_ENTRY_VALUE(entry, const struct hlsl_ir_function_decl, entry); - int params_count = params ? list_count(params) : 0; - int decl_params_count = decl->parameters ? list_count(decl->parameters) : 0; - int r; - struct list *p1cur, *p2cur; - - if (params_count != decl_params_count) - return params_count - decl_params_count; - - p1cur = params ? list_head(params) : NULL; - p2cur = decl->parameters ? list_head(decl->parameters) : NULL; - while (p1cur && p2cur) - { - struct hlsl_ir_var *p1, *p2; - p1 = LIST_ENTRY(p1cur, struct hlsl_ir_var, param_entry); - p2 = LIST_ENTRY(p2cur, struct hlsl_ir_var, param_entry); - if ((r = compare_param_hlsl_types(p1->data_type, p2->data_type))) - return r; - p1cur = list_next(params, p1cur); - p2cur = list_next(decl->parameters, p2cur); - } - return 0; -} - -static int compare_function_rb(const void *key, const struct wine_rb_entry *entry) -{ - const char *name = key; - const struct hlsl_ir_function *func = WINE_RB_ENTRY_VALUE(entry, const struct hlsl_ir_function,entry); - - return strcmp(name, func->name); -} - -void init_functions_tree(struct wine_rb_tree *funcs) -{ - wine_rb_init(&hlsl_ctx.functions, compare_function_rb); -} - -const char *debug_base_type(const struct hlsl_type *type) -{ - const char *name = "(unknown)"; - - switch (type->base_type) - { - case HLSL_TYPE_FLOAT: name = "float"; break; - case HLSL_TYPE_HALF: name = "half"; break; - case HLSL_TYPE_DOUBLE: name = "double"; break; - case HLSL_TYPE_INT: name = "int"; break; - case HLSL_TYPE_UINT: name = "uint"; break; - case HLSL_TYPE_BOOL: name = "bool"; break; - case HLSL_TYPE_SAMPLER: - switch (type->sampler_dim) - { - case HLSL_SAMPLER_DIM_GENERIC: name = "sampler"; break; - case HLSL_SAMPLER_DIM_1D: name = "sampler1D"; break; - case HLSL_SAMPLER_DIM_2D: name = "sampler2D"; break; - case HLSL_SAMPLER_DIM_3D: name = "sampler3D"; break; - case HLSL_SAMPLER_DIM_CUBE: name = "samplerCUBE"; break; - } - break; - default: - FIXME("Unhandled case %u\n", type->base_type); - } - return name; -} - -const char *debug_hlsl_type(const struct hlsl_type *type) -{ - const char *name; - - if (type->name) - return debugstr_a(type->name); - - if (type->type == HLSL_CLASS_STRUCT) - return ""; - - if (type->type == HLSL_CLASS_ARRAY) - { - name = debug_base_type(type->e.array.type); - return wine_dbg_sprintf("%s[%u]", name, type->e.array.elements_count); - } - - name = debug_base_type(type); - - if (type->type == HLSL_CLASS_SCALAR) - return wine_dbg_sprintf("%s", name); - if (type->type == HLSL_CLASS_VECTOR) - return wine_dbg_sprintf("%s%u", name, type->dimx); - if (type->type == HLSL_CLASS_MATRIX) - return wine_dbg_sprintf("%s%ux%u", name, type->dimx, type->dimy); - return "unexpected_type"; -} - -const char *debug_modifiers(DWORD modifiers) -{ - char string[110]; - - string[0] = 0; - if (modifiers & HLSL_STORAGE_EXTERN) - strcat(string, " extern"); /* 7 */ - if (modifiers & HLSL_STORAGE_NOINTERPOLATION) - strcat(string, " nointerpolation"); /* 16 */ - if (modifiers & HLSL_MODIFIER_PRECISE) - strcat(string, " precise"); /* 8 */ - if (modifiers & HLSL_STORAGE_SHARED) - strcat(string, " shared"); /* 7 */ - if (modifiers & HLSL_STORAGE_GROUPSHARED) - strcat(string, " groupshared"); /* 12 */ - if (modifiers & HLSL_STORAGE_STATIC) - strcat(string, " static"); /* 7 */ - if (modifiers & HLSL_STORAGE_UNIFORM) - strcat(string, " uniform"); /* 8 */ - if (modifiers & HLSL_STORAGE_VOLATILE) - strcat(string, " volatile"); /* 9 */ - if (modifiers & HLSL_MODIFIER_CONST) - strcat(string, " const"); /* 6 */ - if (modifiers & HLSL_MODIFIER_ROW_MAJOR) - strcat(string, " row_major"); /* 10 */ - if (modifiers & HLSL_MODIFIER_COLUMN_MAJOR) - strcat(string, " column_major"); /* 13 */ - if ((modifiers & (HLSL_STORAGE_IN | HLSL_STORAGE_OUT)) == (HLSL_STORAGE_IN | HLSL_STORAGE_OUT)) - strcat(string, " inout"); /* 6 */ - else if (modifiers & HLSL_STORAGE_IN) - strcat(string, " in"); /* 3 */ - else if (modifiers & HLSL_STORAGE_OUT) - strcat(string, " out"); /* 4 */ - - return wine_dbg_sprintf("%s", string[0] ? string + 1 : ""); -} - -const char *debug_node_type(enum hlsl_ir_node_type type) -{ - static const char * const names[] = - { - "HLSL_IR_ASSIGNMENT", - "HLSL_IR_CONSTANT", - "HLSL_IR_EXPR", - "HLSL_IR_IF", - "HLSL_IR_LOAD", - "HLSL_IR_LOOP", - "HLSL_IR_JUMP", - "HLSL_IR_SWIZZLE", - }; - - if (type >= ARRAY_SIZE(names)) - return "Unexpected node type"; - return names[type]; -} - -static void debug_dump_instr(const struct hlsl_ir_node *instr); - -static void debug_dump_instr_list(const struct list *list) -{ - struct hlsl_ir_node *instr; - - LIST_FOR_EACH_ENTRY(instr, list, struct hlsl_ir_node, entry) - { - debug_dump_instr(instr); - wine_dbg_printf("\n"); - } -} - -static void debug_dump_src(const struct hlsl_src *src) -{ - if (src->node->index) - wine_dbg_printf("@%u", src->node->index); - else - wine_dbg_printf("%p", src->node); -} - -static void debug_dump_ir_var(const struct hlsl_ir_var *var) -{ - if (var->modifiers) - wine_dbg_printf("%s ", debug_modifiers(var->modifiers)); - wine_dbg_printf("%s %s", debug_hlsl_type(var->data_type), var->name); - if (var->semantic) - wine_dbg_printf(" : %s", debugstr_a(var->semantic)); -} - -static void debug_dump_deref(const struct hlsl_deref *deref) -{ - if (deref->offset.node) - /* Print the variable's type for convenience. */ - wine_dbg_printf("(%s %s)", debug_hlsl_type(deref->var->data_type), deref->var->name); - else - wine_dbg_printf("%s", deref->var->name); - if (deref->offset.node) - { - wine_dbg_printf("["); - debug_dump_src(&deref->offset); - wine_dbg_printf("]"); - } -} - -static void debug_dump_ir_constant(const struct hlsl_ir_constant *constant) -{ - struct hlsl_type *type = constant->node.data_type; - unsigned int x; - - if (type->dimx != 1) - wine_dbg_printf("{"); - for (x = 0; x < type->dimx; ++x) - { - switch (type->base_type) - { - case HLSL_TYPE_FLOAT: - wine_dbg_printf("%.8e ", constant->value.f[x]); - break; - case HLSL_TYPE_DOUBLE: - wine_dbg_printf("%.16e ", constant->value.d[x]); - break; - case HLSL_TYPE_INT: - wine_dbg_printf("%d ", constant->value.i[x]); - break; - case HLSL_TYPE_UINT: - wine_dbg_printf("%u ", constant->value.u[x]); - break; - case HLSL_TYPE_BOOL: - wine_dbg_printf("%s ", constant->value.b[x] ? "true" : "false"); - break; - default: - wine_dbg_printf("Constants of type %s not supported\n", debug_base_type(type)); - } - } - if (type->dimx != 1) - wine_dbg_printf("}"); -} - -static const char *debug_expr_op(const struct hlsl_ir_expr *expr) -{ - static const char * const op_names[] = - { - "~", - "!", - "-", - "abs", - "sign", - "rcp", - "rsq", - "sqrt", - "nrm", - "exp2", - "log2", - - "cast", - - "fract", - - "sin", - "cos", - "sin_reduced", - "cos_reduced", - - "dsx", - "dsy", - - "sat", - - "pre++", - "pre--", - "post++", - "post--", - - "+", - "-", - "*", - "/", - - "%", - - "<", - ">", - "<=", - ">=", - "==", - "!=", - - "&&", - "||", - - "<<", - ">>", - "&", - "|", - "^", - - "dot", - "crs", - "min", - "max", - - "pow", - - "lerp", - - ",", - }; - - if (expr->op == HLSL_IR_UNOP_CAST) - return debug_hlsl_type(expr->node.data_type); - - return op_names[expr->op]; -} - -/* Dumps the expression in a prefix "operator (operands)" form */ -static void debug_dump_ir_expr(const struct hlsl_ir_expr *expr) -{ - unsigned int i; - - wine_dbg_printf("%s (", debug_expr_op(expr)); - for (i = 0; i < 3 && expr->operands[i].node; ++i) - { - debug_dump_src(&expr->operands[i]); - wine_dbg_printf(" "); - } - wine_dbg_printf(")"); -} - -static const char *debug_writemask(DWORD writemask) -{ - static const char components[] = {'x', 'y', 'z', 'w'}; - char string[5]; - unsigned int i = 0, pos = 0; - - assert(!(writemask & ~BWRITERSP_WRITEMASK_ALL)); - - while (writemask) - { - if (writemask & 1) - string[pos++] = components[i]; - writemask >>= 1; - i++; - } - string[pos] = '\0'; - return wine_dbg_sprintf(".%s", string); -} - -static void debug_dump_ir_assignment(const struct hlsl_ir_assignment *assign) -{ - wine_dbg_printf("= ("); - debug_dump_deref(&assign->lhs); - if (assign->writemask != BWRITERSP_WRITEMASK_ALL) - wine_dbg_printf("%s", debug_writemask(assign->writemask)); - wine_dbg_printf(" "); - debug_dump_src(&assign->rhs); - wine_dbg_printf(")"); -} - -static void debug_dump_ir_swizzle(const struct hlsl_ir_swizzle *swizzle) -{ - unsigned int i; - - debug_dump_src(&swizzle->val); - wine_dbg_printf("."); - if (swizzle->val.node->data_type->dimy > 1) - { - for (i = 0; i < swizzle->node.data_type->dimx; ++i) - wine_dbg_printf("_m%u%u", (swizzle->swizzle >> i * 8) & 0xf, (swizzle->swizzle >> (i * 8 + 4)) & 0xf); - } - else - { - static const char c[] = {'x', 'y', 'z', 'w'}; - - for (i = 0; i < swizzle->node.data_type->dimx; ++i) - wine_dbg_printf("%c", c[(swizzle->swizzle >> i * 2) & 0x3]); - } -} - -static void debug_dump_ir_jump(const struct hlsl_ir_jump *jump) -{ - switch (jump->type) - { - case HLSL_IR_JUMP_BREAK: - wine_dbg_printf("break"); - break; - case HLSL_IR_JUMP_CONTINUE: - wine_dbg_printf("continue"); - break; - case HLSL_IR_JUMP_DISCARD: - wine_dbg_printf("discard"); - break; - case HLSL_IR_JUMP_RETURN: - wine_dbg_printf("return"); - break; - } -} - -static void debug_dump_ir_if(const struct hlsl_ir_if *if_node) -{ - wine_dbg_printf("if ("); - debug_dump_src(&if_node->condition); - wine_dbg_printf(")\n{\n"); - debug_dump_instr_list(&if_node->then_instrs); - wine_dbg_printf("}\nelse\n{\n"); - debug_dump_instr_list(&if_node->else_instrs); - wine_dbg_printf("}\n"); -} - -static void debug_dump_ir_loop(const struct hlsl_ir_loop *loop) -{ - wine_dbg_printf("for (;;)\n{\n"); - debug_dump_instr_list(&loop->body); - wine_dbg_printf("}\n"); -} - -static void debug_dump_instr(const struct hlsl_ir_node *instr) -{ - if (instr->index) - wine_dbg_printf("%4u: ", instr->index); - else - wine_dbg_printf("%p: ", instr); - - wine_dbg_printf("%10s | ", instr->data_type ? debug_hlsl_type(instr->data_type) : ""); - - switch (instr->type) - { - case HLSL_IR_EXPR: - debug_dump_ir_expr(expr_from_node(instr)); - break; - case HLSL_IR_LOAD: - debug_dump_deref(&load_from_node(instr)->src); - break; - case HLSL_IR_CONSTANT: - debug_dump_ir_constant(constant_from_node(instr)); - break; - case HLSL_IR_ASSIGNMENT: - debug_dump_ir_assignment(assignment_from_node(instr)); - break; - case HLSL_IR_SWIZZLE: - debug_dump_ir_swizzle(swizzle_from_node(instr)); - break; - case HLSL_IR_JUMP: - debug_dump_ir_jump(jump_from_node(instr)); - break; - case HLSL_IR_IF: - debug_dump_ir_if(if_from_node(instr)); - break; - case HLSL_IR_LOOP: - debug_dump_ir_loop(loop_from_node(instr)); - break; - default: - wine_dbg_printf("", debug_node_type(instr->type)); - } -} - -void debug_dump_ir_function_decl(const struct hlsl_ir_function_decl *func) -{ - struct hlsl_ir_var *param; - - TRACE("Dumping function %s.\n", debugstr_a(func->func->name)); - TRACE("Function parameters:\n"); - LIST_FOR_EACH_ENTRY(param, func->parameters, struct hlsl_ir_var, param_entry) - { - debug_dump_ir_var(param); - wine_dbg_printf("\n"); - } - if (func->semantic) - TRACE("Function semantic: %s\n", debugstr_a(func->semantic)); - if (func->body) - { - debug_dump_instr_list(func->body); - } -} - -void free_hlsl_type(struct hlsl_type *type) -{ - struct hlsl_struct_field *field, *next_field; - - d3dcompiler_free((void *)type->name); - if (type->type == HLSL_CLASS_STRUCT) - { - LIST_FOR_EACH_ENTRY_SAFE(field, next_field, type->e.elements, struct hlsl_struct_field, entry) - { - d3dcompiler_free((void *)field->name); - d3dcompiler_free((void *)field->semantic); - d3dcompiler_free(field); - } - } - d3dcompiler_free(type); -} - -void free_instr_list(struct list *list) -{ - struct hlsl_ir_node *node, *next_node; - - if (!list) - return; - /* Iterate in reverse, to avoid use-after-free when unlinking sources from - * the "uses" list. */ - LIST_FOR_EACH_ENTRY_SAFE_REV(node, next_node, list, struct hlsl_ir_node, entry) - free_instr(node); - d3dcompiler_free(list); -} - -static void free_ir_constant(struct hlsl_ir_constant *constant) -{ - d3dcompiler_free(constant); -} - -static void free_ir_load(struct hlsl_ir_load *load) -{ - hlsl_src_remove(&load->src.offset); - d3dcompiler_free(load); -} - -static void free_ir_swizzle(struct hlsl_ir_swizzle *swizzle) -{ - hlsl_src_remove(&swizzle->val); - d3dcompiler_free(swizzle); -} - -static void free_ir_expr(struct hlsl_ir_expr *expr) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(expr->operands); ++i) - hlsl_src_remove(&expr->operands[i]); - d3dcompiler_free(expr); -} - -static void free_ir_assignment(struct hlsl_ir_assignment *assignment) -{ - hlsl_src_remove(&assignment->rhs); - hlsl_src_remove(&assignment->lhs.offset); - d3dcompiler_free(assignment); -} - -static void free_ir_if(struct hlsl_ir_if *if_node) -{ - struct hlsl_ir_node *node, *next_node; - - LIST_FOR_EACH_ENTRY_SAFE(node, next_node, &if_node->then_instrs, struct hlsl_ir_node, entry) - free_instr(node); - LIST_FOR_EACH_ENTRY_SAFE(node, next_node, &if_node->else_instrs, struct hlsl_ir_node, entry) - free_instr(node); - hlsl_src_remove(&if_node->condition); - d3dcompiler_free(if_node); -} - -static void free_ir_loop(struct hlsl_ir_loop *loop) -{ - struct hlsl_ir_node *node, *next_node; - - LIST_FOR_EACH_ENTRY_SAFE(node, next_node, &loop->body, struct hlsl_ir_node, entry) - free_instr(node); - d3dcompiler_free(loop); -} - -static void free_ir_jump(struct hlsl_ir_jump *jump) -{ - d3dcompiler_free(jump); -} - -void free_instr(struct hlsl_ir_node *node) -{ - switch (node->type) - { - case HLSL_IR_CONSTANT: - free_ir_constant(constant_from_node(node)); - break; - case HLSL_IR_LOAD: - free_ir_load(load_from_node(node)); - break; - case HLSL_IR_SWIZZLE: - free_ir_swizzle(swizzle_from_node(node)); - break; - case HLSL_IR_EXPR: - free_ir_expr(expr_from_node(node)); - break; - case HLSL_IR_ASSIGNMENT: - free_ir_assignment(assignment_from_node(node)); - break; - case HLSL_IR_IF: - free_ir_if(if_from_node(node)); - break; - case HLSL_IR_LOOP: - free_ir_loop(loop_from_node(node)); - break; - case HLSL_IR_JUMP: - free_ir_jump(jump_from_node(node)); - break; - default: - FIXME("Unsupported node type %s\n", debug_node_type(node->type)); - } -} - -static void free_function_decl(struct hlsl_ir_function_decl *decl) -{ - d3dcompiler_free((void *)decl->semantic); - d3dcompiler_free(decl->parameters); - free_instr_list(decl->body); - d3dcompiler_free(decl); -} - -static void free_function_decl_rb(struct wine_rb_entry *entry, void *context) -{ - free_function_decl(WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry)); -} - -static void free_function(struct hlsl_ir_function *func) -{ - wine_rb_destroy(&func->overloads, free_function_decl_rb, NULL); - d3dcompiler_free((void *)func->name); - d3dcompiler_free(func); -} - -void free_function_rb(struct wine_rb_entry *entry, void *context) -{ - free_function(WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry)); -} - -void add_function_decl(struct wine_rb_tree *funcs, char *name, struct hlsl_ir_function_decl *decl, BOOL intrinsic) -{ - struct hlsl_ir_function *func; - struct wine_rb_entry *func_entry, *old_entry; - - func_entry = wine_rb_get(funcs, name); - if (func_entry) - { - func = WINE_RB_ENTRY_VALUE(func_entry, struct hlsl_ir_function, entry); - if (intrinsic != func->intrinsic) - { - if (intrinsic) - { - ERR("Redeclaring a user defined function as an intrinsic.\n"); - return; - } - TRACE("Function %s redeclared as a user defined function.\n", debugstr_a(name)); - func->intrinsic = intrinsic; - wine_rb_destroy(&func->overloads, free_function_decl_rb, NULL); - wine_rb_init(&func->overloads, compare_function_decl_rb); - } - decl->func = func; - if ((old_entry = wine_rb_get(&func->overloads, decl->parameters))) - { - struct hlsl_ir_function_decl *old_decl = - WINE_RB_ENTRY_VALUE(old_entry, struct hlsl_ir_function_decl, entry); - - if (!decl->body) - { - free_function_decl(decl); - d3dcompiler_free(name); - return; - } - wine_rb_remove(&func->overloads, old_entry); - free_function_decl(old_decl); - } - wine_rb_put(&func->overloads, decl->parameters, &decl->entry); - d3dcompiler_free(name); - return; - } - func = d3dcompiler_alloc(sizeof(*func)); - func->name = name; - wine_rb_init(&func->overloads, compare_function_decl_rb); - decl->func = func; - wine_rb_put(&func->overloads, decl->parameters, &decl->entry); - func->intrinsic = intrinsic; - wine_rb_put(funcs, func->name, &func->entry); -} -#endif diff --git a/dlls/d3dcompiler_46/Makefile.in b/dlls/d3dcompiler_46/Makefile.in index 24c9acfc014..f58176c61eb 100644 --- a/dlls/d3dcompiler_46/Makefile.in +++ b/dlls/d3dcompiler_46/Makefile.in @@ -16,12 +16,10 @@ C_SRCS = \ LEX_SRCS = \ asmshader.l \ - hlsl.l \ ppl.l BISON_SRCS = \ asmshader.y \ - hlsl.y \ ppy.y RC_SRCS = version.rc diff --git a/dlls/d3dcompiler_47/Makefile.in b/dlls/d3dcompiler_47/Makefile.in index 44bec38d8d2..30b8dc22a45 100644 --- a/dlls/d3dcompiler_47/Makefile.in +++ b/dlls/d3dcompiler_47/Makefile.in @@ -17,12 +17,10 @@ C_SRCS = \ LEX_SRCS = \ asmshader.l \ - hlsl.l \ ppl.l BISON_SRCS = \ asmshader.y \ - hlsl.y \ ppy.y RC_SRCS = version.rc