From: Henri Verbeet hverbeet@codeweavers.com
We typically want to use lower-left in OpenGL environments when rendering to FBOs. --- include/vkd3d_shader.h | 25 +++++++++++++++++++++++++ libs/vkd3d-shader/spirv.c | 13 ++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h index 94f79c7c7..1d6cbbf88 100644 --- a/include/vkd3d_shader.h +++ b/include/vkd3d_shader.h @@ -173,6 +173,21 @@ enum vkd3d_shader_compile_option_backward_compatibility VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_BACKWARD_COMPATIBILITY), };
+/** + * Determines the origin of fragment coordinates. + * + * \since 1.10 + */ +enum vkd3d_shader_compile_option_fragment_coordinate_origin +{ + /** Fragment coordinates originate from the upper-left. This is the + * default; it's also the only value supported by Vulkan environments. */ + VKD3D_SHADER_COMPILE_OPTION_FRAGMENT_COORDINATE_ORIGIN_UPPER_LEFT = 0x00000000, + /** Fragment coordinates originate from the lower-left. This matches the + * traditional behaviour of OpenGL environments. */ + VKD3D_SHADER_COMPILE_OPTION_FRAGMENT_COORDINATE_ORIGIN_LOWER_LEFT = 0x00000001, +}; + enum vkd3d_shader_compile_option_name { /** @@ -220,6 +235,16 @@ enum vkd3d_shader_compile_option_name * \since 1.10 */ VKD3D_SHADER_COMPILE_OPTION_BACKWARD_COMPATIBILITY = 0x00000008, + /** + * This option specifies the origin of fragment coordinates for SPIR-V + * targets. + * + * \a value is a member of enum + * vkd3d_shader_compile_option_fragment_coordinate_origin. + * + * \since 1.10 + */ + VKD3D_SHADER_COMPILE_OPTION_FRAGMENT_COORDINATE_ORIGIN = 0x00000009,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_NAME), }; diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 61d757579..c681b9f82 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -2288,6 +2288,7 @@ struct spirv_compiler bool strip_debug; bool ssbo_uavs; bool uav_read_without_format; + SpvExecutionMode fragment_coordinate_origin;
struct rb_tree symbol_table; uint32_t temp_id; @@ -2453,6 +2454,7 @@ static struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_ve compiler->formatting = VKD3D_SHADER_COMPILE_OPTION_FORMATTING_INDENT | VKD3D_SHADER_COMPILE_OPTION_FORMATTING_HEADER; compiler->write_tess_geom_point_size = true; + compiler->fragment_coordinate_origin = SpvExecutionModeOriginUpperLeft;
for (i = 0; i < compile_info->option_count; ++i) { @@ -2493,6 +2495,15 @@ static struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_ve compiler->write_tess_geom_point_size = option->value; break;
+ case VKD3D_SHADER_COMPILE_OPTION_FRAGMENT_COORDINATE_ORIGIN: + if (option->value == VKD3D_SHADER_COMPILE_OPTION_FRAGMENT_COORDINATE_ORIGIN_UPPER_LEFT) + compiler->fragment_coordinate_origin = SpvExecutionModeOriginUpperLeft; + else if (option->value == VKD3D_SHADER_COMPILE_OPTION_FRAGMENT_COORDINATE_ORIGIN_LOWER_LEFT) + compiler->fragment_coordinate_origin = SpvExecutionModeOriginLowerLeft; + else + WARN("Ignoring unrecognised value %#x for option %#x.\n", option->value, option->name); + break; + default: WARN("Ignoring unrecognised option %#x with value %#x.\n", option->name, option->value); break; @@ -5358,7 +5369,7 @@ static void spirv_compiler_emit_initial_declarations(struct spirv_compiler *comp break; case VKD3D_SHADER_TYPE_PIXEL: vkd3d_spirv_set_execution_model(builder, SpvExecutionModelFragment); - spirv_compiler_emit_execution_mode(compiler, SpvExecutionModeOriginUpperLeft, NULL, 0); + spirv_compiler_emit_execution_mode(compiler, compiler->fragment_coordinate_origin, NULL, 0); break; case VKD3D_SHADER_TYPE_COMPUTE: vkd3d_spirv_set_execution_model(builder, SpvExecutionModelGLCompute);
From: Henri Verbeet hverbeet@codeweavers.com
--- programs/vkd3d-compiler/main.c | 61 ++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 13 deletions(-)
diff --git a/programs/vkd3d-compiler/main.c b/programs/vkd3d-compiler/main.c index 2d10baca7..4409d250b 100644 --- a/programs/vkd3d-compiler/main.c +++ b/programs/vkd3d-compiler/main.c @@ -40,6 +40,7 @@ enum OPTION_HELP = CHAR_MAX + 1, OPTION_BUFFER_UAV, OPTION_ENTRY, + OPTION_FRAGMENT_COORDINATE_ORIGIN, OPTION_MATRIX_STORAGE_ORDER, OPTION_OUTPUT, OPTION_PRINT_SOURCE_TYPES, @@ -189,6 +190,11 @@ static void print_usage(const char *program_name) " optionally prefixed by '+' or '-'. Valid flags are\n" " 'colour', 'indent', 'offsets', 'header', and 'raw-ids'.\n" " The 'indent' and 'header' flags are enabled by default.\n" + " --fragment-coordinate-origin=<origin>\n" + " Specify the origin of fragment coordinates for SPIR-V\n" + " targets. Valid values are 'upper-left' (default) and\n" + " 'lower-left'. The only value supported by Vulkan\n" + " environments is 'upper-left'.\n" " --matrix-storage-order=<order>\n" " Specify the default matrix storage order. Valid values\n" " are 'column' (default) and 'row'.\n" @@ -337,6 +343,24 @@ static bool parse_formatting(uint32_t *formatting, bool *colour, char *arg) return true; }
+static bool parse_fragment_coordinate_origin(enum vkd3d_shader_compile_option_fragment_coordinate_origin *origin, + const char *arg) +{ + if (!strcmp(arg, "upper-left")) + { + *origin = VKD3D_SHADER_COMPILE_OPTION_FRAGMENT_COORDINATE_ORIGIN_UPPER_LEFT; + return true; + } + + if (!strcmp(arg, "lower-left")) + { + *origin = VKD3D_SHADER_COMPILE_OPTION_FRAGMENT_COORDINATE_ORIGIN_LOWER_LEFT; + return true; + } + + return false; +} + static bool parse_matrix_storage_order(enum vkd3d_shader_compile_option_pack_matrix_order *order, const char *arg) { if (!strcmp(arg, "column")) @@ -441,25 +465,27 @@ static bool validate_target_type( static bool parse_command_line(int argc, char **argv, struct options *options) { enum vkd3d_shader_compile_option_pack_matrix_order pack_matrix_order; + enum vkd3d_shader_compile_option_fragment_coordinate_origin origin; enum vkd3d_shader_compile_option_buffer_uav buffer_uav; unsigned int compat_options = 0; int option;
static struct option long_options[] = { - {"help", no_argument, NULL, OPTION_HELP}, - {"buffer-uav", required_argument, NULL, OPTION_BUFFER_UAV}, - {"entry", required_argument, NULL, OPTION_ENTRY}, - {"matrix-storage-order", required_argument, NULL, OPTION_MATRIX_STORAGE_ORDER}, - {"output", required_argument, NULL, OPTION_OUTPUT}, - {"formatting", required_argument, NULL, OPTION_TEXT_FORMATTING}, - {"print-source-types", no_argument, NULL, OPTION_PRINT_SOURCE_TYPES}, - {"print-target-types", no_argument, NULL, OPTION_PRINT_TARGET_TYPES}, - {"profile", required_argument, NULL, OPTION_PROFILE}, - {"strip-debug", no_argument, NULL, OPTION_STRIP_DEBUG}, - {"version", no_argument, NULL, OPTION_VERSION}, - {"semantic-compat-map", no_argument, NULL, OPTION_SEMANTIC_COMPAT_MAP}, - {NULL, 0, NULL, 0}, + {"help", no_argument, NULL, OPTION_HELP}, + {"buffer-uav", required_argument, NULL, OPTION_BUFFER_UAV}, + {"entry", required_argument, NULL, OPTION_ENTRY}, + {"fragment-coordinate-origin", required_argument, NULL, OPTION_FRAGMENT_COORDINATE_ORIGIN}, + {"matrix-storage-order", required_argument, NULL, OPTION_MATRIX_STORAGE_ORDER}, + {"output", required_argument, NULL, OPTION_OUTPUT}, + {"formatting", required_argument, NULL, OPTION_TEXT_FORMATTING}, + {"print-source-types", no_argument, NULL, OPTION_PRINT_SOURCE_TYPES}, + {"print-target-types", no_argument, NULL, OPTION_PRINT_TARGET_TYPES}, + {"profile", required_argument, NULL, OPTION_PROFILE}, + {"strip-debug", no_argument, NULL, OPTION_STRIP_DEBUG}, + {"version", no_argument, NULL, OPTION_VERSION}, + {"semantic-compat-map", no_argument, NULL, OPTION_SEMANTIC_COMPAT_MAP}, + {NULL, 0, NULL, 0}, };
memset(options, 0, sizeof(*options)); @@ -501,6 +527,15 @@ static bool parse_command_line(int argc, char **argv, struct options *options) options->preprocess_only = true; break;
+ case OPTION_FRAGMENT_COORDINATE_ORIGIN: + if (!parse_fragment_coordinate_origin(&origin, optarg)) + { + fprintf(stderr, "Invalid fragment coordinate origin '%s' specified.\n", optarg); + return false; + } + add_compile_option(options, VKD3D_SHADER_COMPILE_OPTION_FRAGMENT_COORDINATE_ORIGIN, origin); + break; + case 'h': case OPTION_HELP: options->print_help = true;
This merge request was approved by Giovanni Mascellani.
This merge request was approved by Henri Verbeet.