Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/d3dcompiler_43/bytecodewriter.c | 174 +++++++-------------------- 1 file changed, 44 insertions(+), 130 deletions(-)
diff --git a/dlls/d3dcompiler_43/bytecodewriter.c b/dlls/d3dcompiler_43/bytecodewriter.c index 35bd6669ef9..b1c0bb60714 100644 --- a/dlls/d3dcompiler_43/bytecodewriter.c +++ b/dlls/d3dcompiler_43/bytecodewriter.c @@ -2285,130 +2285,29 @@ static const struct bytecode_backend ps_3_backend = { ps_3_handlers };
-static void init_vs10_dx9_writer(struct bc_writer *writer) { - TRACE("Creating DirectX9 vertex shader 1.0 writer\n"); - writer->funcs = &vs_1_x_backend; -} - -static void init_vs11_dx9_writer(struct bc_writer *writer) { - TRACE("Creating DirectX9 vertex shader 1.1 writer\n"); - writer->funcs = &vs_1_x_backend; -} - -static void init_vs20_dx9_writer(struct bc_writer *writer) { - TRACE("Creating DirectX9 vertex shader 2.0 writer\n"); - writer->funcs = &vs_2_0_backend; -} - -static void init_vs2x_dx9_writer(struct bc_writer *writer) { - TRACE("Creating DirectX9 vertex shader 2.x writer\n"); - writer->funcs = &vs_2_x_backend; -} - -static void init_vs30_dx9_writer(struct bc_writer *writer) { - TRACE("Creating DirectX9 vertex shader 3.0 writer\n"); - writer->funcs = &vs_3_backend; -} - -static void init_ps10_dx9_writer(struct bc_writer *writer) { - TRACE("Creating DirectX9 pixel shader 1.0 writer\n"); - writer->funcs = &ps_1_0123_backend; -} - -static void init_ps11_dx9_writer(struct bc_writer *writer) { - TRACE("Creating DirectX9 pixel shader 1.1 writer\n"); - writer->funcs = &ps_1_0123_backend; -} - -static void init_ps12_dx9_writer(struct bc_writer *writer) { - TRACE("Creating DirectX9 pixel shader 1.2 writer\n"); - writer->funcs = &ps_1_0123_backend; -} - -static void init_ps13_dx9_writer(struct bc_writer *writer) { - TRACE("Creating DirectX9 pixel shader 1.3 writer\n"); - writer->funcs = &ps_1_0123_backend; -} - -static void init_ps14_dx9_writer(struct bc_writer *writer) { - TRACE("Creating DirectX9 pixel shader 1.4 writer\n"); - writer->funcs = &ps_1_4_backend; -} - -static void init_ps20_dx9_writer(struct bc_writer *writer) { - TRACE("Creating DirectX9 pixel shader 2.0 writer\n"); - writer->funcs = &ps_2_0_backend; -} - -static void init_ps2x_dx9_writer(struct bc_writer *writer) { - TRACE("Creating DirectX9 pixel shader 2.x writer\n"); - writer->funcs = &ps_2_x_backend; -} - -static void init_ps30_dx9_writer(struct bc_writer *writer) { - TRACE("Creating DirectX9 pixel shader 3.0 writer\n"); - writer->funcs = &ps_3_backend; -} - -static struct bc_writer *create_writer(DWORD version) +static const struct { - struct bc_writer *ret = d3dcompiler_alloc(sizeof(*ret)); - - if(!ret) { - WARN("Failed to allocate a bytecode writer instance\n"); - return NULL; - } - - switch(version) { - case BWRITERVS_VERSION(1, 0): - init_vs10_dx9_writer(ret); - break; - case BWRITERVS_VERSION(1, 1): - init_vs11_dx9_writer(ret); - break; - case BWRITERVS_VERSION(2, 0): - init_vs20_dx9_writer(ret); - break; - case BWRITERVS_VERSION(2, 1): - init_vs2x_dx9_writer(ret); - break; - case BWRITERVS_VERSION(3, 0): - init_vs30_dx9_writer(ret); - break; - case BWRITERPS_VERSION(1, 0): - init_ps10_dx9_writer(ret); - break; - case BWRITERPS_VERSION(1, 1): - init_ps11_dx9_writer(ret); - break; - case BWRITERPS_VERSION(1, 2): - init_ps12_dx9_writer(ret); - break; - case BWRITERPS_VERSION(1, 3): - init_ps13_dx9_writer(ret); - break; - case BWRITERPS_VERSION(1, 4): - init_ps14_dx9_writer(ret); - break; - case BWRITERPS_VERSION(2, 0): - init_ps20_dx9_writer(ret); - break; - case BWRITERPS_VERSION(2, 1): - init_ps2x_dx9_writer(ret); - break; - case BWRITERPS_VERSION(3, 0): - init_ps30_dx9_writer(ret); - break; - default: - WARN("Unexpected shader version requested: %08x\n", version); - goto fail; - } - return ret; - -fail: - d3dcompiler_free(ret); - return NULL; + enum shader_type type; + unsigned char major, minor; + const struct bytecode_backend *backend; } +shader_backends[] = +{ + {ST_VERTEX, 1, 0, &vs_1_x_backend}, + {ST_VERTEX, 1, 1, &vs_1_x_backend}, + {ST_VERTEX, 2, 0, &vs_2_0_backend}, + {ST_VERTEX, 2, 1, &vs_2_x_backend}, + {ST_VERTEX, 3, 0, &vs_3_backend}, + + {ST_PIXEL, 1, 0, &ps_1_0123_backend}, + {ST_PIXEL, 1, 1, &ps_1_0123_backend}, + {ST_PIXEL, 1, 2, &ps_1_0123_backend}, + {ST_PIXEL, 1, 3, &ps_1_0123_backend}, + {ST_PIXEL, 1, 4, &ps_1_4_backend}, + {ST_PIXEL, 2, 0, &ps_2_0_backend}, + {ST_PIXEL, 2, 1, &ps_2_x_backend}, + {ST_PIXEL, 3, 0, &ps_3_backend}, +};
static HRESULT call_instr_handler(struct bc_writer *writer, const struct instruction *instr, @@ -2443,17 +2342,32 @@ HRESULT shader_write_bytecode(const struct bwriter_shader *shader, DWORD **resul ERR("NULL shader structure, aborting\n"); return E_FAIL; } - writer = create_writer(sm1_version(shader)); - writer->shader = shader; - *result = NULL;
- if(!writer) { - WARN("Could not create a bytecode writer instance. Either unsupported version\n"); - WARN("or out of memory\n"); - hr = E_FAIL; - goto error; + if (!(writer = d3dcompiler_alloc(sizeof(*writer)))) + return E_OUTOFMEMORY; + + for (i = 0; i < ARRAY_SIZE(shader_backends); ++i) + { + if (shader->type == shader_backends[i].type + && shader->major_version == shader_backends[i].major + && shader->minor_version == shader_backends[i].minor) + { + writer->funcs = shader_backends[i].backend; + break; + } + } + + if (!writer->funcs) + { + FIXME("Unsupported shader type %#x, version %u.%u.\n", + shader->type, shader->major_version, shader->minor_version); + d3dcompiler_free(writer); + return E_NOTIMPL; }
+ writer->shader = shader; + *result = NULL; + buffer = allocate_buffer(); if(!buffer) { WARN("Failed to allocate a buffer for the shader bytecode\n");
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/d3dcompiler_43/bytecodewriter.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/dlls/d3dcompiler_43/bytecodewriter.c b/dlls/d3dcompiler_43/bytecodewriter.c index b1c0bb60714..39ab6a5cccf 100644 --- a/dlls/d3dcompiler_43/bytecodewriter.c +++ b/dlls/d3dcompiler_43/bytecodewriter.c @@ -592,9 +592,9 @@ static DWORD d3dsp_register( D3DSHADER_PARAM_REGISTER_TYPE type, DWORD num ) /****************************************************** * Implementation of the writer functions starts here * ******************************************************/ -static void write_declarations(struct bc_writer *This, - struct bytecode_buffer *buffer, BOOL len, - const struct declaration *decls, unsigned int num, DWORD type) { +static void write_declarations(struct bc_writer *This, struct bytecode_buffer *buffer, + const struct declaration *decls, unsigned int num, DWORD type) +{ DWORD i; DWORD instr_dcl = D3DSIO_DCL; DWORD token; @@ -602,9 +602,8 @@ static void write_declarations(struct bc_writer *This,
ZeroMemory(®, sizeof(reg));
- if(len) { + if (This->shader->major_version > 1) instr_dcl |= 2 << D3DSI_INSTLENGTH_SHIFT; - }
for(i = 0; i < num; i++) { if(decls[i].builtin) continue; @@ -759,7 +758,7 @@ static void vs_1_x_header(struct bc_writer *This, const struct bwriter_shader *s return; }
- write_declarations(This, buffer, FALSE, shader->inputs, shader->num_inputs, BWRITERSPR_INPUT); + write_declarations(This, buffer, shader->inputs, shader->num_inputs, BWRITERSPR_INPUT); write_constF(shader, buffer, FALSE); }
@@ -1569,7 +1568,7 @@ static void vs_2_header(struct bc_writer *This, return; }
- write_declarations(This, buffer, TRUE, shader->inputs, shader->num_inputs, BWRITERSPR_INPUT); + write_declarations(This, buffer, shader->inputs, shader->num_inputs, BWRITERSPR_INPUT); write_constF(shader, buffer, TRUE); write_constB(shader, buffer, TRUE); write_constI(shader, buffer, TRUE); @@ -1836,7 +1835,7 @@ static void ps_2_header(struct bc_writer *This, const struct bwriter_shader *sha return; }
- write_declarations(This, buffer, TRUE, shader->inputs, shader->num_inputs, BWRITERSPR_INPUT); + write_declarations(This, buffer, shader->inputs, shader->num_inputs, BWRITERSPR_INPUT); write_samplers(shader, buffer); write_constF(shader, buffer, TRUE); write_constB(shader, buffer, TRUE); @@ -2065,8 +2064,8 @@ static const struct bytecode_backend ps_2_x_backend = { };
static void sm_3_header(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer) { - write_declarations(This, buffer, TRUE, shader->inputs, shader->num_inputs, BWRITERSPR_INPUT); - write_declarations(This, buffer, TRUE, shader->outputs, shader->num_outputs, BWRITERSPR_OUTPUT); + write_declarations(This, buffer, shader->inputs, shader->num_inputs, BWRITERSPR_INPUT); + write_declarations(This, buffer, shader->outputs, shader->num_outputs, BWRITERSPR_OUTPUT); write_constF(shader, buffer, TRUE); write_constB(shader, buffer, TRUE); write_constI(shader, buffer, TRUE);
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/d3dcompiler_43/bytecodewriter.c | 75 +++++++++++------------ dlls/d3dcompiler_43/d3dcompiler_private.h | 8 +-- 2 files changed, 39 insertions(+), 44 deletions(-)
diff --git a/dlls/d3dcompiler_43/bytecodewriter.c b/dlls/d3dcompiler_43/bytecodewriter.c index 39ab6a5cccf..05e0ebaf2a9 100644 --- a/dlls/d3dcompiler_43/bytecodewriter.c +++ b/dlls/d3dcompiler_43/bytecodewriter.c @@ -27,6 +27,35 @@
WINE_DEFAULT_DEBUG_CHANNEL(bytecodewriter);
+static BOOL array_reserve(void **elements, unsigned int *capacity, unsigned int count, unsigned int size) +{ + unsigned int max_capacity, new_capacity; + void *new_elements; + + if (count <= *capacity) + return TRUE; + + max_capacity = ~(unsigned int)0 / size; + if (count > max_capacity) + return FALSE; + + new_capacity = max(8, *capacity); + while (new_capacity < count && new_capacity <= max_capacity / 2) + new_capacity *= 2; + if (new_capacity < count) + new_capacity = count; + + if (!(new_elements = d3dcompiler_realloc(*elements, new_capacity * size))) + { + ERR("Failed to allocate memory.\n"); + return FALSE; + } + + *elements = new_elements; + *capacity = new_capacity; + return TRUE; +} + /**************************************************************** * General assembler shader construction helper routines follow * ****************************************************************/ @@ -73,30 +102,11 @@ struct instruction *alloc_instr(unsigned int srcs) { * instr: Instruction to add to the shader */ BOOL add_instruction(struct bwriter_shader *shader, struct instruction *instr) { - struct instruction **new_instructions; - if(!shader) return FALSE;
- if(shader->instr_alloc_size == 0) { - shader->instr = d3dcompiler_alloc(sizeof(*shader->instr) * INSTRARRAY_INITIAL_SIZE); - if(!shader->instr) { - ERR("Failed to allocate the shader instruction array\n"); - return FALSE; - } - shader->instr_alloc_size = INSTRARRAY_INITIAL_SIZE; - } else if(shader->instr_alloc_size == shader->num_instrs) { - new_instructions = d3dcompiler_realloc(shader->instr, - sizeof(*shader->instr) * (shader->instr_alloc_size) * 2); - if(!new_instructions) { - ERR("Failed to grow the shader instruction array\n"); - return FALSE; - } - shader->instr = new_instructions; - shader->instr_alloc_size = shader->instr_alloc_size * 2; - } else if(shader->num_instrs > shader->instr_alloc_size) { - ERR("More instructions than allocated. This should not happen\n"); + if (!array_reserve((void **)&shader->instr, &shader->instr_alloc_size, + shader->num_instrs + 1, sizeof(*shader->instr))) return FALSE; - }
shader->instr[shader->num_instrs] = instr; shader->num_instrs++; @@ -310,13 +320,6 @@ static struct bytecode_buffer *allocate_buffer(void) {
ret = d3dcompiler_alloc(sizeof(*ret)); if(!ret) return NULL; - - ret->alloc_size = BYTECODEBUFFER_INITIAL_SIZE; - ret->data = d3dcompiler_alloc(sizeof(DWORD) * ret->alloc_size); - if(!ret->data) { - d3dcompiler_free(ret); - return NULL; - } ret->state = S_OK; return ret; } @@ -324,18 +327,12 @@ static struct bytecode_buffer *allocate_buffer(void) { static void put_dword(struct bytecode_buffer *buffer, DWORD value) { if(FAILED(buffer->state)) return;
- if(buffer->alloc_size == buffer->size) { - DWORD *newarray; - buffer->alloc_size *= 2; - newarray = d3dcompiler_realloc(buffer->data, - sizeof(DWORD) * buffer->alloc_size); - if(!newarray) { - ERR("Failed to grow the buffer data memory\n"); - buffer->state = E_OUTOFMEMORY; - return; - } - buffer->data = newarray; + if (!array_reserve((void **)&buffer->data, &buffer->alloc_size, buffer->size + 1, sizeof(*buffer->data))) + { + buffer->state = E_OUTOFMEMORY; + return; } + buffer->data[buffer->size++] = value; }
diff --git a/dlls/d3dcompiler_43/d3dcompiler_private.h b/dlls/d3dcompiler_43/d3dcompiler_private.h index b9caf595804..ee9e705d75a 100644 --- a/dlls/d3dcompiler_43/d3dcompiler_private.h +++ b/dlls/d3dcompiler_43/d3dcompiler_private.h @@ -115,7 +115,6 @@ struct samplerdecl { DWORD mod; };
-#define INSTRARRAY_INITIAL_SIZE 8 struct bwriter_shader { enum shader_type type; unsigned char major_version, minor_version; @@ -149,6 +148,8 @@ static inline void *d3dcompiler_alloc(SIZE_T size)
static inline void *d3dcompiler_realloc(void *ptr, SIZE_T size) { + if (!ptr) + return d3dcompiler_alloc(size); return HeapReAlloc(GetProcessHeap(), 0, ptr, size); }
@@ -293,12 +294,9 @@ static inline void set_parse_status(enum parse_status *current, enum parse_statu *current = PARSE_WARN; }
-/* A reasonable value as initial size */ -#define BYTECODEBUFFER_INITIAL_SIZE 32 struct bytecode_buffer { DWORD *data; - DWORD size; - DWORD alloc_size; + unsigned int size, alloc_size; /* For tracking rare out of memory situations without passing * return values around everywhere */
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
On Thu, Mar 26, 2020 at 5:29 AM Zebediah Figura z.figura12@gmail.com wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
dlls/d3dcompiler_43/bytecodewriter.c | 75 +++++++++++------------ dlls/d3dcompiler_43/d3dcompiler_private.h | 8 +-- 2 files changed, 39 insertions(+), 44 deletions(-)
diff --git a/dlls/d3dcompiler_43/bytecodewriter.c b/dlls/d3dcompiler_43/bytecodewriter.c index 39ab6a5cccf..05e0ebaf2a9 100644 --- a/dlls/d3dcompiler_43/bytecodewriter.c +++ b/dlls/d3dcompiler_43/bytecodewriter.c @@ -27,6 +27,35 @@
WINE_DEFAULT_DEBUG_CHANNEL(bytecodewriter);
+static BOOL array_reserve(void **elements, unsigned int *capacity, unsigned int count, unsigned int size) +{
- unsigned int max_capacity, new_capacity;
- void *new_elements;
- if (count <= *capacity)
return TRUE;
- max_capacity = ~(unsigned int)0 / size;
I think you can use ~0u since you're now using unsigned int here (which I agree is a good change for d3dcompiler).
@@ -73,30 +102,11 @@ struct instruction *alloc_instr(unsigned int srcs) {
- instr: Instruction to add to the shader
*/ BOOL add_instruction(struct bwriter_shader *shader, struct instruction *instr) {
- struct instruction **new_instructions;
- if(!shader) return FALSE;
I assume you're going to touch (or get rid of) this function in the future but, in general, feel free to fix up formatting.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/d3dcompiler_43/bytecodewriter.c | 46 +++++++++++++++++++ dlls/d3dcompiler_43/d3dcompiler_private.h | 55 ----------------------- 2 files changed, 46 insertions(+), 55 deletions(-)
diff --git a/dlls/d3dcompiler_43/bytecodewriter.c b/dlls/d3dcompiler_43/bytecodewriter.c index 05e0ebaf2a9..32eeb8be97f 100644 --- a/dlls/d3dcompiler_43/bytecodewriter.c +++ b/dlls/d3dcompiler_43/bytecodewriter.c @@ -308,6 +308,52 @@ BOOL record_sampler(struct bwriter_shader *shader, DWORD samptype, DWORD mod, DW return TRUE; }
+struct bytecode_buffer +{ + DWORD *data; + unsigned int size, alloc_size; + HRESULT state; +}; + +struct bc_writer; + +typedef void (*instr_writer)(struct bc_writer *writer, const struct instruction *instr, + struct bytecode_buffer *buffer); + +struct bytecode_backend +{ + void (*header)(struct bc_writer *writer, const struct bwriter_shader *shader, + struct bytecode_buffer *buffer); + void (*end)(struct bc_writer *writer, const struct bwriter_shader *shader, + struct bytecode_buffer *buffer); + void (*srcreg)(struct bc_writer *writer, const struct shader_reg *reg, + struct bytecode_buffer *buffer); + void (*dstreg)(struct bc_writer *writer, const struct shader_reg *reg, + struct bytecode_buffer *buffer, DWORD shift, DWORD mod); + void (*opcode)(struct bc_writer *writer, const struct instruction *instr, + DWORD token, struct bytecode_buffer *buffer); + + const struct instr_handler_table + { + DWORD opcode; + instr_writer func; + } *instructions; +}; + +struct bc_writer +{ + const struct bytecode_backend *funcs; + const struct bwriter_shader *shader; + + HRESULT state; + + /* Vertex shader varying mapping. */ + DWORD oPos_regnum, oD_regnum[2], oT_regnum[8], oFog_regnum, oFog_mask, oPts_regnum, oPts_mask; + + /* Pixel shader varying mapping. */ + DWORD t_regnum[8], v_regnum[2]; +}; +
/* shader bytecode buffer manipulation functions. * allocate_buffer creates a new buffer structure, put_dword adds a new diff --git a/dlls/d3dcompiler_43/d3dcompiler_private.h b/dlls/d3dcompiler_43/d3dcompiler_private.h index ee9e705d75a..2a926282128 100644 --- a/dlls/d3dcompiler_43/d3dcompiler_private.h +++ b/dlls/d3dcompiler_43/d3dcompiler_private.h @@ -294,61 +294,6 @@ static inline void set_parse_status(enum parse_status *current, enum parse_statu *current = PARSE_WARN; }
-struct bytecode_buffer { - DWORD *data; - unsigned int size, alloc_size; - /* For tracking rare out of memory situations without passing - * return values around everywhere - */ - HRESULT state; -}; - -struct bc_writer; /* Predeclaration for use in vtable parameters */ - -typedef void (*instr_writer)(struct bc_writer *This, - const struct instruction *instr, - struct bytecode_buffer *buffer); - -struct bytecode_backend { - void (*header)(struct bc_writer *This, const struct bwriter_shader *shader, - struct bytecode_buffer *buffer); - void (*end)(struct bc_writer *This, const struct bwriter_shader *shader, - struct bytecode_buffer *buffer); - void (*srcreg)(struct bc_writer *This, const struct shader_reg *reg, - struct bytecode_buffer *buffer); - void (*dstreg)(struct bc_writer *This, const struct shader_reg *reg, - struct bytecode_buffer *buffer, DWORD shift, DWORD mod); - void (*opcode)(struct bc_writer *This, const struct instruction *instr, - DWORD token, struct bytecode_buffer *buffer); - - const struct instr_handler_table { - DWORD opcode; - instr_writer func; - } *instructions; -}; - -/* Bytecode writing stuff */ -struct bc_writer { - const struct bytecode_backend *funcs; - const struct bwriter_shader *shader; - - /* Avoid result checking */ - HRESULT state; - - /* Vertex shader varying mapping */ - DWORD oPos_regnum; - DWORD oD_regnum[2]; - DWORD oT_regnum[8]; - DWORD oFog_regnum; - DWORD oFog_mask; - DWORD oPts_regnum; - DWORD oPts_mask; - - /* Pixel shader specific members */ - DWORD t_regnum[8]; - DWORD v_regnum[2]; -}; - /* Debug utility routines */ const char *debug_print_srcmod(DWORD mod) DECLSPEC_HIDDEN; const char *debug_print_dstmod(DWORD mod) DECLSPEC_HIDDEN;
Signed-off-by: Matteo Bruni mbruni@codeweavers.com