Signed-off-by: Atharva Nimbalkar atharvakn@gmail.com --- include/vkd3d_shader.h | 4 ++++ libs/vkd3d-shader/vkd3d_shader_main.c | 10 ++++++++++ libs/vkd3d-shader/vkd3d_shader_private.h | 2 ++ programs/vkd3d-compiler/main.c | 3 +++ 4 files changed, 19 insertions(+)
diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h index 5092fac..58e507b 100644 --- a/include/vkd3d_shader.h +++ b/include/vkd3d_shader.h @@ -491,6 +491,10 @@ enum vkd3d_shader_target_type * the format used for Direct3D shader model 4 and 5 shaders. */ VKD3D_SHADER_TARGET_DXBC_TPF, + /** + * An 'OpenGL Shading Language' shader. + */ + VKD3D_SHADER_TARGET_GLSL,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_TARGET_TYPE), }; diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index 78312a1..a9b5d0a 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -1032,6 +1032,15 @@ static int compile_dxbc_tpf(const struct vkd3d_shader_compile_info *compile_info return ret; }
+ if (compile_info->target_type == VKD3D_SHADER_TARGET_GLSL) + { + vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_GLSL_INTERNAL, + "Internal compiler error: Unhandled instruction."); + vkd3d_shader_parser_destroy(&parser); + vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info); + return VKD3D_ERROR; + } + if (!(spirv_compiler = vkd3d_dxbc_compiler_create(&parser.shader_version, &parser.shader_desc, compile_info, &scan_descriptor_info, message_context))) { @@ -1280,6 +1289,7 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( VKD3D_SHADER_TARGET_SPIRV_TEXT, #endif VKD3D_SHADER_TARGET_D3D_ASM, + VKD3D_SHADER_TARGET_GLSL, };
static const enum vkd3d_shader_target_type hlsl_types[] = diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 8550380..b490b9c 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -115,6 +115,8 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_HLSL_NOT_IMPLEMENTED = 5017,
VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION = 5300, + + VKD3D_SHADER_ERROR_GLSL_INTERNAL = 6000, };
enum vkd3d_shader_opcode diff --git a/programs/vkd3d-compiler/main.c b/programs/vkd3d-compiler/main.c index fb19a70..71f90f8 100644 --- a/programs/vkd3d-compiler/main.c +++ b/programs/vkd3d-compiler/main.c @@ -90,6 +90,9 @@ target_type_info[] = "dxbc-tpf", "A 'Tokenized Program Format' shader embedded in a DXBC container.\n" " This is the format used for Direct3D shader model 4 and 5 shaders.\n", true}, + {VKD3D_SHADER_TARGET_GLSL, + "glsl", "An 'OpenGL Shading Language' shader.\n", + false} };
static bool read_shader(struct vkd3d_shader_code *shader, FILE *f)
Signed-off-by: Atharva Nimbalkar atharvakn@gmail.com --- Makefile.am | 1 + libs/vkd3d-shader/glsl.c | 118 +++++++++++++++++++++++ libs/vkd3d-shader/vkd3d_shader_main.c | 17 +++- libs/vkd3d-shader/vkd3d_shader_private.h | 9 ++ 4 files changed, 142 insertions(+), 3 deletions(-) create mode 100644 libs/vkd3d-shader/glsl.c
diff --git a/Makefile.am b/Makefile.am index 9624485..18ba0fa 100644 --- a/Makefile.am +++ b/Makefile.am @@ -169,6 +169,7 @@ libvkd3d_shader_la_SOURCES = \ include/vkd3d_shader.h \ libs/vkd3d-shader/checksum.c \ libs/vkd3d-shader/dxbc.c \ + libs/vkd3d-shader/glsl.c \ libs/vkd3d-shader/hlsl.c \ libs/vkd3d-shader/hlsl.h \ libs/vkd3d-shader/hlsl_codegen.c \ diff --git a/libs/vkd3d-shader/glsl.c b/libs/vkd3d-shader/glsl.c new file mode 100644 index 0000000..cb67bb0 --- /dev/null +++ b/libs/vkd3d-shader/glsl.c @@ -0,0 +1,118 @@ +/* + * Copyright 2021 Atharva Nimbalkar + * + * 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 "vkd3d_shader_private.h" + +struct vkd3d_glsl_generator +{ + struct vkd3d_string_buffer buffer; + struct vkd3d_shader_location location; + struct vkd3d_shader_message_context *message_context; + bool failed; +}; + +struct vkd3d_glsl_generator *vkd3d_glsl_generator_create(const struct vkd3d_shader_compile_info *compile_info, + struct vkd3d_shader_message_context *message_context) +{ + struct vkd3d_glsl_generator *generator; + + if (!(generator = vkd3d_malloc(sizeof(*generator)))) + return NULL; + + memset(generator, 0, sizeof(*generator)); + generator->location.source_name = compile_info->source_name; + generator->location.line = 2; /* Line 1 is the version token. */ + generator->message_context = message_context; + return generator; +} + +static void VKD3D_PRINTF_FUNC(3, 4) vkd3d_glsl_compiler_error( + struct vkd3d_glsl_generator *generator, + enum vkd3d_shader_error error, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vkd3d_shader_error(generator->message_context, &generator->location, error, fmt, args); + va_end(args); + generator->failed = true; + return; +} + +static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *generator, + const struct vkd3d_shader_instruction *instruction) +{ + switch (instruction->handler_idx) + { + default: + vkd3d_glsl_compiler_error(generator, + VKD3D_SHADER_ERROR_GLSL_INTERNAL, + "Unhandled instruction %#x", instruction->handler_idx); + break; + } + + ++generator->location.line; + return; +} + +int vkd3d_glsl_generator_generate(void *parser_data, const uint32_t *parser_ptr, + struct vkd3d_glsl_generator *generator, + struct vkd3d_shader_code *out) +{ + void *code; + struct vkd3d_shader_instruction ins; + + vkd3d_string_buffer_printf(&generator->buffer, "#version 440\n\n"); + vkd3d_string_buffer_printf(&generator->buffer, "void main()\n{\n"); + + while (!shader_sm4_is_end(parser_data, &parser_ptr)) + { + shader_sm4_read_instruction(parser_data, &parser_ptr, &ins); + + if (ins.handler_idx == VKD3DSIH_INVALID) + { + vkd3d_glsl_compiler_error(generator, + VKD3D_SHADER_ERROR_GLSL_INTERNAL, + "Encountered unrecognized or invalid instruction."); + break; + } + + vkd3d_glsl_handle_instruction(generator, &ins); + } + + if (generator->failed) + return VKD3D_ERROR; + + vkd3d_string_buffer_printf(&generator->buffer, "}\n"); + + if ((code = vkd3d_malloc(generator->buffer.buffer_size))) + { + memcpy(code, generator->buffer.buffer, generator->buffer.content_size); + out->size = generator->buffer.content_size; + out->code = code; + } + else return VKD3D_ERROR_OUT_OF_MEMORY; + + return VKD3D_OK; +} + +void vkd3d_glsl_generator_destroy(struct vkd3d_glsl_generator *generator) +{ + vkd3d_string_buffer_cleanup(&generator->buffer); + vkd3d_free(generator); +} diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index a9b5d0a..d2182e1 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -1034,11 +1034,22 @@ static int compile_dxbc_tpf(const struct vkd3d_shader_compile_info *compile_info
if (compile_info->target_type == VKD3D_SHADER_TARGET_GLSL) { - vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_GLSL_INTERNAL, - "Internal compiler error: Unhandled instruction."); + struct vkd3d_glsl_generator *glsl_generator; + + if (!(glsl_generator = vkd3d_glsl_generator_create(compile_info, message_context))) + { + ERR("Failed to create GLSL generator.\n"); + vkd3d_shader_parser_destroy(&parser); + vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info); + return VKD3D_ERROR; + } + + ret = vkd3d_glsl_generator_generate(parser.data, parser.ptr, glsl_generator, out); + + vkd3d_glsl_generator_destroy(glsl_generator); vkd3d_shader_parser_destroy(&parser); vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info); - return VKD3D_ERROR; + return ret; }
if (!(spirv_compiler = vkd3d_dxbc_compiler_create(&parser.shader_version, diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index b490b9c..3863797 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -984,6 +984,15 @@ void free_shader_desc(struct vkd3d_shader_desc *desc); int shader_parse_input_signature(const void *dxbc, size_t dxbc_length, struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_signature *signature);
+struct vkd3d_glsl_generator; + +struct vkd3d_glsl_generator *vkd3d_glsl_generator_create(const struct vkd3d_shader_compile_info *compile_info, + struct vkd3d_shader_message_context *message_context); +int vkd3d_glsl_generator_generate(void *parser_data, const uint32_t *parser_ptr, + struct vkd3d_glsl_generator *generator, + struct vkd3d_shader_code *out); +void vkd3d_glsl_generator_destroy(struct vkd3d_glsl_generator *generator); + struct vkd3d_dxbc_compiler;
struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader_version *shader_version,
On Wed, 18 Aug 2021 at 06:20, Atharva Nimbalkar atharvakn@gmail.com wrote:
+static void VKD3D_PRINTF_FUNC(3, 4) vkd3d_glsl_compiler_error(
struct vkd3d_glsl_generator *generator,
enum vkd3d_shader_error error, const char *fmt, ...)
+{
- va_list args;
- va_start(args, fmt);
- vkd3d_shader_error(generator->message_context, &generator->location, error, fmt, args);
- va_end(args);
- generator->failed = true;
- return;
+}
That doesn't quite do the right thing. You should use vkd3d_shader_verror() instead of vkd3d_shader_error() here, so that "args" is interpreted as an argument list instead of matching against the first argument in the format string.
Signed-off-by: Atharva Nimbalkar atharvakn@gmail.com --- libs/vkd3d-shader/glsl.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/libs/vkd3d-shader/glsl.c b/libs/vkd3d-shader/glsl.c index cb67bb0..4247c20 100644 --- a/libs/vkd3d-shader/glsl.c +++ b/libs/vkd3d-shader/glsl.c @@ -59,6 +59,8 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *generator { switch (instruction->handler_idx) { + case VKD3DSIH_DCL_INPUT: + break; default: vkd3d_glsl_compiler_error(generator, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=95804
Your paranoid android.
=== debiant2 (build log) ===
Task: Patch failed to apply
=== debiant2 (build log) ===
Task: Patch failed to apply
Signed-off-by: Atharva Nimbalkar atharvakn@gmail.com --- libs/vkd3d-shader/glsl.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/libs/vkd3d-shader/glsl.c b/libs/vkd3d-shader/glsl.c index 4247c20..ee2acdb 100644 --- a/libs/vkd3d-shader/glsl.c +++ b/libs/vkd3d-shader/glsl.c @@ -60,6 +60,7 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *generator switch (instruction->handler_idx) { case VKD3DSIH_DCL_INPUT: + case VKD3DSIH_DCL_OUTPUT_SIV: break; default: vkd3d_glsl_compiler_error(generator,
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=95805
Your paranoid android.
=== debiant2 (build log) ===
Task: Patch failed to apply
=== debiant2 (build log) ===
Task: Patch failed to apply
Signed-off-by: Atharva Nimbalkar atharvakn@gmail.com --- libs/vkd3d-shader/glsl.c | 23 ++++++++++++++++++++++- libs/vkd3d-shader/vkd3d_shader_main.c | 2 +- libs/vkd3d-shader/vkd3d_shader_private.h | 3 ++- 3 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/libs/vkd3d-shader/glsl.c b/libs/vkd3d-shader/glsl.c index ee2acdb..d34b5e8 100644 --- a/libs/vkd3d-shader/glsl.c +++ b/libs/vkd3d-shader/glsl.c @@ -20,13 +20,15 @@
struct vkd3d_glsl_generator { + struct vkd3d_shader_version version; struct vkd3d_string_buffer buffer; struct vkd3d_shader_location location; struct vkd3d_shader_message_context *message_context; bool failed; };
-struct vkd3d_glsl_generator *vkd3d_glsl_generator_create(const struct vkd3d_shader_compile_info *compile_info, +struct vkd3d_glsl_generator *vkd3d_glsl_generator_create(const struct vkd3d_shader_version *version, + const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context) { struct vkd3d_glsl_generator *generator; @@ -35,6 +37,7 @@ struct vkd3d_glsl_generator *vkd3d_glsl_generator_create(const struct vkd3d_shad return NULL;
memset(generator, 0, sizeof(*generator)); + generator->version = *version; generator->location.source_name = compile_info->source_name; generator->location.line = 2; /* Line 1 is the version token. */ generator->message_context = message_context; @@ -54,6 +57,21 @@ static void VKD3D_PRINTF_FUNC(3, 4) vkd3d_glsl_compiler_error( return; }
+static void shader_glsl_ret(struct vkd3d_glsl_generator *generator, + const struct vkd3d_shader_instruction *ins) +{ + const struct vkd3d_shader_version *version = &generator->version; + + /* + * TODO: Implement in_subroutine + * TODO: shader_glsl_generate_shader_epilogue(generator); + */ + if (version->major >= 4) + { + vkd3d_string_buffer_printf(&generator->buffer, "return;\n"); + } +} + static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *generator, const struct vkd3d_shader_instruction *instruction) { @@ -62,6 +80,9 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *generator case VKD3DSIH_DCL_INPUT: case VKD3DSIH_DCL_OUTPUT_SIV: break; + case VKD3DSIH_RET: + shader_glsl_ret(generator, instruction); + break; default: vkd3d_glsl_compiler_error(generator, VKD3D_SHADER_ERROR_GLSL_INTERNAL, diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index d2182e1..16994d2 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -1036,7 +1036,7 @@ static int compile_dxbc_tpf(const struct vkd3d_shader_compile_info *compile_info { struct vkd3d_glsl_generator *glsl_generator;
- if (!(glsl_generator = vkd3d_glsl_generator_create(compile_info, message_context))) + if (!(glsl_generator = vkd3d_glsl_generator_create(&parser.shader_version, compile_info, message_context))) { ERR("Failed to create GLSL generator.\n"); vkd3d_shader_parser_destroy(&parser); diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 3863797..9efa598 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -986,7 +986,8 @@ int shader_parse_input_signature(const void *dxbc, size_t dxbc_length,
struct vkd3d_glsl_generator;
-struct vkd3d_glsl_generator *vkd3d_glsl_generator_create(const struct vkd3d_shader_compile_info *compile_info, +struct vkd3d_glsl_generator *vkd3d_glsl_generator_create(const struct vkd3d_shader_version *version, + const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context); int vkd3d_glsl_generator_generate(void *parser_data, const uint32_t *parser_ptr, struct vkd3d_glsl_generator *generator,
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=95806
Your paranoid android.
=== debiant2 (build log) ===
Task: Patch failed to apply
=== debiant2 (build log) ===
Task: Patch failed to apply
Signed-off-by: Atharva Nimbalkar atharvakn@gmail.com --- libs/vkd3d-shader/glsl.c | 234 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 234 insertions(+)
diff --git a/libs/vkd3d-shader/glsl.c b/libs/vkd3d-shader/glsl.c index d34b5e8..75b7bbc 100644 --- a/libs/vkd3d-shader/glsl.c +++ b/libs/vkd3d-shader/glsl.c @@ -18,15 +18,60 @@
#include "vkd3d_shader_private.h"
+struct glsl_src_param +{ + struct vkd3d_string_buffer *param_str; +}; + +struct glsl_dst_param +{ + struct vkd3d_string_buffer *reg_name; + struct vkd3d_string_buffer *mask_str; +}; + +static const char * const shift_glsl_tab[] = +{ + "", /* 0 (none) */ + "2.0 * ", /* 1 (x2) */ + "4.0 * ", /* 2 (x4) */ + "8.0 * ", /* 3 (x8) */ + "16.0 * ", /* 4 (x16) */ + "32.0 * ", /* 5 (x32) */ + "", /* 6 (x64) */ + "", /* 7 (x128) */ + "", /* 8 (d256) */ + "", /* 9 (d128) */ + "", /* 10 (d64) */ + "", /* 11 (d32) */ + "0.0625 * ", /* 12 (d16) */ + "0.125 * ", /* 13 (d8) */ + "0.25 * ", /* 14 (d4) */ + "0.5 * " /* 15 (d2) */ +}; + struct vkd3d_glsl_generator { struct vkd3d_shader_version version; struct vkd3d_string_buffer buffer; struct vkd3d_shader_location location; + struct vkd3d_string_buffer_cache string_buffers; struct vkd3d_shader_message_context *message_context; bool failed; };
+static void glsl_dst_param_cleanup(struct glsl_dst_param *dst, + struct vkd3d_string_buffer_cache *buffers) +{ + vkd3d_string_buffer_release(buffers, dst->mask_str); + vkd3d_string_buffer_release(buffers, dst->reg_name); +} + +static void glsl_src_param_cleanup(struct glsl_src_param *src, + struct vkd3d_string_buffer_cache *buffers) +{ + vkd3d_string_buffer_release(buffers, src->param_str); +} + struct vkd3d_glsl_generator *vkd3d_glsl_generator_create(const struct vkd3d_shader_version *version, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context) @@ -41,6 +86,8 @@ struct vkd3d_glsl_generator *vkd3d_glsl_generator_create(const struct vkd3d_shad generator->location.source_name = compile_info->source_name; generator->location.line = 2; /* Line 1 is the version token. */ generator->message_context = message_context; + vkd3d_string_buffer_cache_init(&generator->string_buffers); + return generator; }
@@ -72,6 +119,189 @@ static void shader_glsl_ret(struct vkd3d_glsl_generator *generator, } }
+static bool shader_is_scalar(const struct vkd3d_shader_register *reg) +{ + switch (reg->type) + { + case VKD3DSPR_RASTOUT: + /* oFog & oPts */ + if (reg->idx[0].offset) + return true; + /* oPos */ + return false; + + case VKD3DSPR_CONSTBOOL: /* b# */ + case VKD3DSPR_DEPTHOUT: /* oDepth */ + case VKD3DSPR_DEPTHOUTGE: + case VKD3DSPR_DEPTHOUTLE: + case VKD3DSPR_LOOP: /* aL */ + case VKD3DSPR_OUTPOINTID: + case VKD3DSPR_PREDICATE: /* p0 */ + case VKD3DSPR_PRIMID: /* primID */ + case VKD3DSPR_COVERAGE: /* vCoverage */ + case VKD3DSPR_SAMPLEMASK: /* oMask */ + return true; + + case VKD3DSPR_MISCTYPE: + switch (reg->idx[0].offset) + { + case 0: /* vPos */ + return false; + case 1: /* vFace */ + return true; + default: + return false; + } + + case VKD3DSPR_IMMCONST: + return reg->immconst_type == VKD3D_IMMCONST_SCALAR; + + default: + return false; + } +} + +static void shader_glsl_print_write_mask(uint32_t write_mask, struct vkd3d_string_buffer *str) +{ + vkd3d_string_buffer_printf(str, "."); + if (write_mask & VKD3DSP_WRITEMASK_0) vkd3d_string_buffer_printf(str, "x"); + if (write_mask & VKD3DSP_WRITEMASK_1) vkd3d_string_buffer_printf(str, "y"); + if (write_mask & VKD3DSP_WRITEMASK_2) vkd3d_string_buffer_printf(str, "z"); + if (write_mask & VKD3DSP_WRITEMASK_3) vkd3d_string_buffer_printf(str, "w"); +} + +/* Get the GLSL write mask for the destination register */ +static uint32_t shader_glsl_get_write_mask(const struct vkd3d_shader_dst_param *param, + struct vkd3d_string_buffer *write_mask) +{ + uint32_t mask = param->write_mask; + + if (shader_is_scalar(¶m->reg)) + { + return VKD3DSP_WRITEMASK_0; + } + + shader_glsl_print_write_mask(mask, write_mask); + return mask; +} + +static void glsl_src_param_init_ext(struct vkd3d_glsl_generator *gen, + const struct vkd3d_shader_src_param *vkd3d_src, uint32_t mask, struct glsl_src_param *glsl_src, + enum vkd3d_data_type data_type); + +/* Writes the GLSL variable name that corresponds to the register that the + * DX opcode parameter is trying to access */ +static void shader_glsl_get_register_name(struct vkd3d_glsl_generator *gen, + const struct vkd3d_shader_register *reg, enum vkd3d_data_type data_type, + struct vkd3d_string_buffer *register_name, bool *is_swizzled) +{ + /* TODO: Add implementation + * Sets an error state as of now + */ + if(is_swizzled) + *is_swizzled = false; + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, + "Internal compiler error: Unhandled register type %#x.", reg->type); +} + +/* From a given parameter token, generate the corresponding GLSL string. + * Also, return the actual register name and swizzle in case the + * caller needs this information as well. */ +static void glsl_src_param_init_ext(struct vkd3d_glsl_generator *gen, + const struct vkd3d_shader_src_param *vkd3d_src, uint32_t mask, struct glsl_src_param *glsl_src, + enum vkd3d_data_type data_type) +{ + /* + * TODO: Add implementation + * Sets an error state as of now. + */ + + glsl_src->param_str = vkd3d_string_buffer_get(&gen->string_buffers); + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, + "Internal compiler error: Unhandled parameter token."); +} + +static void glsl_src_param_init(struct vkd3d_glsl_generator *gen, + const struct vkd3d_shader_src_param *vkd3d_src, uint32_t mask, + struct glsl_src_param *glsl_src) +{ + glsl_src_param_init_ext(gen, vkd3d_src, mask, glsl_src, vkd3d_src->reg.data_type); +} + +/* From a given parameter token, generate the corresponding GLSL string. + * Also, return the actual register name and swizzle in case the + * caller needs this information as well. */ +static uint32_t glsl_dst_param_init(struct vkd3d_glsl_generator *gen, + const struct vkd3d_shader_dst_param *vkd3d_dst, struct glsl_dst_param *glsl_dst) +{ + glsl_dst->mask_str = vkd3d_string_buffer_get(&gen->string_buffers); + glsl_dst->reg_name = vkd3d_string_buffer_get(&gen->string_buffers); + shader_glsl_get_register_name(gen, &vkd3d_dst->reg, vkd3d_dst->reg.data_type, glsl_dst->reg_name, NULL); + return shader_glsl_get_write_mask(vkd3d_dst, glsl_dst->mask_str); +} + +/* Append the destination part of the instruction to the buffer, return the effective write mask */ +static void shader_glsl_append_dst(struct vkd3d_glsl_generator *gen, + struct vkd3d_string_buffer *buffer, + const struct vkd3d_shader_instruction *ins, + struct glsl_dst_param *dst_param) +{ + if (ins->flags & VKD3DSI_PRECISE_XYZW) + vkd3d_string_buffer_printf(dst_param->reg_name, "tmp_precise[%u]", 0); + + switch (ins->dst[0].reg.data_type) + { + case VKD3D_DATA_FLOAT: + vkd3d_string_buffer_printf(buffer, "%s%s = %s(", + dst_param->reg_name->buffer, dst_param->mask_str->buffer, shift_glsl_tab[ins->dst[0].shift]); + break; + default: + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, + "Unhandled data type %#x.", ins->dst[0].reg.data_type); + vkd3d_string_buffer_printf(buffer, "%s%s = %s(", + dst_param->reg_name->buffer, dst_param->mask_str->buffer, shift_glsl_tab[ins->dst[0].shift]); + break; + } +} + +static void VKD3D_PRINTF_FUNC(4, 5) shader_glsl_print_assignment(struct vkd3d_glsl_generator *gen, + const struct vkd3d_shader_instruction *ins, + struct glsl_dst_param *dst_param, + const char *fmt, ...) +{ + va_list args; + + shader_glsl_append_dst(gen, &gen->buffer, ins, dst_param); + va_start(args, fmt); + vkd3d_string_buffer_vprintf(&gen->buffer, fmt, args); + va_end(args); +} + +static void shader_glsl_cast(struct vkd3d_glsl_generator *gen, + const struct vkd3d_shader_instruction *ins, + const char *vector_constructor, const char *scalar_constructor) +{ + struct glsl_src_param src_param; + struct glsl_dst_param dst_param; + + unsigned int write_mask = glsl_dst_param_init(gen, &ins->dst[0], &dst_param); + uint32_t mask_size = vkd3d_write_mask_component_count(write_mask); + glsl_src_param_init(gen, &ins->src[0], write_mask, &src_param); + if (mask_size > 1) + shader_glsl_print_assignment(gen, ins, &dst_param, "%s%u(%s));\n", vector_constructor, mask_size, src_param.param_str->buffer); + else + shader_glsl_print_assignment(gen, ins, &dst_param, "%s(%s));\n", scalar_constructor, src_param.param_str->buffer); + + glsl_src_param_cleanup(&src_param, &gen->string_buffers); + glsl_dst_param_cleanup(&dst_param, &gen->string_buffers); +} + +static void shader_glsl_to_float(struct vkd3d_glsl_generator *gen, + const struct vkd3d_shader_instruction *ins) +{ + shader_glsl_cast(gen, ins, "vec", "float"); +} + static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *generator, const struct vkd3d_shader_instruction *instruction) { @@ -80,6 +310,9 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *generator case VKD3DSIH_DCL_INPUT: case VKD3DSIH_DCL_OUTPUT_SIV: break; + case VKD3DSIH_ITOF: + shader_glsl_to_float(generator, instruction); + break; case VKD3DSIH_RET: shader_glsl_ret(generator, instruction); break; @@ -138,5 +371,6 @@ int vkd3d_glsl_generator_generate(void *parser_data, const uint32_t *parser_ptr, void vkd3d_glsl_generator_destroy(struct vkd3d_glsl_generator *generator) { vkd3d_string_buffer_cleanup(&generator->buffer); + vkd3d_string_buffer_cache_cleanup(&generator->string_buffers); vkd3d_free(generator); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=95807
Your paranoid android.
=== debiant2 (build log) ===
Task: Patch failed to apply
=== debiant2 (build log) ===
Task: Patch failed to apply
On Wed, 18 Aug 2021 at 06:20, Atharva Nimbalkar atharvakn@gmail.com wrote:
+/* Writes the GLSL variable name that corresponds to the register that the
- DX opcode parameter is trying to access */
+static void shader_glsl_get_register_name(struct vkd3d_glsl_generator *gen,
const struct vkd3d_shader_register *reg, enum vkd3d_data_type data_type,
struct vkd3d_string_buffer *register_name, bool *is_swizzled)
+{
- /* TODO: Add implementation
* Sets an error state as of now
*/
- if(is_swizzled)
*is_swizzled = false;
- vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
"Internal compiler error: Unhandled register type %#x.", reg->type);
+}
There's a missing space between "if" and "is_swizzled".
+/* Append the destination part of the instruction to the buffer, return the effective write mask */ +static void shader_glsl_append_dst(struct vkd3d_glsl_generator *gen,
struct vkd3d_string_buffer *buffer,
const struct vkd3d_shader_instruction *ins,
struct glsl_dst_param *dst_param)
+{
- if (ins->flags & VKD3DSI_PRECISE_XYZW)
vkd3d_string_buffer_printf(dst_param->reg_name, "tmp_precise[%u]", 0);
That doesn't quite do the right thing. vkd3d_string_buffer_printf() appends to the existing buffer, it doesn't replace it. More, we don't actually want to modify "dst_param" here. The right thing to do would probably be to handle VKD3DSI_PRECISE_XYZW in shader_glsl_print_assignment() instead of here, but there's also no need to handle VKD3DSI_PRECISE_XYZW in this patch, so it's best deferred until a later patch.
- switch (ins->dst[0].reg.data_type)
- {
case VKD3D_DATA_FLOAT:
vkd3d_string_buffer_printf(buffer, "%s%s = %s(",
dst_param->reg_name->buffer, dst_param->mask_str->buffer, shift_glsl_tab[ins->dst[0].shift]);
break;
default:
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
"Unhandled data type %#x.", ins->dst[0].reg.data_type);
vkd3d_string_buffer_printf(buffer, "%s%s = %s(",
dst_param->reg_name->buffer, dst_param->mask_str->buffer, shift_glsl_tab[ins->dst[0].shift]);
break;
- }
+}
8-space (i.e., double) indent for line continuations, please.
+static void shader_glsl_cast(struct vkd3d_glsl_generator *gen,
const struct vkd3d_shader_instruction *ins,
const char *vector_constructor, const char *scalar_constructor)
+{
- struct glsl_src_param src_param;
- struct glsl_dst_param dst_param;
- unsigned int write_mask = glsl_dst_param_init(gen, &ins->dst[0], &dst_param);
- uint32_t mask_size = vkd3d_write_mask_component_count(write_mask);
- glsl_src_param_init(gen, &ins->src[0], write_mask, &src_param);
- if (mask_size > 1)
shader_glsl_print_assignment(gen, ins, &dst_param, "%s%u(%s));\n", vector_constructor, mask_size, src_param.param_str->buffer);
- else
shader_glsl_print_assignment(gen, ins, &dst_param, "%s(%s));\n", scalar_constructor, src_param.param_str->buffer);
- glsl_src_param_cleanup(&src_param, &gen->string_buffers);
- glsl_dst_param_cleanup(&dst_param, &gen->string_buffers);
+}
We could take shader_glsl_print_assignment() one step further, and print the trailing ");\n" in shader_glsl_print_assignment() as well, so that we get the following here:
if (mask_size > 1) shader_glsl_print_assignment(gen, ins, &dst_param, "%s%u(%s)", vector_constructor, mask_size, src_param.param_str->buffer); else shader_glsl_print_assignment(gen, ins, &dst_param, "%s(%s)", scalar_constructor, src_param.param_str->buffer);
Signed-off-by: Atharva Nimbalkar atharvakn@gmail.com --- libs/vkd3d-shader/glsl.c | 186 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 180 insertions(+), 6 deletions(-)
diff --git a/libs/vkd3d-shader/glsl.c b/libs/vkd3d-shader/glsl.c index 75b7bbc..32458f0 100644 --- a/libs/vkd3d-shader/glsl.c +++ b/libs/vkd3d-shader/glsl.c @@ -161,6 +161,30 @@ static bool shader_is_scalar(const struct vkd3d_shader_register *reg) } }
+static void shader_glsl_print_swizzle(uint32_t swizzle, bool fixup, uint32_t mask, + struct vkd3d_string_buffer *str) +{ + /* For registers of type VKD3DDECLTYPE_D3DCOLOR, data is stored as "bgra", + * but addressed as "rgba". To fix this we need to swap the register's x + * and z components. */ + const char *swizzle_chars = fixup ? "zyxw" : "xyzw"; + unsigned int i; + + vkd3d_string_buffer_printf(str, "."); + for (i = 0; i < 4; ++i) + { + if (mask & (VKD3DSP_WRITEMASK_0 << i)) + vkd3d_string_buffer_printf(str, "%c", swizzle_chars[vkd3d_swizzle_get_component(swizzle, i)]); + } +} + +static void shader_glsl_get_swizzle(const struct vkd3d_shader_src_param *param, + bool fixup, uint32_t mask, struct vkd3d_string_buffer *swizzle_str) +{ + if (!shader_is_scalar(¶m->reg)) + shader_glsl_print_swizzle(param->swizzle, fixup, mask, swizzle_str); +} + static void shader_glsl_print_write_mask(uint32_t write_mask, struct vkd3d_string_buffer *str) { vkd3d_string_buffer_printf(str, "."); @@ -204,6 +228,120 @@ static void shader_glsl_get_register_name(struct vkd3d_glsl_generator *gen, "Internal compiler error: Unhandled register type %#x.", reg->type); }
+static void shader_glsl_sprintf_cast(struct vkd3d_glsl_generator *gen, + struct vkd3d_string_buffer *dst_param, const char *src_param, + enum vkd3d_data_type dst_data_type, enum vkd3d_data_type src_data_type, unsigned int size) +{ + if (dst_data_type == VKD3D_DATA_UNORM || dst_data_type == VKD3D_DATA_SNORM) + dst_data_type = VKD3D_DATA_FLOAT; + if (src_data_type == VKD3D_DATA_UNORM || src_data_type == VKD3D_DATA_SNORM) + src_data_type = VKD3D_DATA_FLOAT; + + if (dst_data_type == src_data_type) + { + vkd3d_string_buffer_printf(dst_param, "%s", src_param); + return; + } + + if (src_data_type == VKD3D_DATA_FLOAT) + { + switch (dst_data_type) + { + case VKD3D_DATA_INT: + vkd3d_string_buffer_printf(dst_param, "floatBitsToInt(%s)", src_param); + return; + case VKD3D_DATA_RESOURCE: + case VKD3D_DATA_SAMPLER: + case VKD3D_DATA_UINT: + vkd3d_string_buffer_printf(dst_param, "floatBitsToUint(%s)", src_param); + return; + default: + break; + } + } + + if (src_data_type == VKD3D_DATA_UINT && dst_data_type == VKD3D_DATA_FLOAT) + { + vkd3d_string_buffer_printf(dst_param, "uintBitsToFloat(%s)", src_param); + return; + } + + if (src_data_type == VKD3D_DATA_INT) + { + switch (dst_data_type) + { + case VKD3D_DATA_FLOAT: + vkd3d_string_buffer_printf(dst_param, "intBitsToFloat(%s)", src_param); + return; + case VKD3D_DATA_UINT: + if (size == 1) + vkd3d_string_buffer_printf(dst_param, "uint(%s)", src_param); + else + vkd3d_string_buffer_printf(dst_param, "uvec%u(%s)", size, src_param); + return; + default: + break; + } + } + + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, + "Unhandled cast from %#x to %#x.\n", src_data_type, dst_data_type); + vkd3d_string_buffer_printf(dst_param, "%s", src_param); +} + +/* Generate a GLSL parameter that does the input modifier computation and return the input register/mask to use */ +static void shader_glsl_gen_modifier(struct vkd3d_glsl_generator *gen, + enum vkd3d_shader_src_modifier src_modifier, + const char *in_reg, const struct vkd3d_string_buffer *in_regswizzle, + struct vkd3d_string_buffer *out_str) +{ + switch (src_modifier) + { + case VKD3DSPSM_DZ: /* Need to handle this in the instructions itself (texld & texcrd). */ + case VKD3DSPSM_DW: + case VKD3DSPSM_NONE: + vkd3d_string_buffer_printf(out_str, "%s%s", in_reg, in_regswizzle->buffer); + break; + case VKD3DSPSM_NEG: + vkd3d_string_buffer_printf(out_str, "-%s%s", in_reg, in_regswizzle->buffer); + break; + case VKD3DSPSM_NOT: + vkd3d_string_buffer_printf(out_str, "!%s%s", in_reg, in_regswizzle->buffer); + break; + case VKD3DSPSM_BIAS: + vkd3d_string_buffer_printf(out_str, "(%s%s - vec4(0.5)%s)", in_reg, in_regswizzle->buffer, in_regswizzle->buffer); + break; + case VKD3DSPSM_BIASNEG: + vkd3d_string_buffer_printf(out_str, "-(%s%s - vec4(0.5)%s)", in_reg, in_regswizzle->buffer, in_regswizzle->buffer); + break; + case VKD3DSPSM_SIGN: + vkd3d_string_buffer_printf(out_str, "(2.0 * (%s%s - 0.5))", in_reg, in_regswizzle->buffer); + break; + case VKD3DSPSM_SIGNNEG: + vkd3d_string_buffer_printf(out_str, "-(2.0 * (%s%s - 0.5))", in_reg, in_regswizzle->buffer); + break; + case VKD3DSPSM_COMP: + vkd3d_string_buffer_printf(out_str, "(1.0 - %s%s)", in_reg, in_regswizzle->buffer); + break; + case VKD3DSPSM_X2: + vkd3d_string_buffer_printf(out_str, "(2.0 * %s%s)", in_reg, in_regswizzle->buffer); + break; + case VKD3DSPSM_X2NEG: + vkd3d_string_buffer_printf(out_str, "-(2.0 * %s%s)", in_reg, in_regswizzle->buffer); + break; + case VKD3DSPSM_ABS: + vkd3d_string_buffer_printf(out_str, "abs(%s%s)", in_reg, in_regswizzle->buffer); + break; + case VKD3DSPSM_ABSNEG: + vkd3d_string_buffer_printf(out_str, "-abs(%s%s)", in_reg, in_regswizzle->buffer); + break; + default: + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, + "Unhandled modifier %#x\n", src_modifier); + vkd3d_string_buffer_printf(out_str, "%s%s", in_reg, in_regswizzle->buffer); + } +} + /* From a given parameter token, generate the corresponding GLSL string. * Also, return the actual register name and swizzle in case the * caller needs this information as well. */ @@ -211,14 +349,50 @@ static void glsl_src_param_init_ext(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_src_param *vkd3d_src, uint32_t mask, struct glsl_src_param *glsl_src, enum vkd3d_data_type data_type) { - /* - * TODO: Add implementation - * Sets an error state as of now. - */ + struct vkd3d_string_buffer *param_str = vkd3d_string_buffer_get(&gen->string_buffers); + struct vkd3d_string_buffer *reg_name = vkd3d_string_buffer_get(&gen->string_buffers); + struct vkd3d_string_buffer *swizzle_str = vkd3d_string_buffer_get(&gen->string_buffers); + enum vkd3d_data_type param_data_type; + bool is_color = false; + unsigned int size;
glsl_src->param_str = vkd3d_string_buffer_get(&gen->string_buffers); - vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, - "Internal compiler error: Unhandled parameter token."); + shader_glsl_get_register_name(gen, &vkd3d_src->reg, data_type, reg_name, &is_color); + shader_glsl_get_swizzle(vkd3d_src, false, mask, swizzle_str); + + switch (vkd3d_src->reg.type) + { + case VKD3DSPR_IMMCONST: + param_data_type = data_type; + size = vkd3d_src->reg.immconst_type == VKD3D_IMMCONST_SCALAR ? 1 : 4; + break; + case VKD3DSPR_FORKINSTID: + case VKD3DSPR_GSINSTID: + case VKD3DSPR_JOININSTID: + case VKD3DSPR_LOCALTHREADINDEX: + case VKD3DSPR_OUTPOINTID: + case VKD3DSPR_PRIMID: + param_data_type = VKD3D_DATA_INT; + size = 1; + break; + case VKD3DSPR_LOCALTHREADID: + case VKD3DSPR_THREADGROUPID: + case VKD3DSPR_THREADID: + param_data_type = VKD3D_DATA_INT; + size = 3; + break; + default: + param_data_type = VKD3D_DATA_FLOAT; + size = 4; + break; + } + + shader_glsl_sprintf_cast(gen, param_str, reg_name->buffer, data_type, param_data_type, size); + shader_glsl_gen_modifier(gen, vkd3d_src->modifiers, param_str->buffer, swizzle_str, glsl_src->param_str); + + vkd3d_string_buffer_release(&gen->string_buffers, swizzle_str); + vkd3d_string_buffer_release(&gen->string_buffers, reg_name); + vkd3d_string_buffer_release(&gen->string_buffers, param_str); }
static void glsl_src_param_init(struct vkd3d_glsl_generator *gen,
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=95808
Your paranoid android.
=== debiant2 (build log) ===
Task: Patch failed to apply
=== debiant2 (build log) ===
Task: Patch failed to apply
On Wed, 18 Aug 2021 at 06:28, Atharva Nimbalkar atharvakn@gmail.com wrote:
+/* Generate a GLSL parameter that does the input modifier computation and return the input register/mask to use */ +static void shader_glsl_gen_modifier(struct vkd3d_glsl_generator *gen,
enum vkd3d_shader_src_modifier src_modifier,
const char *in_reg, const struct vkd3d_string_buffer *in_regswizzle,
struct vkd3d_string_buffer *out_str)
+{
- switch (src_modifier)
- {
case VKD3DSPSM_DZ: /* Need to handle this in the instructions itself (texld & texcrd). */
case VKD3DSPSM_DW:
case VKD3DSPSM_NONE:
vkd3d_string_buffer_printf(out_str, "%s%s", in_reg, in_regswizzle->buffer);
break;
case VKD3DSPSM_NEG:
vkd3d_string_buffer_printf(out_str, "-%s%s", in_reg, in_regswizzle->buffer);
break;
case VKD3DSPSM_NOT:
vkd3d_string_buffer_printf(out_str, "!%s%s", in_reg, in_regswizzle->buffer);
break;
case VKD3DSPSM_BIAS:
vkd3d_string_buffer_printf(out_str, "(%s%s - vec4(0.5)%s)", in_reg, in_regswizzle->buffer, in_regswizzle->buffer);
break;
case VKD3DSPSM_BIASNEG:
vkd3d_string_buffer_printf(out_str, "-(%s%s - vec4(0.5)%s)", in_reg, in_regswizzle->buffer, in_regswizzle->buffer);
break;
case VKD3DSPSM_SIGN:
vkd3d_string_buffer_printf(out_str, "(2.0 * (%s%s - 0.5))", in_reg, in_regswizzle->buffer);
break;
case VKD3DSPSM_SIGNNEG:
vkd3d_string_buffer_printf(out_str, "-(2.0 * (%s%s - 0.5))", in_reg, in_regswizzle->buffer);
break;
case VKD3DSPSM_COMP:
vkd3d_string_buffer_printf(out_str, "(1.0 - %s%s)", in_reg, in_regswizzle->buffer);
break;
case VKD3DSPSM_X2:
vkd3d_string_buffer_printf(out_str, "(2.0 * %s%s)", in_reg, in_regswizzle->buffer);
break;
case VKD3DSPSM_X2NEG:
vkd3d_string_buffer_printf(out_str, "-(2.0 * %s%s)", in_reg, in_regswizzle->buffer);
break;
case VKD3DSPSM_ABS:
vkd3d_string_buffer_printf(out_str, "abs(%s%s)", in_reg, in_regswizzle->buffer);
break;
case VKD3DSPSM_ABSNEG:
vkd3d_string_buffer_printf(out_str, "-abs(%s%s)", in_reg, in_regswizzle->buffer);
break;
default:
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
"Unhandled modifier %#x\n", src_modifier);
vkd3d_string_buffer_printf(out_str, "%s%s", in_reg, in_regswizzle->buffer);
- }
+}
We can defer most modifier handling to a later patch; the only cases we really need to handle in this patch are VKD3DSPSM_NONE and "default".
@@ -211,14 +349,50 @@ static void glsl_src_param_init_ext(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_src_param *vkd3d_src, uint32_t mask, struct glsl_src_param *glsl_src, enum vkd3d_data_type data_type) {
- /*
* TODO: Add implementation
* Sets an error state as of now.
*/
struct vkd3d_string_buffer *param_str = vkd3d_string_buffer_get(&gen->string_buffers);
struct vkd3d_string_buffer *reg_name = vkd3d_string_buffer_get(&gen->string_buffers);
struct vkd3d_string_buffer *swizzle_str = vkd3d_string_buffer_get(&gen->string_buffers);
enum vkd3d_data_type param_data_type;
bool is_color = false;
unsigned int size;
glsl_src->param_str = vkd3d_string_buffer_get(&gen->string_buffers);
- vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
"Internal compiler error: Unhandled parameter token.");
- shader_glsl_get_register_name(gen, &vkd3d_src->reg, data_type, reg_name, &is_color);
- shader_glsl_get_swizzle(vkd3d_src, false, mask, swizzle_str);
We should pass "is_color" to shader_glsl_get_swizzle() here.
Signed-off-by: Atharva Nimbalkar atharvakn@gmail.com --- libs/vkd3d-shader/glsl.c | 58 +++++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 6 deletions(-)
diff --git a/libs/vkd3d-shader/glsl.c b/libs/vkd3d-shader/glsl.c index 32458f0..afab2c3 100644 --- a/libs/vkd3d-shader/glsl.c +++ b/libs/vkd3d-shader/glsl.c @@ -219,13 +219,59 @@ static void shader_glsl_get_register_name(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_register *reg, enum vkd3d_data_type data_type, struct vkd3d_string_buffer *register_name, bool *is_swizzled) { - /* TODO: Add implementation - * Sets an error state as of now - */ - if(is_swizzled) + /* + * Currently adds support for input and output shaders. + * with support for relative addressing. + */ + + const struct vkd3d_shader_version *version = &gen->version; + const char *prefix = shader_get_type_prefix(version->type); + struct glsl_src_param rel_param0, rel_param1; + + rel_param0.param_str = vkd3d_string_buffer_get(&gen->string_buffers); + rel_param1.param_str = vkd3d_string_buffer_get(&gen->string_buffers); + if (reg->idx[0].offset != ~0u && reg->idx[0].rel_addr) + glsl_src_param_init_ext(gen, reg->idx[0].rel_addr, VKD3DSP_WRITEMASK_0, + &rel_param0, reg->idx[0].rel_addr->reg.data_type); + if (reg->idx[1].offset != ~0u && reg->idx[1].rel_addr) + glsl_src_param_init_ext(gen, reg->idx[1].rel_addr, VKD3DSP_WRITEMASK_0, + &rel_param1, reg->idx[1].rel_addr->reg.data_type); + if (is_swizzled) *is_swizzled = false; - vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, - "Internal compiler error: Unhandled register type %#x.", reg->type); + + switch (reg->type) + { + case VKD3DSPR_INPUT: + if (version->type == VKD3D_SHADER_TYPE_VERTEX) + { + if (reg->idx[0].rel_addr) + { + vkd3d_string_buffer_printf(register_name, "%s_in[%s + %u]", + prefix, rel_param0.param_str->buffer, reg->idx[0].offset); + } + else + { + vkd3d_string_buffer_printf(register_name, "%s_in%u", prefix, reg->idx[0].offset); + } + break; + } + break; + case VKD3DSPR_OUTPUT: + if (reg->idx[0].rel_addr) + vkd3d_string_buffer_printf(register_name, "%s_out[%s + %u]", + prefix, rel_param0.param_str->buffer, reg->idx[0].offset); + else + vkd3d_string_buffer_printf(register_name, "%s_out[%u]", prefix, reg->idx[0].offset); + break; + default: + vkd3d_string_buffer_printf(register_name, "unrecognised_register"); + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, + "Unhandled register type %#x.\n", reg->type); + break; + } + + glsl_src_param_cleanup(&rel_param0, &gen->string_buffers); + glsl_src_param_cleanup(&rel_param1, &gen->string_buffers); }
static void shader_glsl_sprintf_cast(struct vkd3d_glsl_generator *gen,
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=95809
Your paranoid android.
=== debiant2 (build log) ===
Task: Patch failed to apply
=== debiant2 (build log) ===
Task: Patch failed to apply
On Wed, 18 Aug 2021 at 06:21, Atharva Nimbalkar atharvakn@gmail.com wrote:
@@ -219,13 +219,59 @@ static void shader_glsl_get_register_name(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_register *reg, enum vkd3d_data_type data_type, struct vkd3d_string_buffer *register_name, bool *is_swizzled) {
- /* TODO: Add implementation
* Sets an error state as of now
*/
- if(is_swizzled)
- /*
- Currently adds support for input and output shaders.
- with support for relative addressing.
- */
"registers", not "shaders".
- const struct vkd3d_shader_version *version = &gen->version;
- const char *prefix = shader_get_type_prefix(version->type);
- struct glsl_src_param rel_param0, rel_param1;
- rel_param0.param_str = vkd3d_string_buffer_get(&gen->string_buffers);
- rel_param1.param_str = vkd3d_string_buffer_get(&gen->string_buffers);
- if (reg->idx[0].offset != ~0u && reg->idx[0].rel_addr)
glsl_src_param_init_ext(gen, reg->idx[0].rel_addr, VKD3DSP_WRITEMASK_0,
&rel_param0, reg->idx[0].rel_addr->reg.data_type);
- if (reg->idx[1].offset != ~0u && reg->idx[1].rel_addr)
glsl_src_param_init_ext(gen, reg->idx[1].rel_addr, VKD3DSP_WRITEMASK_0,
&rel_param1, reg->idx[1].rel_addr->reg.data_type);
"rel_param0.param_str" and "rel_param1.param_str" are also initialised by glsl_src_param_init_ext(), so would be leaked in that case. I assume the vkd3d_string_buffer_get() calls were added to match the glsl_src_param_cleanup() at the end of this function. Perhaps the best thing to do would be to only call those in the same cases that we call glsl_src_param_init_ext() above.
- if (is_swizzled) *is_swizzled = false;
- vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
"Internal compiler error: Unhandled register type %#x.", reg->type);
- switch (reg->type)
- {
case VKD3DSPR_INPUT:
if (version->type == VKD3D_SHADER_TYPE_VERTEX)
{
if (reg->idx[0].rel_addr)
{
vkd3d_string_buffer_printf(register_name, "%s_in[%s + %u]",
prefix, rel_param0.param_str->buffer, reg->idx[0].offset);
}
else
{
vkd3d_string_buffer_printf(register_name, "%s_in%u", prefix, reg->idx[0].offset);
}
break;
}
break;
This doesn't handle inputs for other shader types. That's fine, but we should generate an error when we encounter those.
case VKD3DSPR_OUTPUT:
if (reg->idx[0].rel_addr)
vkd3d_string_buffer_printf(register_name, "%s_out[%s + %u]",
prefix, rel_param0.param_str->buffer, reg->idx[0].offset);
else
vkd3d_string_buffer_printf(register_name, "%s_out[%u]", prefix, reg->idx[0].offset);
break;
We could conceivably split this patch in two, one implementing handling of VKD3DSPR_OUTPUT, and the other implementing handling of VKD3DSPR_INPUT.
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=95803
Your paranoid android.
=== debiant2 (build log) ===
Task: Patch failed to apply
=== debiant2 (build log) ===
Task: Patch failed to apply
On 8/17/21 11:19 PM, Atharva Nimbalkar wrote:
Signed-off-by: Atharva Nimbalkar atharvakn@gmail.com
include/vkd3d_shader.h | 4 ++++ libs/vkd3d-shader/vkd3d_shader_main.c | 10 ++++++++++ libs/vkd3d-shader/vkd3d_shader_private.h | 2 ++ programs/vkd3d-compiler/main.c | 3 +++ 4 files changed, 19 insertions(+)
diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h index 5092fac..58e507b 100644 --- a/include/vkd3d_shader.h +++ b/include/vkd3d_shader.h @@ -491,6 +491,10 @@ enum vkd3d_shader_target_type * the format used for Direct3D shader model 4 and 5 shaders. */ VKD3D_SHADER_TARGET_DXBC_TPF,
- /**
* An 'OpenGL Shading Language' shader.
*/
Could use a follow-up patch, but this probably deserves a "\since 1.3".
VKD3D_SHADER_TARGET_GLSL,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_TARGET_TYPE), };
On Wed, 18 Aug 2021 at 16:20, Zebediah Figura (she/her) zfigura@codeweavers.com wrote:
@@ -491,6 +491,10 @@ enum vkd3d_shader_target_type * the format used for Direct3D shader model 4 and 5 shaders. */ VKD3D_SHADER_TARGET_DXBC_TPF,
- /**
* An 'OpenGL Shading Language' shader.
*/
Could use a follow-up patch, but this probably deserves a "\since 1.3".
Right. Note that that also applies to the other sources and targets introduced since 1.2 though.