| 
									
										
										
										
											2021-08-19 20:18:13 +05:30
										 |  |  | /*
 | 
					
						
							|  |  |  |  * 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"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  | struct glsl_resource_type_info | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-10-18 21:21:15 +02:00
										 |  |  |     /* The number of coordinates needed to sample the resource type. */ | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |     size_t coord_size; | 
					
						
							| 
									
										
										
										
											2024-10-18 21:21:15 +02:00
										 |  |  |     /* Whether the resource type is an array type. */ | 
					
						
							|  |  |  |     bool array; | 
					
						
							|  |  |  |     /* Whether the resource type has a shadow/comparison variant. */ | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |     bool shadow; | 
					
						
							| 
									
										
										
										
											2024-10-18 21:21:15 +02:00
										 |  |  |     /* The type suffix for resource type. I.e., the "2D" part of "usampler2D"
 | 
					
						
							|  |  |  |      * or "iimage2D". */ | 
					
						
							| 
									
										
										
										
											2024-10-05 20:48:51 +02:00
										 |  |  |     const char *type_suffix; | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  | struct glsl_src | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     struct vkd3d_string_buffer *str; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct glsl_dst | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const struct vkd3d_shader_dst_param *vsir; | 
					
						
							|  |  |  |     struct vkd3d_string_buffer *register_name; | 
					
						
							|  |  |  |     struct vkd3d_string_buffer *mask; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-19 20:18:13 +05:30
										 |  |  | struct vkd3d_glsl_generator | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-11-17 18:39:48 +01:00
										 |  |  |     struct vsir_program *program; | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  |     struct vkd3d_string_buffer_cache string_buffers; | 
					
						
							|  |  |  |     struct vkd3d_string_buffer *buffer; | 
					
						
							| 
									
										
										
										
											2023-02-26 04:04:58 +01:00
										 |  |  |     struct vkd3d_shader_location location; | 
					
						
							| 
									
										
										
										
											2021-08-19 20:18:13 +05:30
										 |  |  |     struct vkd3d_shader_message_context *message_context; | 
					
						
							| 
									
										
										
										
											2023-11-17 07:18:47 +01:00
										 |  |  |     unsigned int indent; | 
					
						
							| 
									
										
										
										
											2023-11-22 14:33:18 +01:00
										 |  |  |     const char *prefix; | 
					
						
							| 
									
										
										
										
											2021-08-19 20:18:13 +05:30
										 |  |  |     bool failed; | 
					
						
							| 
									
										
										
										
											2023-11-22 14:33:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     struct shader_limits | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         unsigned int input_count; | 
					
						
							| 
									
										
										
										
											2023-12-16 16:11:35 +01:00
										 |  |  |         unsigned int output_count; | 
					
						
							| 
									
										
										
										
											2023-11-22 14:33:18 +01:00
										 |  |  |     } limits; | 
					
						
							|  |  |  |     bool interstage_input; | 
					
						
							| 
									
										
										
										
											2023-12-16 16:11:35 +01:00
										 |  |  |     bool interstage_output; | 
					
						
							| 
									
										
										
										
											2024-02-25 00:35:48 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     const struct vkd3d_shader_interface_info *interface_info; | 
					
						
							|  |  |  |     const struct vkd3d_shader_descriptor_offset_info *offset_info; | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |     const struct vkd3d_shader_scan_combined_resource_sampler_info *combined_sampler_info; | 
					
						
							| 
									
										
										
										
											2021-08-19 20:18:13 +05:30
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 21:11:57 +02:00
										 |  |  | static void shader_glsl_print_subscript(struct vkd3d_string_buffer *buffer, struct vkd3d_glsl_generator *gen, | 
					
						
							|  |  |  |         const struct vkd3d_shader_src_param *rel_addr, unsigned int offset); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-19 20:18:13 +05:30
										 |  |  | 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); | 
					
						
							| 
									
										
										
										
											2023-02-26 04:04:58 +01:00
										 |  |  |     vkd3d_shader_verror(generator->message_context, &generator->location, error, fmt, args); | 
					
						
							| 
									
										
										
										
											2021-08-19 20:18:13 +05:30
										 |  |  |     va_end(args); | 
					
						
							|  |  |  |     generator->failed = true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-22 14:33:18 +01:00
										 |  |  | static const char *shader_glsl_get_prefix(enum vkd3d_shader_type type) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     switch (type) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         case VKD3D_SHADER_TYPE_VERTEX: | 
					
						
							|  |  |  |             return "vs"; | 
					
						
							|  |  |  |         case VKD3D_SHADER_TYPE_HULL: | 
					
						
							|  |  |  |             return "hs"; | 
					
						
							|  |  |  |         case VKD3D_SHADER_TYPE_DOMAIN: | 
					
						
							|  |  |  |             return "ds"; | 
					
						
							|  |  |  |         case VKD3D_SHADER_TYPE_GEOMETRY: | 
					
						
							|  |  |  |             return "gs"; | 
					
						
							|  |  |  |         case VKD3D_SHADER_TYPE_PIXEL: | 
					
						
							|  |  |  |             return "ps"; | 
					
						
							|  |  |  |         case VKD3D_SHADER_TYPE_COMPUTE: | 
					
						
							|  |  |  |             return "cs"; | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  | static const struct glsl_resource_type_info *shader_glsl_get_resource_type_info(enum vkd3d_shader_resource_type t) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     static const struct glsl_resource_type_info info[] = | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-10-18 21:21:15 +02:00
										 |  |  |         {0, 0, 0, "None"},      /* VKD3D_SHADER_RESOURCE_NONE */ | 
					
						
							|  |  |  |         {1, 0, 0, "Buffer"},    /* VKD3D_SHADER_RESOURCE_BUFFER */ | 
					
						
							|  |  |  |         {1, 0, 1, "1D"},        /* VKD3D_SHADER_RESOURCE_TEXTURE_1D */ | 
					
						
							|  |  |  |         {2, 0, 1, "2D"},        /* VKD3D_SHADER_RESOURCE_TEXTURE_2D */ | 
					
						
							|  |  |  |         {2, 0, 0, "2DMS"},      /* VKD3D_SHADER_RESOURCE_TEXTURE_2DMS */ | 
					
						
							|  |  |  |         {3, 0, 0, "3D"},        /* VKD3D_SHADER_RESOURCE_TEXTURE_3D */ | 
					
						
							|  |  |  |         {3, 0, 1, "Cube"},      /* VKD3D_SHADER_RESOURCE_TEXTURE_CUBE */ | 
					
						
							|  |  |  |         {2, 1, 1, "1DArray"},   /* VKD3D_SHADER_RESOURCE_TEXTURE_1DARRAY */ | 
					
						
							|  |  |  |         {3, 1, 1, "2DArray"},   /* VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY */ | 
					
						
							|  |  |  |         {3, 1, 0, "2DMSArray"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY */ | 
					
						
							|  |  |  |         {4, 1, 1, "CubeArray"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY */ | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!t || t >= ARRAY_SIZE(info)) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return &info[t]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const struct vkd3d_shader_descriptor_info1 *shader_glsl_get_descriptor(struct vkd3d_glsl_generator *gen, | 
					
						
							|  |  |  |         enum vkd3d_shader_descriptor_type type, unsigned int idx, unsigned int space) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2025-03-14 23:14:06 +01:00
										 |  |  |     const struct vkd3d_shader_scan_descriptor_info1 *info = &gen->program->descriptors; | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for (unsigned int i = 0; i < info->descriptor_count; ++i) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         const struct vkd3d_shader_descriptor_info1 *d = &info->descriptors[i]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (d->type == type && d->register_space == space && d->register_index == idx) | 
					
						
							|  |  |  |             return d; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const struct vkd3d_shader_descriptor_info1 *shader_glsl_get_descriptor_by_id( | 
					
						
							|  |  |  |         struct vkd3d_glsl_generator *gen, enum vkd3d_shader_descriptor_type type, unsigned int id) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2025-03-14 23:14:06 +01:00
										 |  |  |     const struct vkd3d_shader_scan_descriptor_info1 *info = &gen->program->descriptors; | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for (unsigned int i = 0; i < info->descriptor_count; ++i) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         const struct vkd3d_shader_descriptor_info1 *d = &info->descriptors[i]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (d->type == type && d->register_id == id) | 
					
						
							|  |  |  |             return d; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-17 07:18:47 +01:00
										 |  |  | static void shader_glsl_print_indent(struct vkd3d_string_buffer *buffer, unsigned int indent) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(buffer, "%*s", 4 * indent, ""); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  | static void shader_glsl_print_combined_sampler_name(struct vkd3d_string_buffer *buffer, | 
					
						
							|  |  |  |         struct vkd3d_glsl_generator *gen, unsigned int resource_index, | 
					
						
							|  |  |  |         unsigned int resource_space, unsigned int sampler_index, unsigned int sampler_space) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(buffer, "%s_t_%u", gen->prefix, resource_index); | 
					
						
							|  |  |  |     if (resource_space) | 
					
						
							|  |  |  |         vkd3d_string_buffer_printf(buffer, "_%u", resource_space); | 
					
						
							|  |  |  |     if (sampler_index != VKD3D_SHADER_DUMMY_SAMPLER_INDEX) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         vkd3d_string_buffer_printf(buffer, "_s_%u", sampler_index); | 
					
						
							|  |  |  |         if (sampler_space) | 
					
						
							|  |  |  |             vkd3d_string_buffer_printf(buffer, "_%u", sampler_space); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-05 20:48:51 +02:00
										 |  |  | static void shader_glsl_print_image_name(struct vkd3d_string_buffer *buffer, | 
					
						
							|  |  |  |         struct vkd3d_glsl_generator *gen, unsigned int idx, unsigned int space) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(buffer, "%s_image_%u", gen->prefix, idx); | 
					
						
							|  |  |  |     if (space) | 
					
						
							|  |  |  |         vkd3d_string_buffer_printf(buffer, "_%u", space); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  | static void shader_glsl_print_register_name(struct vkd3d_string_buffer *buffer, | 
					
						
							|  |  |  |         struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_register *reg) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-08-23 21:02:31 +05:30
										 |  |  |     switch (reg->type) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         case VKD3DSPR_TEMP: | 
					
						
							|  |  |  |             vkd3d_string_buffer_printf(buffer, "r[%u]", reg->idx[0].offset); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-22 14:33:18 +01:00
										 |  |  |         case VKD3DSPR_INPUT: | 
					
						
							|  |  |  |             if (reg->idx_count != 1) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                         "Internal compiler error: Unhandled input register index count %u.", reg->idx_count); | 
					
						
							|  |  |  |                 vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type); | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if (reg->idx[0].rel_addr) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                         "Internal compiler error: Unhandled input register indirect addressing."); | 
					
						
							|  |  |  |                 vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type); | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             vkd3d_string_buffer_printf(buffer, "%s_in[%u]", gen->prefix, reg->idx[0].offset); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 16:11:35 +01:00
										 |  |  |         case VKD3DSPR_OUTPUT: | 
					
						
							|  |  |  |             if (reg->idx_count != 1) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                         "Internal compiler error: Unhandled output register index count %u.", reg->idx_count); | 
					
						
							|  |  |  |                 vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type); | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if (reg->idx[0].rel_addr) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                         "Internal compiler error: Unhandled output register indirect addressing."); | 
					
						
							|  |  |  |                 vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type); | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             vkd3d_string_buffer_printf(buffer, "%s_out[%u]", gen->prefix, reg->idx[0].offset); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-02 00:49:35 +02:00
										 |  |  |         case VKD3DSPR_DEPTHOUT: | 
					
						
							|  |  |  |             if (gen->program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL) | 
					
						
							|  |  |  |                 vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                         "Internal compiler error: Unhandled depth output in shader type #%x.", | 
					
						
							|  |  |  |                         gen->program->shader_version.type); | 
					
						
							|  |  |  |             vkd3d_string_buffer_printf(buffer, "gl_FragDepth"); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 08:26:51 +05:30
										 |  |  |         case VKD3DSPR_IMMCONST: | 
					
						
							|  |  |  |             switch (reg->dimension) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 case VSIR_DIMENSION_SCALAR: | 
					
						
							|  |  |  |                     vkd3d_string_buffer_printf(buffer, "%#xu", reg->u.immconst_u32[0]); | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-20 01:30:58 +05:30
										 |  |  |                 case VSIR_DIMENSION_VEC4: | 
					
						
							|  |  |  |                     vkd3d_string_buffer_printf(buffer, "uvec4(%#xu, %#xu, %#xu, %#xu)", | 
					
						
							|  |  |  |                             reg->u.immconst_u32[0], reg->u.immconst_u32[1], | 
					
						
							|  |  |  |                             reg->u.immconst_u32[2], reg->u.immconst_u32[3]); | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 08:26:51 +05:30
										 |  |  |                 default: | 
					
						
							|  |  |  |                     vkd3d_string_buffer_printf(buffer, "<unhandled_dimension %#x>", reg->dimension); | 
					
						
							|  |  |  |                     vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                             "Internal compiler error: Unhandled dimension %#x.", reg->dimension); | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-25 00:35:48 +01:00
										 |  |  |         case VKD3DSPR_CONSTBUFFER: | 
					
						
							|  |  |  |             if (reg->idx_count != 3) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                         "Internal compiler error: Unhandled constant buffer register index count %u.", reg->idx_count); | 
					
						
							|  |  |  |                 vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type); | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-02-12 12:46:39 -05:00
										 |  |  |             if (reg->idx[0].rel_addr) | 
					
						
							| 
									
										
										
										
											2024-02-25 00:35:48 +01:00
										 |  |  |             { | 
					
						
							|  |  |  |                 vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                         "Internal compiler error: Unhandled constant buffer register indirect addressing."); | 
					
						
							|  |  |  |                 vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type); | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-02-12 12:46:39 -05:00
										 |  |  |             vkd3d_string_buffer_printf(buffer, "%s_cb_%u", gen->prefix, reg->idx[0].offset); | 
					
						
							|  |  |  |             shader_glsl_print_subscript(buffer, gen, reg->idx[2].rel_addr, reg->idx[2].offset); | 
					
						
							| 
									
										
										
										
											2024-02-25 00:35:48 +01:00
										 |  |  |             break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-06 22:15:58 +02:00
										 |  |  |         case VKD3DSPR_THREADID: | 
					
						
							|  |  |  |             vkd3d_string_buffer_printf(buffer, "gl_GlobalInvocationID"); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 21:11:57 +02:00
										 |  |  |         case VKD3DSPR_IDXTEMP: | 
					
						
							|  |  |  |             vkd3d_string_buffer_printf(buffer, "x%u", reg->idx[0].offset); | 
					
						
							|  |  |  |             shader_glsl_print_subscript(buffer, gen, reg->idx[1].rel_addr, reg->idx[1].offset); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-23 21:02:31 +05:30
										 |  |  |         default: | 
					
						
							|  |  |  |             vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                     "Internal compiler error: Unhandled register type %#x.", reg->type); | 
					
						
							|  |  |  |             vkd3d_string_buffer_printf(buffer, "<unrecognised register %#x>", reg->type); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void shader_glsl_print_swizzle(struct vkd3d_string_buffer *buffer, uint32_t swizzle, uint32_t mask) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const char swizzle_chars[] = "xyzw"; | 
					
						
							|  |  |  |     unsigned int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(buffer, "."); | 
					
						
							|  |  |  |     for (i = 0; i < VKD3D_VEC4_SIZE; ++i) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (mask & (VKD3DSP_WRITEMASK_0 << i)) | 
					
						
							|  |  |  |             vkd3d_string_buffer_printf(buffer, "%c", swizzle_chars[vsir_swizzle_get_component(swizzle, i)]); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void shader_glsl_print_write_mask(struct vkd3d_string_buffer *buffer, uint32_t write_mask) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(buffer, "."); | 
					
						
							|  |  |  |     if (write_mask & VKD3DSP_WRITEMASK_0) | 
					
						
							|  |  |  |         vkd3d_string_buffer_printf(buffer, "x"); | 
					
						
							|  |  |  |     if (write_mask & VKD3DSP_WRITEMASK_1) | 
					
						
							|  |  |  |         vkd3d_string_buffer_printf(buffer, "y"); | 
					
						
							|  |  |  |     if (write_mask & VKD3DSP_WRITEMASK_2) | 
					
						
							|  |  |  |         vkd3d_string_buffer_printf(buffer, "z"); | 
					
						
							|  |  |  |     if (write_mask & VKD3DSP_WRITEMASK_3) | 
					
						
							|  |  |  |         vkd3d_string_buffer_printf(buffer, "w"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void glsl_src_cleanup(struct glsl_src *src, struct vkd3d_string_buffer_cache *cache) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     vkd3d_string_buffer_release(cache, src->str); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 08:26:51 +05:30
										 |  |  | static void shader_glsl_print_bitcast(struct vkd3d_string_buffer *dst, struct vkd3d_glsl_generator *gen, | 
					
						
							| 
									
										
										
										
											2024-04-26 23:50:31 +02:00
										 |  |  |         const char *src, enum vkd3d_data_type dst_data_type, enum vkd3d_data_type src_data_type, unsigned int size) | 
					
						
							| 
									
										
										
										
											2021-08-25 08:26:51 +05:30
										 |  |  | { | 
					
						
							|  |  |  |     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, "%s", src); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-26 23:50:31 +02:00
										 |  |  |     if (src_data_type == VKD3D_DATA_FLOAT) | 
					
						
							| 
									
										
										
										
											2021-08-25 23:51:09 +05:30
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-04-26 23:50:31 +02:00
										 |  |  |         switch (dst_data_type) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             case VKD3D_DATA_INT: | 
					
						
							|  |  |  |                 vkd3d_string_buffer_printf(dst, "floatBitsToInt(%s)", src); | 
					
						
							|  |  |  |                 return; | 
					
						
							|  |  |  |             case VKD3D_DATA_UINT: | 
					
						
							|  |  |  |                 vkd3d_string_buffer_printf(dst, "floatBitsToUint(%s)", src); | 
					
						
							|  |  |  |                 return; | 
					
						
							|  |  |  |             default: | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-08-25 23:51:09 +05:30
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-26 23:50:31 +02:00
										 |  |  |     if (src_data_type == VKD3D_DATA_UINT) | 
					
						
							| 
									
										
										
										
											2021-08-25 08:26:51 +05:30
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-04-26 23:50:31 +02:00
										 |  |  |         switch (dst_data_type) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             case VKD3D_DATA_FLOAT: | 
					
						
							|  |  |  |                 vkd3d_string_buffer_printf(dst, "uintBitsToFloat(%s)", src); | 
					
						
							|  |  |  |                 return; | 
					
						
							|  |  |  |             case VKD3D_DATA_INT: | 
					
						
							|  |  |  |                 if (size == 1) | 
					
						
							|  |  |  |                     vkd3d_string_buffer_printf(dst, "int(%s)", src); | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                     vkd3d_string_buffer_printf(dst, "ivec%u(%s)", size, src); | 
					
						
							|  |  |  |                 return; | 
					
						
							|  |  |  |             default: | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-08-25 08:26:51 +05:30
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |             "Internal compiler error: Unhandled bitcast from %#x to %#x.", | 
					
						
							|  |  |  |             src_data_type, dst_data_type); | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(dst, "%s", src); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-05 20:48:51 +02:00
										 |  |  | static void shader_glsl_print_src(struct vkd3d_string_buffer *buffer, struct vkd3d_glsl_generator *gen, | 
					
						
							|  |  |  |         const struct vkd3d_shader_src_param *vsir_src, uint32_t mask, enum vkd3d_data_type data_type) | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  | { | 
					
						
							|  |  |  |     const struct vkd3d_shader_register *reg = &vsir_src->reg; | 
					
						
							| 
									
										
										
										
											2024-04-12 18:39:01 +02:00
										 |  |  |     struct vkd3d_string_buffer *register_name, *str; | 
					
						
							| 
									
										
										
										
											2021-08-25 08:26:51 +05:30
										 |  |  |     enum vkd3d_data_type src_data_type; | 
					
						
							| 
									
										
										
										
											2024-04-26 23:50:31 +02:00
										 |  |  |     unsigned int size; | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 08:26:51 +05:30
										 |  |  |     register_name = vkd3d_string_buffer_get(&gen->string_buffers); | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  | 
 | 
					
						
							|  |  |  |     if (reg->non_uniform) | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							| 
									
										
										
										
											2024-08-17 00:23:51 +02:00
										 |  |  |                 "Internal compiler error: Unhandled 'non-uniform' modifier."); | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-06 22:15:58 +02:00
										 |  |  |     if (reg->type == VKD3DSPR_IMMCONST || reg->type == VKD3DSPR_THREADID) | 
					
						
							| 
									
										
										
										
											2021-08-25 08:26:51 +05:30
										 |  |  |         src_data_type = VKD3D_DATA_UINT; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         src_data_type = VKD3D_DATA_FLOAT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     shader_glsl_print_register_name(register_name, gen, reg); | 
					
						
							| 
									
										
										
										
											2024-04-12 18:39:01 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (!vsir_src->modifiers) | 
					
						
							| 
									
										
										
										
											2024-10-05 20:48:51 +02:00
										 |  |  |         str = buffer; | 
					
						
							| 
									
										
										
										
											2024-04-12 18:39:01 +02:00
										 |  |  |     else | 
					
						
							|  |  |  |         str = vkd3d_string_buffer_get(&gen->string_buffers); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-26 23:50:31 +02:00
										 |  |  |     size = reg->dimension == VSIR_DIMENSION_VEC4 ? 4 : 1; | 
					
						
							| 
									
										
										
										
											2024-10-05 20:48:51 +02:00
										 |  |  |     shader_glsl_print_bitcast(str, gen, register_name->buffer, data_type, src_data_type, size); | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  |     if (reg->dimension == VSIR_DIMENSION_VEC4) | 
					
						
							| 
									
										
										
										
											2024-04-12 18:39:01 +02:00
										 |  |  |         shader_glsl_print_swizzle(str, vsir_src->swizzle, mask); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     switch (vsir_src->modifiers) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         case VKD3DSPSM_NONE: | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-04-27 00:37:48 +02:00
										 |  |  |         case VKD3DSPSM_NEG: | 
					
						
							| 
									
										
										
										
											2024-10-05 20:48:51 +02:00
										 |  |  |             vkd3d_string_buffer_printf(buffer, "-%s", str->buffer); | 
					
						
							| 
									
										
										
										
											2024-04-27 00:37:48 +02:00
										 |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-04-12 18:39:01 +02:00
										 |  |  |         case VKD3DSPSM_ABS: | 
					
						
							| 
									
										
										
										
											2024-10-05 20:48:51 +02:00
										 |  |  |             vkd3d_string_buffer_printf(buffer, "abs(%s)", str->buffer); | 
					
						
							| 
									
										
										
										
											2024-04-12 18:39:01 +02:00
										 |  |  |             break; | 
					
						
							| 
									
										
										
										
											2025-05-29 21:44:36 +02:00
										 |  |  |         case VKD3DSPSM_ABSNEG: | 
					
						
							|  |  |  |             vkd3d_string_buffer_printf(buffer, "-abs(%s)", str->buffer); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-04-12 18:39:01 +02:00
										 |  |  |         default: | 
					
						
							| 
									
										
										
										
											2024-10-05 20:48:51 +02:00
										 |  |  |             vkd3d_string_buffer_printf(buffer, "<unhandled modifier %#x>(%s)", | 
					
						
							| 
									
										
										
										
											2024-04-12 18:39:01 +02:00
										 |  |  |                     vsir_src->modifiers, str->buffer); | 
					
						
							|  |  |  |             vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                     "Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-08-25 08:26:51 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-05 20:48:51 +02:00
										 |  |  |     if (str != buffer) | 
					
						
							| 
									
										
										
										
											2024-04-12 18:39:01 +02:00
										 |  |  |         vkd3d_string_buffer_release(&gen->string_buffers, str); | 
					
						
							| 
									
										
										
										
											2021-08-25 08:26:51 +05:30
										 |  |  |     vkd3d_string_buffer_release(&gen->string_buffers, register_name); | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-05 20:48:51 +02:00
										 |  |  | static void glsl_src_init(struct glsl_src *glsl_src, struct vkd3d_glsl_generator *gen, | 
					
						
							|  |  |  |         const struct vkd3d_shader_src_param *vsir_src, uint32_t mask) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     glsl_src->str = vkd3d_string_buffer_get(&gen->string_buffers); | 
					
						
							|  |  |  |     shader_glsl_print_src(glsl_src->str, gen, vsir_src, mask, vsir_src->reg.data_type); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  | static void glsl_dst_cleanup(struct glsl_dst *dst, struct vkd3d_string_buffer_cache *cache) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     vkd3d_string_buffer_release(cache, dst->mask); | 
					
						
							|  |  |  |     vkd3d_string_buffer_release(cache, dst->register_name); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static uint32_t glsl_dst_init(struct glsl_dst *glsl_dst, struct vkd3d_glsl_generator *gen, | 
					
						
							|  |  |  |         const struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_dst_param *vsir_dst) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     uint32_t write_mask = vsir_dst->write_mask; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ins->flags & VKD3DSI_PRECISE_XYZW) | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							| 
									
										
										
										
											2024-08-17 00:23:51 +02:00
										 |  |  |                 "Internal compiler error: Unhandled 'precise' modifier."); | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  |     if (vsir_dst->reg.non_uniform) | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							| 
									
										
										
										
											2024-08-17 00:23:51 +02:00
										 |  |  |                 "Internal compiler error: Unhandled 'non-uniform' modifier."); | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  | 
 | 
					
						
							|  |  |  |     glsl_dst->vsir = vsir_dst; | 
					
						
							|  |  |  |     glsl_dst->register_name = vkd3d_string_buffer_get(&gen->string_buffers); | 
					
						
							|  |  |  |     glsl_dst->mask = vkd3d_string_buffer_get(&gen->string_buffers); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     shader_glsl_print_register_name(glsl_dst->register_name, gen, &vsir_dst->reg); | 
					
						
							|  |  |  |     shader_glsl_print_write_mask(glsl_dst->mask, write_mask); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return write_mask; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 21:11:57 +02:00
										 |  |  | static void shader_glsl_print_subscript(struct vkd3d_string_buffer *buffer, struct vkd3d_glsl_generator *gen, | 
					
						
							|  |  |  |         const struct vkd3d_shader_src_param *rel_addr, unsigned int offset) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     struct glsl_src r; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!rel_addr) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         vkd3d_string_buffer_printf(buffer, "[%u]", offset); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     glsl_src_init(&r, gen, rel_addr, VKD3DSP_WRITEMASK_0); | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(buffer, "[%s", r.str->buffer); | 
					
						
							|  |  |  |     if (offset) | 
					
						
							|  |  |  |         vkd3d_string_buffer_printf(buffer, " + %u", offset); | 
					
						
							| 
									
										
										
										
											2025-02-12 12:46:39 -05:00
										 |  |  |     vkd3d_string_buffer_printf(buffer, "]"); | 
					
						
							| 
									
										
										
										
											2024-09-30 21:11:57 +02:00
										 |  |  |     glsl_src_cleanup(&r, &gen->string_buffers); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  | static void VKD3D_PRINTF_FUNC(4, 0) shader_glsl_vprint_assignment(struct vkd3d_glsl_generator *gen, | 
					
						
							|  |  |  |         struct glsl_dst *dst, enum vkd3d_data_type data_type, const char *format, va_list args) | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-08-25 23:51:09 +05:30
										 |  |  |     struct vkd3d_string_buffer *buffer = gen->buffer; | 
					
						
							| 
									
										
										
										
											2024-05-04 00:48:22 +02:00
										 |  |  |     uint32_t modifiers = dst->vsir->modifiers; | 
					
						
							| 
									
										
										
										
											2021-08-25 23:51:09 +05:30
										 |  |  |     bool close = true; | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-29 21:48:20 +02:00
										 |  |  |     /* It is always legitimate to ignore _pp. */ | 
					
						
							|  |  |  |     modifiers &= ~VKD3DSPDM_PARTIALPRECISION; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  |     if (dst->vsir->shift) | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                 "Internal compiler error: Unhandled destination shift %#x.", dst->vsir->shift); | 
					
						
							| 
									
										
										
										
											2024-05-04 00:48:22 +02:00
										 |  |  |     if (modifiers & ~VKD3DSPDM_SATURATE) | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							| 
									
										
										
										
											2024-05-04 00:48:22 +02:00
										 |  |  |                 "Internal compiler error: Unhandled destination modifier(s) %#x.", modifiers); | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 23:51:09 +05:30
										 |  |  |     shader_glsl_print_indent(buffer, gen->indent); | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(buffer, "%s%s = ", dst->register_name->buffer, dst->mask->buffer); | 
					
						
							| 
									
										
										
										
											2024-05-04 00:48:22 +02:00
										 |  |  |     if (modifiers & VKD3DSPDM_SATURATE) | 
					
						
							|  |  |  |         vkd3d_string_buffer_printf(buffer, "clamp("); | 
					
						
							| 
									
										
										
										
											2021-08-25 23:51:09 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |     switch (data_type) | 
					
						
							| 
									
										
										
										
											2021-08-25 23:51:09 +05:30
										 |  |  |     { | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |                     "Internal compiler error: Unhandled destination register data type %#x.", data_type); | 
					
						
							| 
									
										
										
										
											2021-08-25 23:51:09 +05:30
										 |  |  |             /* fall through */ | 
					
						
							|  |  |  |         case VKD3D_DATA_FLOAT: | 
					
						
							|  |  |  |             close = false; | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-05-01 13:52:14 +02:00
										 |  |  |         case VKD3D_DATA_INT: | 
					
						
							|  |  |  |             vkd3d_string_buffer_printf(buffer, "intBitsToFloat("); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2021-08-25 23:51:09 +05:30
										 |  |  |         case VKD3D_DATA_UINT: | 
					
						
							|  |  |  |             vkd3d_string_buffer_printf(buffer, "uintBitsToFloat("); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 23:51:09 +05:30
										 |  |  |     vkd3d_string_buffer_vprintf(buffer, format, args); | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-04 00:48:22 +02:00
										 |  |  |     if (close) | 
					
						
							|  |  |  |         vkd3d_string_buffer_printf(buffer, ")"); | 
					
						
							|  |  |  |     if (modifiers & VKD3DSPDM_SATURATE) | 
					
						
							|  |  |  |         vkd3d_string_buffer_printf(buffer, ", 0.0, 1.0)"); | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(buffer, ";\n"); | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  | static void VKD3D_PRINTF_FUNC(3, 4) shader_glsl_print_assignment( | 
					
						
							|  |  |  |         struct vkd3d_glsl_generator *gen, struct glsl_dst *dst, const char *format, ...) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     va_list args; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     va_start(args, format); | 
					
						
							|  |  |  |     shader_glsl_vprint_assignment(gen, dst, dst->vsir->reg.data_type, format, args); | 
					
						
							|  |  |  |     va_end(args); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void VKD3D_PRINTF_FUNC(4, 5) shader_glsl_print_assignment_ext(struct vkd3d_glsl_generator *gen, | 
					
						
							|  |  |  |         struct glsl_dst *dst, enum vkd3d_data_type data_type, const char *format, ...) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     va_list args; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     va_start(args, format); | 
					
						
							|  |  |  |     shader_glsl_vprint_assignment(gen, dst, data_type, format, args); | 
					
						
							|  |  |  |     va_end(args); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-17 07:06:11 +01:00
										 |  |  | static void shader_glsl_unhandled(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2025-06-03 13:58:22 +02:00
										 |  |  |     const char *name = vsir_opcode_get_name(ins->opcode, "<unknown>"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  |     shader_glsl_print_indent(gen->buffer, gen->indent); | 
					
						
							| 
									
										
										
										
											2025-06-03 13:58:22 +02:00
										 |  |  |     vkd3d_string_buffer_printf(gen->buffer, "/* <unhandled instruction \"%s\" (%#x)> */\n", name, ins->opcode); | 
					
						
							| 
									
										
										
										
											2023-11-17 07:06:11 +01:00
										 |  |  |     vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							| 
									
										
										
										
											2025-06-03 13:58:22 +02:00
										 |  |  |             "Internal compiler error: Unhandled instruction \"%s\" (%#x).", name, ins->opcode); | 
					
						
							| 
									
										
										
										
											2023-11-17 07:06:11 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-28 14:32:54 +05:30
										 |  |  | static void shader_glsl_binop(struct vkd3d_glsl_generator *gen, | 
					
						
							|  |  |  |         const struct vkd3d_shader_instruction *ins, const char *op) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     struct glsl_src src[2]; | 
					
						
							|  |  |  |     struct glsl_dst dst; | 
					
						
							|  |  |  |     uint32_t mask; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     mask = glsl_dst_init(&dst, gen, ins, &ins->dst[0]); | 
					
						
							|  |  |  |     glsl_src_init(&src[0], gen, &ins->src[0], mask); | 
					
						
							|  |  |  |     glsl_src_init(&src[1], gen, &ins->src[1], mask); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     shader_glsl_print_assignment(gen, &dst, "%s %s %s", src[0].str->buffer, op, src[1].str->buffer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     glsl_src_cleanup(&src[1], &gen->string_buffers); | 
					
						
							|  |  |  |     glsl_src_cleanup(&src[0], &gen->string_buffers); | 
					
						
							|  |  |  |     glsl_dst_cleanup(&dst, &gen->string_buffers); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-02 01:15:29 +02:00
										 |  |  | static void shader_glsl_dot(struct vkd3d_glsl_generator *gen, | 
					
						
							|  |  |  |         const struct vkd3d_shader_instruction *ins, uint32_t src_mask) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     unsigned int component_count; | 
					
						
							|  |  |  |     struct glsl_src src[2]; | 
					
						
							|  |  |  |     struct glsl_dst dst; | 
					
						
							|  |  |  |     uint32_t dst_mask; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     dst_mask = glsl_dst_init(&dst, gen, ins, &ins->dst[0]); | 
					
						
							|  |  |  |     glsl_src_init(&src[0], gen, &ins->src[0], src_mask); | 
					
						
							|  |  |  |     glsl_src_init(&src[1], gen, &ins->src[1], src_mask); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((component_count = vsir_write_mask_component_count(dst_mask)) > 1) | 
					
						
							|  |  |  |         shader_glsl_print_assignment(gen, &dst, "vec%d(dot(%s, %s))", | 
					
						
							|  |  |  |                 component_count, src[0].str->buffer, src[1].str->buffer); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         shader_glsl_print_assignment(gen, &dst, "dot(%s, %s)", | 
					
						
							|  |  |  |                 src[0].str->buffer, src[1].str->buffer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     glsl_src_cleanup(&src[1], &gen->string_buffers); | 
					
						
							|  |  |  |     glsl_src_cleanup(&src[0], &gen->string_buffers); | 
					
						
							|  |  |  |     glsl_dst_cleanup(&dst, &gen->string_buffers); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-28 18:53:51 +02:00
										 |  |  | static void shader_glsl_intrinsic(struct vkd3d_glsl_generator *gen, | 
					
						
							|  |  |  |         const struct vkd3d_shader_instruction *ins, const char *op) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-05-03 15:33:00 +02:00
										 |  |  |     struct vkd3d_string_buffer *args; | 
					
						
							| 
									
										
										
										
											2024-04-28 18:53:51 +02:00
										 |  |  |     struct glsl_src src; | 
					
						
							|  |  |  |     struct glsl_dst dst; | 
					
						
							| 
									
										
										
										
											2024-05-03 15:33:00 +02:00
										 |  |  |     unsigned int i; | 
					
						
							| 
									
										
										
										
											2024-04-28 18:53:51 +02:00
										 |  |  |     uint32_t mask; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     mask = glsl_dst_init(&dst, gen, ins, &ins->dst[0]); | 
					
						
							| 
									
										
										
										
											2024-05-03 15:33:00 +02:00
										 |  |  |     args = vkd3d_string_buffer_get(&gen->string_buffers); | 
					
						
							| 
									
										
										
										
											2024-04-28 18:53:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-03 15:33:00 +02:00
										 |  |  |     for (i = 0; i < ins->src_count; ++i) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         glsl_src_init(&src, gen, &ins->src[i], mask); | 
					
						
							|  |  |  |         vkd3d_string_buffer_printf(args, "%s%s", i ? ", " : "", src.str->buffer); | 
					
						
							|  |  |  |         glsl_src_cleanup(&src, &gen->string_buffers); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     shader_glsl_print_assignment(gen, &dst, "%s(%s)", op, args->buffer); | 
					
						
							| 
									
										
										
										
											2024-04-28 18:53:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-03 15:33:00 +02:00
										 |  |  |     vkd3d_string_buffer_release(&gen->string_buffers, args); | 
					
						
							| 
									
										
										
										
											2024-04-28 18:53:51 +02:00
										 |  |  |     glsl_dst_cleanup(&dst, &gen->string_buffers); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-22 21:41:23 +02:00
										 |  |  | static void shader_glsl_relop(struct vkd3d_glsl_generator *gen, | 
					
						
							|  |  |  |         const struct vkd3d_shader_instruction *ins, const char *scalar_op, const char *vector_op) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     unsigned int mask_size; | 
					
						
							|  |  |  |     struct glsl_src src[2]; | 
					
						
							|  |  |  |     struct glsl_dst dst; | 
					
						
							|  |  |  |     uint32_t mask; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     mask = glsl_dst_init(&dst, gen, ins, &ins->dst[0]); | 
					
						
							|  |  |  |     glsl_src_init(&src[0], gen, &ins->src[0], mask); | 
					
						
							|  |  |  |     glsl_src_init(&src[1], gen, &ins->src[1], mask); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((mask_size = vsir_write_mask_component_count(mask)) > 1) | 
					
						
							|  |  |  |         shader_glsl_print_assignment(gen, &dst, "uvec%u(%s(%s, %s)) * 0xffffffffu", | 
					
						
							|  |  |  |                 mask_size, vector_op, src[0].str->buffer, src[1].str->buffer); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         shader_glsl_print_assignment(gen, &dst, "%s %s %s ? 0xffffffffu : 0u", | 
					
						
							|  |  |  |                 src[0].str->buffer, scalar_op, src[1].str->buffer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     glsl_src_cleanup(&src[1], &gen->string_buffers); | 
					
						
							|  |  |  |     glsl_src_cleanup(&src[0], &gen->string_buffers); | 
					
						
							|  |  |  |     glsl_dst_cleanup(&dst, &gen->string_buffers); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  | static void shader_glsl_cast(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins, | 
					
						
							|  |  |  |         const char *scalar_constructor, const char *vector_constructor) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     unsigned int component_count; | 
					
						
							|  |  |  |     struct glsl_src src; | 
					
						
							|  |  |  |     struct glsl_dst dst; | 
					
						
							|  |  |  |     uint32_t mask; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     mask = glsl_dst_init(&dst, gen, ins, &ins->dst[0]); | 
					
						
							|  |  |  |     glsl_src_init(&src, gen, &ins->src[0], mask); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((component_count = vsir_write_mask_component_count(mask)) > 1) | 
					
						
							|  |  |  |         shader_glsl_print_assignment(gen, &dst, "%s%u(%s)", | 
					
						
							|  |  |  |                 vector_constructor, component_count, src.str->buffer); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         shader_glsl_print_assignment(gen, &dst, "%s(%s)", | 
					
						
							|  |  |  |                 scalar_constructor, src.str->buffer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     glsl_src_cleanup(&src, &gen->string_buffers); | 
					
						
							|  |  |  |     glsl_dst_cleanup(&dst, &gen->string_buffers); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-03 15:07:16 +02:00
										 |  |  | static void shader_glsl_end_block(struct vkd3d_glsl_generator *gen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     --gen->indent; | 
					
						
							|  |  |  |     shader_glsl_print_indent(gen->buffer, gen->indent); | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(gen->buffer, "}\n"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void shader_glsl_begin_block(struct vkd3d_glsl_generator *gen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     shader_glsl_print_indent(gen->buffer, gen->indent); | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(gen->buffer, "{\n"); | 
					
						
							|  |  |  |     ++gen->indent; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-03 14:21:01 +02:00
										 |  |  | static void shader_glsl_if(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const char *condition; | 
					
						
							|  |  |  |     struct glsl_src src; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     glsl_src_init(&src, gen, &ins->src[0], VKD3DSP_WRITEMASK_0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     shader_glsl_print_indent(gen->buffer, gen->indent); | 
					
						
							|  |  |  |     condition = ins->flags == VKD3D_SHADER_CONDITIONAL_OP_NZ ? "bool" : "!bool"; | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(gen->buffer, "if (%s(%s))\n", condition, src.str->buffer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     glsl_src_cleanup(&src, &gen->string_buffers); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-03 15:07:16 +02:00
										 |  |  |     shader_glsl_begin_block(gen); | 
					
						
							| 
									
										
										
										
											2024-05-03 14:21:01 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-03 21:35:39 +02:00
										 |  |  | static void shader_glsl_else(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-10-03 15:07:16 +02:00
										 |  |  |     shader_glsl_end_block(gen); | 
					
						
							|  |  |  |     shader_glsl_print_indent(gen->buffer, gen->indent); | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(gen->buffer, "else\n"); | 
					
						
							|  |  |  |     shader_glsl_begin_block(gen); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-05-03 21:35:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-03 15:07:16 +02:00
										 |  |  | static void shader_glsl_loop(struct vkd3d_glsl_generator *gen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     shader_glsl_print_indent(gen->buffer, gen->indent); | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(gen->buffer, "for (;;)\n"); | 
					
						
							|  |  |  |     shader_glsl_begin_block(gen); | 
					
						
							| 
									
										
										
										
											2024-05-03 21:35:39 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-03 15:07:16 +02:00
										 |  |  | static void shader_glsl_break(struct vkd3d_glsl_generator *gen) | 
					
						
							| 
									
										
										
										
											2024-05-03 14:21:01 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     shader_glsl_print_indent(gen->buffer, gen->indent); | 
					
						
							| 
									
										
										
										
											2024-10-03 15:07:16 +02:00
										 |  |  |     vkd3d_string_buffer_printf(gen->buffer, "break;\n"); | 
					
						
							| 
									
										
										
										
											2024-05-03 14:21:01 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-03 16:14:36 +02:00
										 |  |  | static void shader_glsl_continue(struct vkd3d_glsl_generator *gen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     shader_glsl_print_indent(gen->buffer, gen->indent); | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(gen->buffer, "continue;\n"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-03 15:46:07 +02:00
										 |  |  | static void shader_glsl_switch(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     struct glsl_src src; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     glsl_src_init(&src, gen, &ins->src[0], VKD3DSP_WRITEMASK_0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     shader_glsl_print_indent(gen->buffer, gen->indent); | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(gen->buffer, "switch (%s)\n", src.str->buffer); | 
					
						
							|  |  |  |     shader_glsl_begin_block(gen); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     glsl_src_cleanup(&src, &gen->string_buffers); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void shader_glsl_case(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     struct glsl_src src; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     glsl_src_init(&src, gen, &ins->src[0], VKD3DSP_WRITEMASK_0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     shader_glsl_print_indent(gen->buffer, gen->indent); | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(gen->buffer, "case %s:\n", src.str->buffer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     glsl_src_cleanup(&src, &gen->string_buffers); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void shader_glsl_default(struct vkd3d_glsl_generator *gen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     shader_glsl_print_indent(gen->buffer, gen->indent); | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(gen->buffer, "default:\n"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-20 13:31:38 +02:00
										 |  |  | static void shader_glsl_print_texel_offset(struct vkd3d_string_buffer *buffer, struct vkd3d_glsl_generator *gen, | 
					
						
							|  |  |  |         unsigned int offset_size, const struct vkd3d_shader_texel_offset *offset) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     switch (offset_size) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         case 1: | 
					
						
							|  |  |  |             vkd3d_string_buffer_printf(buffer, "%d", offset->u); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case 2: | 
					
						
							|  |  |  |             vkd3d_string_buffer_printf(buffer, "ivec2(%d, %d)", offset->u, offset->v); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                     "Internal compiler error: Invalid texel offset size %u.", offset_size); | 
					
						
							|  |  |  |             /* fall through */ | 
					
						
							|  |  |  |         case 3: | 
					
						
							|  |  |  |             vkd3d_string_buffer_printf(buffer, "ivec3(%d, %d, %d)", offset->u, offset->v, offset->w); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  | static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-10-09 13:34:21 +02:00
										 |  |  |     unsigned int resource_id, resource_idx, resource_space, sample_count; | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |     const struct glsl_resource_type_info *resource_type_info; | 
					
						
							|  |  |  |     const struct vkd3d_shader_descriptor_info1 *d; | 
					
						
							|  |  |  |     enum vkd3d_shader_resource_type resource_type; | 
					
						
							|  |  |  |     struct vkd3d_string_buffer *fetch; | 
					
						
							|  |  |  |     enum vkd3d_data_type data_type; | 
					
						
							| 
									
										
										
										
											2024-10-09 13:34:21 +02:00
										 |  |  |     struct glsl_src coord; | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |     struct glsl_dst dst; | 
					
						
							|  |  |  |     uint32_t coord_mask; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (vkd3d_shader_instruction_has_texel_offset(ins)) | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                 "Internal compiler error: Unhandled texel fetch offset."); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ins->src[1].reg.idx[0].rel_addr || ins->src[1].reg.idx[1].rel_addr) | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_UNSUPPORTED, | 
					
						
							|  |  |  |                 "Descriptor indexing is not supported."); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resource_id = ins->src[1].reg.idx[0].offset; | 
					
						
							|  |  |  |     resource_idx = ins->src[1].reg.idx[1].offset; | 
					
						
							|  |  |  |     if ((d = shader_glsl_get_descriptor_by_id(gen, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource_id))) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         resource_type = d->resource_type; | 
					
						
							|  |  |  |         resource_space = d->register_space; | 
					
						
							| 
									
										
										
										
											2024-10-09 13:34:21 +02:00
										 |  |  |         sample_count = d->sample_count; | 
					
						
							| 
									
										
										
										
											2025-04-03 22:46:57 +02:00
										 |  |  |         data_type = d->resource_data_type; | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                 "Internal compiler error: Undeclared resource descriptor %u.", resource_id); | 
					
						
							|  |  |  |         resource_space = 0; | 
					
						
							|  |  |  |         resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; | 
					
						
							| 
									
										
										
										
											2024-10-09 13:34:21 +02:00
										 |  |  |         sample_count = 1; | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |         data_type = VKD3D_DATA_FLOAT; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type))) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->coord_size); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                 "Internal compiler error: Unhandled resource type %#x.", resource_type); | 
					
						
							|  |  |  |         coord_mask = vkd3d_write_mask_from_component_count(2); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     glsl_dst_init(&dst, gen, ins, &ins->dst[0]); | 
					
						
							|  |  |  |     glsl_src_init(&coord, gen, &ins->src[0], coord_mask); | 
					
						
							|  |  |  |     fetch = vkd3d_string_buffer_get(&gen->string_buffers); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(fetch, "texelFetch("); | 
					
						
							|  |  |  |     shader_glsl_print_combined_sampler_name(fetch, gen, resource_idx, | 
					
						
							|  |  |  |             resource_space, VKD3D_SHADER_DUMMY_SAMPLER_INDEX, 0); | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(fetch, ", %s", coord.str->buffer); | 
					
						
							|  |  |  |     if (resource_type != VKD3D_SHADER_RESOURCE_BUFFER) | 
					
						
							| 
									
										
										
										
											2024-10-09 13:34:21 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         vkd3d_string_buffer_printf(fetch, ", "); | 
					
						
							|  |  |  |         if (ins->opcode != VKD3DSIH_LD2DMS) | 
					
						
							|  |  |  |             shader_glsl_print_src(fetch, gen, &ins->src[0], VKD3DSP_WRITEMASK_3, ins->src[0].reg.data_type); | 
					
						
							|  |  |  |         else if (sample_count == 1) | 
					
						
							|  |  |  |             /* If the resource isn't a true multisample resource, this is the
 | 
					
						
							|  |  |  |              * "lod" parameter instead of the "sample" parameter. */ | 
					
						
							|  |  |  |             vkd3d_string_buffer_printf(fetch, "0"); | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             shader_glsl_print_src(fetch, gen, &ins->src[2], VKD3DSP_WRITEMASK_0, ins->src[2].reg.data_type); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |     vkd3d_string_buffer_printf(fetch, ")"); | 
					
						
							|  |  |  |     shader_glsl_print_swizzle(fetch, ins->src[1].swizzle, ins->dst[0].write_mask); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     shader_glsl_print_assignment_ext(gen, &dst, data_type, "%s", fetch->buffer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     vkd3d_string_buffer_release(&gen->string_buffers, fetch); | 
					
						
							|  |  |  |     glsl_src_cleanup(&coord, &gen->string_buffers); | 
					
						
							|  |  |  |     glsl_dst_cleanup(&dst, &gen->string_buffers); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-18 17:35:26 +02:00
										 |  |  | static void shader_glsl_print_shadow_coord(struct vkd3d_string_buffer *buffer, struct vkd3d_glsl_generator *gen, | 
					
						
							|  |  |  |         const struct vkd3d_shader_src_param *coord, const struct vkd3d_shader_src_param *ref, unsigned int coord_size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     uint32_t coord_mask = vkd3d_write_mask_from_component_count(coord_size); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     switch (coord_size) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         case 1: | 
					
						
							|  |  |  |             vkd3d_string_buffer_printf(buffer, "vec3("); | 
					
						
							|  |  |  |             shader_glsl_print_src(buffer, gen, coord, coord_mask, coord->reg.data_type); | 
					
						
							|  |  |  |             vkd3d_string_buffer_printf(buffer, ", 0.0, "); | 
					
						
							|  |  |  |             shader_glsl_print_src(buffer, gen, ref, VKD3DSP_WRITEMASK_0, ref->reg.data_type); | 
					
						
							|  |  |  |             vkd3d_string_buffer_printf(buffer, ")"); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         case 4: | 
					
						
							|  |  |  |             shader_glsl_print_src(buffer, gen, coord, coord_mask, coord->reg.data_type); | 
					
						
							|  |  |  |             vkd3d_string_buffer_printf(buffer, ", "); | 
					
						
							|  |  |  |             shader_glsl_print_src(buffer, gen, ref, VKD3DSP_WRITEMASK_0, ref->reg.data_type); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             vkd3d_string_buffer_printf(buffer, "vec%u(", coord_size + 1); | 
					
						
							|  |  |  |             shader_glsl_print_src(buffer, gen, coord, coord_mask, coord->reg.data_type); | 
					
						
							|  |  |  |             vkd3d_string_buffer_printf(buffer, ", "); | 
					
						
							|  |  |  |             shader_glsl_print_src(buffer, gen, ref, VKD3DSP_WRITEMASK_0, ref->reg.data_type); | 
					
						
							|  |  |  |             vkd3d_string_buffer_printf(buffer, ")"); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-29 21:04:57 +02:00
										 |  |  | static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-10-20 13:31:38 +02:00
										 |  |  |     bool shadow_sampler, array, bias, dynamic_offset, gather, grad, lod, lod_zero, offset, shadow; | 
					
						
							| 
									
										
										
										
											2024-09-29 21:04:57 +02:00
										 |  |  |     const struct glsl_resource_type_info *resource_type_info; | 
					
						
							| 
									
										
										
										
											2024-10-19 19:03:54 +02:00
										 |  |  |     const struct vkd3d_shader_src_param *resource, *sampler; | 
					
						
							| 
									
										
										
										
											2024-09-29 21:04:57 +02:00
										 |  |  |     unsigned int resource_id, resource_idx, resource_space; | 
					
						
							|  |  |  |     unsigned int sampler_id, sampler_idx, sampler_space; | 
					
						
							|  |  |  |     const struct vkd3d_shader_descriptor_info1 *d; | 
					
						
							|  |  |  |     enum vkd3d_shader_resource_type resource_type; | 
					
						
							| 
									
										
										
										
											2024-10-19 17:21:01 +02:00
										 |  |  |     unsigned int component_idx, coord_size; | 
					
						
							| 
									
										
										
										
											2024-09-29 21:04:57 +02:00
										 |  |  |     struct vkd3d_string_buffer *sample; | 
					
						
							|  |  |  |     enum vkd3d_data_type data_type; | 
					
						
							|  |  |  |     struct glsl_dst dst; | 
					
						
							| 
									
										
										
										
											2024-10-18 20:45:57 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     bias = ins->opcode == VKD3DSIH_SAMPLE_B; | 
					
						
							| 
									
										
										
										
											2024-10-20 13:31:38 +02:00
										 |  |  |     dynamic_offset = ins->opcode == VKD3DSIH_GATHER4_PO; | 
					
						
							| 
									
										
										
										
											2024-10-19 19:03:54 +02:00
										 |  |  |     gather = ins->opcode == VKD3DSIH_GATHER4 || ins->opcode == VKD3DSIH_GATHER4_PO; | 
					
						
							| 
									
										
										
										
											2024-10-18 21:21:15 +02:00
										 |  |  |     grad = ins->opcode == VKD3DSIH_SAMPLE_GRAD; | 
					
						
							| 
									
										
										
										
											2024-10-18 20:45:57 +02:00
										 |  |  |     lod = ins->opcode == VKD3DSIH_SAMPLE_LOD || ins->opcode == VKD3DSIH_SAMPLE_C_LZ; | 
					
						
							|  |  |  |     lod_zero = ins->opcode == VKD3DSIH_SAMPLE_C_LZ; | 
					
						
							| 
									
										
										
										
											2024-10-20 13:31:38 +02:00
										 |  |  |     offset = dynamic_offset || vkd3d_shader_instruction_has_texel_offset(ins); | 
					
						
							| 
									
										
										
										
											2024-10-18 20:45:57 +02:00
										 |  |  |     shadow = ins->opcode == VKD3DSIH_SAMPLE_C || ins->opcode == VKD3DSIH_SAMPLE_C_LZ; | 
					
						
							| 
									
										
										
										
											2024-09-29 21:04:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-20 13:31:38 +02:00
										 |  |  |     resource = &ins->src[1 + dynamic_offset]; | 
					
						
							|  |  |  |     sampler = &ins->src[2 + dynamic_offset]; | 
					
						
							| 
									
										
										
										
											2024-09-29 21:04:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-19 19:03:54 +02:00
										 |  |  |     if (resource->reg.idx[0].rel_addr || resource->reg.idx[1].rel_addr | 
					
						
							|  |  |  |             || sampler->reg.idx[0].rel_addr || sampler->reg.idx[1].rel_addr) | 
					
						
							| 
									
										
										
										
											2024-09-29 21:04:57 +02:00
										 |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_UNSUPPORTED, | 
					
						
							|  |  |  |                 "Descriptor indexing is not supported."); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-19 19:03:54 +02:00
										 |  |  |     resource_id = resource->reg.idx[0].offset; | 
					
						
							|  |  |  |     resource_idx = resource->reg.idx[1].offset; | 
					
						
							| 
									
										
										
										
											2024-09-29 21:04:57 +02:00
										 |  |  |     if ((d = shader_glsl_get_descriptor_by_id(gen, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource_id))) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         resource_type = d->resource_type; | 
					
						
							|  |  |  |         resource_space = d->register_space; | 
					
						
							| 
									
										
										
										
											2025-04-03 22:46:57 +02:00
										 |  |  |         data_type = d->resource_data_type; | 
					
						
							| 
									
										
										
										
											2024-09-29 21:04:57 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                 "Internal compiler error: Undeclared resource descriptor %u.", resource_id); | 
					
						
							|  |  |  |         resource_space = 0; | 
					
						
							|  |  |  |         resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; | 
					
						
							|  |  |  |         data_type = VKD3D_DATA_FLOAT; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type))) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-10-18 17:35:26 +02:00
										 |  |  |         coord_size = resource_type_info->coord_size; | 
					
						
							| 
									
										
										
										
											2024-10-18 21:21:15 +02:00
										 |  |  |         array = resource_type_info->array; | 
					
						
							| 
									
										
										
										
											2024-09-29 21:04:57 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                 "Internal compiler error: Unhandled resource type %#x.", resource_type); | 
					
						
							| 
									
										
										
										
											2024-10-18 17:35:26 +02:00
										 |  |  |         coord_size = 2; | 
					
						
							| 
									
										
										
										
											2024-10-18 21:21:15 +02:00
										 |  |  |         array = false; | 
					
						
							| 
									
										
										
										
											2024-09-29 21:04:57 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-19 19:03:54 +02:00
										 |  |  |     sampler_id = sampler->reg.idx[0].offset; | 
					
						
							|  |  |  |     sampler_idx = sampler->reg.idx[1].offset; | 
					
						
							| 
									
										
										
										
											2024-09-29 21:04:57 +02:00
										 |  |  |     if ((d = shader_glsl_get_descriptor_by_id(gen, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, sampler_id))) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         sampler_space = d->register_space; | 
					
						
							| 
									
										
										
										
											2024-10-18 20:45:57 +02:00
										 |  |  |         shadow_sampler = d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE; | 
					
						
							| 
									
										
										
										
											2024-10-18 17:35:26 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-18 20:45:57 +02:00
										 |  |  |         if (shadow) | 
					
						
							| 
									
										
										
										
											2024-10-18 17:35:26 +02:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2024-10-18 20:45:57 +02:00
										 |  |  |             if (!shadow_sampler) | 
					
						
							| 
									
										
										
										
											2024-10-18 17:35:26 +02:00
										 |  |  |                 vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                         "Internal compiler error: Sampler %u is not a comparison sampler.", sampler_id); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2024-10-18 20:45:57 +02:00
										 |  |  |             if (shadow_sampler) | 
					
						
							| 
									
										
										
										
											2024-10-18 17:35:26 +02:00
										 |  |  |                 vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                         "Internal compiler error: Sampler %u is a comparison sampler.", sampler_id); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-09-29 21:04:57 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                 "Internal compiler error: Undeclared sampler descriptor %u.", sampler_id); | 
					
						
							|  |  |  |         sampler_space = 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     glsl_dst_init(&dst, gen, ins, &ins->dst[0]); | 
					
						
							|  |  |  |     sample = vkd3d_string_buffer_get(&gen->string_buffers); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-19 17:21:01 +02:00
										 |  |  |     if (gather) | 
					
						
							| 
									
										
										
										
											2024-10-20 13:31:38 +02:00
										 |  |  |         vkd3d_string_buffer_printf(sample, "textureGather"); | 
					
						
							| 
									
										
										
										
											2024-10-19 17:21:01 +02:00
										 |  |  |     else if (grad) | 
					
						
							| 
									
										
										
										
											2024-10-20 13:31:38 +02:00
										 |  |  |         vkd3d_string_buffer_printf(sample, "textureGrad"); | 
					
						
							| 
									
										
										
										
											2024-10-18 21:21:15 +02:00
										 |  |  |     else if (lod) | 
					
						
							| 
									
										
										
										
											2024-10-20 13:31:38 +02:00
										 |  |  |         vkd3d_string_buffer_printf(sample, "textureLod"); | 
					
						
							| 
									
										
										
										
											2024-10-18 20:27:01 +02:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2024-10-20 13:31:38 +02:00
										 |  |  |         vkd3d_string_buffer_printf(sample, "texture"); | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(sample, "%s(", offset ? "Offset" : ""); | 
					
						
							| 
									
										
										
										
											2024-09-29 21:04:57 +02:00
										 |  |  |     shader_glsl_print_combined_sampler_name(sample, gen, resource_idx, resource_space, sampler_idx, sampler_space); | 
					
						
							| 
									
										
										
										
											2024-10-18 17:35:26 +02:00
										 |  |  |     vkd3d_string_buffer_printf(sample, ", "); | 
					
						
							| 
									
										
										
										
											2024-10-18 20:45:57 +02:00
										 |  |  |     if (shadow) | 
					
						
							| 
									
										
										
										
											2024-10-18 17:35:26 +02:00
										 |  |  |         shader_glsl_print_shadow_coord(sample, gen, &ins->src[0], &ins->src[3], coord_size); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         shader_glsl_print_src(sample, gen, &ins->src[0], | 
					
						
							|  |  |  |                 vkd3d_write_mask_from_component_count(coord_size), ins->src[0].reg.data_type); | 
					
						
							| 
									
										
										
										
											2024-10-18 21:21:15 +02:00
										 |  |  |     if (grad) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         vkd3d_string_buffer_printf(sample, ", "); | 
					
						
							|  |  |  |         shader_glsl_print_src(sample, gen, &ins->src[3], | 
					
						
							|  |  |  |                 vkd3d_write_mask_from_component_count(coord_size - array), ins->src[3].reg.data_type); | 
					
						
							|  |  |  |         vkd3d_string_buffer_printf(sample, ", "); | 
					
						
							|  |  |  |         shader_glsl_print_src(sample, gen, &ins->src[4], | 
					
						
							|  |  |  |                 vkd3d_write_mask_from_component_count(coord_size - array), ins->src[4].reg.data_type); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (lod_zero) | 
					
						
							| 
									
										
										
										
											2024-10-18 15:21:27 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-10-18 20:45:57 +02:00
										 |  |  |         vkd3d_string_buffer_printf(sample, ", 0.0"); | 
					
						
							| 
									
										
										
										
											2024-10-18 15:21:27 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-10-20 13:31:38 +02:00
										 |  |  |     else if (lod) | 
					
						
							| 
									
										
										
										
											2024-10-18 20:27:01 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-10-18 20:45:57 +02:00
										 |  |  |         vkd3d_string_buffer_printf(sample, ", "); | 
					
						
							|  |  |  |         shader_glsl_print_src(sample, gen, &ins->src[3], VKD3DSP_WRITEMASK_0, ins->src[3].reg.data_type); | 
					
						
							| 
									
										
										
										
											2024-10-18 20:27:01 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-10-19 19:03:54 +02:00
										 |  |  |     if (offset) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         vkd3d_string_buffer_printf(sample, ", "); | 
					
						
							| 
									
										
										
										
											2024-10-20 13:31:38 +02:00
										 |  |  |         if (dynamic_offset) | 
					
						
							|  |  |  |             shader_glsl_print_src(sample, gen, &ins->src[1], | 
					
						
							|  |  |  |                     vkd3d_write_mask_from_component_count(coord_size - array), ins->src[1].reg.data_type); | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             shader_glsl_print_texel_offset(sample, gen, coord_size - array, &ins->texel_offset); | 
					
						
							| 
									
										
										
										
											2024-10-19 19:03:54 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-10-20 13:31:38 +02:00
										 |  |  |     if (bias) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         vkd3d_string_buffer_printf(sample, ", "); | 
					
						
							|  |  |  |         shader_glsl_print_src(sample, gen, &ins->src[3], VKD3DSP_WRITEMASK_0, ins->src[3].reg.data_type); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (gather) | 
					
						
							| 
									
										
										
										
											2024-10-19 17:21:01 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-10-19 19:03:54 +02:00
										 |  |  |         if ((component_idx = vsir_swizzle_get_component(sampler->swizzle, 0))) | 
					
						
							| 
									
										
										
										
											2024-10-19 17:21:01 +02:00
										 |  |  |             vkd3d_string_buffer_printf(sample, ", %d", component_idx); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-10-18 15:21:27 +02:00
										 |  |  |     vkd3d_string_buffer_printf(sample, ")"); | 
					
						
							| 
									
										
										
										
											2024-10-19 19:03:54 +02:00
										 |  |  |     shader_glsl_print_swizzle(sample, resource->swizzle, ins->dst[0].write_mask); | 
					
						
							| 
									
										
										
										
											2024-09-29 21:04:57 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     shader_glsl_print_assignment_ext(gen, &dst, data_type, "%s", sample->buffer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     vkd3d_string_buffer_release(&gen->string_buffers, sample); | 
					
						
							|  |  |  |     glsl_dst_cleanup(&dst, &gen->string_buffers); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-06 20:58:25 +02:00
										 |  |  | static void shader_glsl_load_uav_typed(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const struct glsl_resource_type_info *resource_type_info; | 
					
						
							|  |  |  |     const struct vkd3d_shader_descriptor_info1 *d; | 
					
						
							|  |  |  |     enum vkd3d_shader_resource_type resource_type; | 
					
						
							|  |  |  |     unsigned int uav_id, uav_idx, uav_space; | 
					
						
							|  |  |  |     struct vkd3d_string_buffer *load; | 
					
						
							| 
									
										
										
										
											2025-04-03 22:46:57 +02:00
										 |  |  |     enum vkd3d_data_type data_type; | 
					
						
							| 
									
										
										
										
											2024-10-06 20:58:25 +02:00
										 |  |  |     struct glsl_src coord; | 
					
						
							|  |  |  |     struct glsl_dst dst; | 
					
						
							|  |  |  |     uint32_t coord_mask; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ins->src[1].reg.idx[0].rel_addr || ins->src[1].reg.idx[1].rel_addr) | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_UNSUPPORTED, | 
					
						
							|  |  |  |                 "Descriptor indexing is not supported."); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     uav_id = ins->src[1].reg.idx[0].offset; | 
					
						
							|  |  |  |     uav_idx = ins->src[1].reg.idx[1].offset; | 
					
						
							|  |  |  |     if ((d = shader_glsl_get_descriptor_by_id(gen, VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, uav_id))) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         resource_type = d->resource_type; | 
					
						
							|  |  |  |         uav_space = d->register_space; | 
					
						
							| 
									
										
										
										
											2025-04-03 22:46:57 +02:00
										 |  |  |         data_type = d->resource_data_type; | 
					
						
							| 
									
										
										
										
											2024-10-06 20:58:25 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                 "Internal compiler error: Undeclared UAV descriptor %u.", uav_id); | 
					
						
							|  |  |  |         uav_space = 0; | 
					
						
							|  |  |  |         resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; | 
					
						
							| 
									
										
										
										
											2025-04-03 22:46:57 +02:00
										 |  |  |         data_type = VKD3D_DATA_FLOAT; | 
					
						
							| 
									
										
										
										
											2024-10-06 20:58:25 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type))) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->coord_size); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                 "Internal compiler error: Unhandled UAV type %#x.", resource_type); | 
					
						
							|  |  |  |         coord_mask = vkd3d_write_mask_from_component_count(2); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     glsl_dst_init(&dst, gen, ins, &ins->dst[0]); | 
					
						
							|  |  |  |     glsl_src_init(&coord, gen, &ins->src[0], coord_mask); | 
					
						
							|  |  |  |     load = vkd3d_string_buffer_get(&gen->string_buffers); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(load, "imageLoad("); | 
					
						
							|  |  |  |     shader_glsl_print_image_name(load, gen, uav_idx, uav_space); | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(load, ", %s)", coord.str->buffer); | 
					
						
							|  |  |  |     shader_glsl_print_swizzle(load, ins->src[1].swizzle, ins->dst[0].write_mask); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-03 22:46:57 +02:00
										 |  |  |     shader_glsl_print_assignment_ext(gen, &dst, data_type, "%s", load->buffer); | 
					
						
							| 
									
										
										
										
											2024-10-06 20:58:25 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     vkd3d_string_buffer_release(&gen->string_buffers, load); | 
					
						
							|  |  |  |     glsl_src_cleanup(&coord, &gen->string_buffers); | 
					
						
							|  |  |  |     glsl_dst_cleanup(&dst, &gen->string_buffers); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-05 20:48:51 +02:00
										 |  |  | static void shader_glsl_store_uav_typed(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const struct glsl_resource_type_info *resource_type_info; | 
					
						
							|  |  |  |     const struct vkd3d_shader_descriptor_info1 *d; | 
					
						
							|  |  |  |     enum vkd3d_shader_resource_type resource_type; | 
					
						
							|  |  |  |     unsigned int uav_id, uav_idx, uav_space; | 
					
						
							|  |  |  |     struct vkd3d_string_buffer *image_data; | 
					
						
							| 
									
										
										
										
											2025-04-03 22:46:57 +02:00
										 |  |  |     enum vkd3d_data_type data_type; | 
					
						
							| 
									
										
										
										
											2024-10-05 20:48:51 +02:00
										 |  |  |     struct glsl_src image_coord; | 
					
						
							|  |  |  |     uint32_t coord_mask; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ins->dst[0].reg.idx[0].rel_addr || ins->dst[0].reg.idx[1].rel_addr) | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_UNSUPPORTED, | 
					
						
							|  |  |  |                 "Descriptor indexing is not supported."); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     uav_id = ins->dst[0].reg.idx[0].offset; | 
					
						
							|  |  |  |     uav_idx = ins->dst[0].reg.idx[1].offset; | 
					
						
							|  |  |  |     if ((d = shader_glsl_get_descriptor_by_id(gen, VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, uav_id))) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         resource_type = d->resource_type; | 
					
						
							|  |  |  |         uav_space = d->register_space; | 
					
						
							| 
									
										
										
										
											2025-04-03 22:46:57 +02:00
										 |  |  |         data_type = d->resource_data_type; | 
					
						
							| 
									
										
										
										
											2024-10-05 20:48:51 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                 "Internal compiler error: Undeclared UAV descriptor %u.", uav_id); | 
					
						
							|  |  |  |         uav_space = 0; | 
					
						
							|  |  |  |         resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; | 
					
						
							| 
									
										
										
										
											2025-04-03 22:46:57 +02:00
										 |  |  |         data_type = VKD3D_DATA_FLOAT; | 
					
						
							| 
									
										
										
										
											2024-10-05 20:48:51 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type))) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->coord_size); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                 "Internal compiler error: Unhandled UAV type %#x.", resource_type); | 
					
						
							|  |  |  |         coord_mask = vkd3d_write_mask_from_component_count(2); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     glsl_src_init(&image_coord, gen, &ins->src[0], coord_mask); | 
					
						
							|  |  |  |     image_data = vkd3d_string_buffer_get(&gen->string_buffers); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ins->src[1].reg.dimension == VSIR_DIMENSION_SCALAR) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2025-04-03 22:46:57 +02:00
										 |  |  |         switch (data_type) | 
					
						
							| 
									
										
										
										
											2024-10-05 20:48:51 +02:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-03 22:46:57 +02:00
										 |  |  |             case VKD3D_DATA_UINT: | 
					
						
							| 
									
										
										
										
											2024-10-05 20:48:51 +02:00
										 |  |  |                 vkd3d_string_buffer_printf(image_data, "uvec4("); | 
					
						
							|  |  |  |                 break; | 
					
						
							| 
									
										
										
										
											2025-04-03 22:46:57 +02:00
										 |  |  |             case VKD3D_DATA_INT: | 
					
						
							| 
									
										
										
										
											2024-10-05 20:48:51 +02:00
										 |  |  |                 vkd3d_string_buffer_printf(image_data, "ivec4("); | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             default: | 
					
						
							|  |  |  |                 vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							| 
									
										
										
										
											2025-04-03 22:46:57 +02:00
										 |  |  |                         "Internal compiler error: Unhandled data type %#x.", data_type); | 
					
						
							| 
									
										
										
										
											2024-10-05 20:48:51 +02:00
										 |  |  |                 /* fall through */ | 
					
						
							| 
									
										
										
										
											2025-04-03 22:46:57 +02:00
										 |  |  |             case VKD3D_DATA_FLOAT: | 
					
						
							|  |  |  |             case VKD3D_DATA_UNORM: | 
					
						
							|  |  |  |             case VKD3D_DATA_SNORM: | 
					
						
							| 
									
										
										
										
											2024-10-05 20:48:51 +02:00
										 |  |  |                 vkd3d_string_buffer_printf(image_data, "vec4("); | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2025-04-03 22:46:57 +02:00
										 |  |  |     shader_glsl_print_src(image_data, gen, &ins->src[1], VKD3DSP_WRITEMASK_ALL, data_type); | 
					
						
							| 
									
										
										
										
											2024-10-05 20:48:51 +02:00
										 |  |  |     if (ins->src[1].reg.dimension == VSIR_DIMENSION_SCALAR) | 
					
						
							|  |  |  |         vkd3d_string_buffer_printf(image_data, ", 0, 0, 0)"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     shader_glsl_print_indent(gen->buffer, gen->indent); | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(gen->buffer, "imageStore("); | 
					
						
							|  |  |  |     shader_glsl_print_image_name(gen->buffer, gen, uav_idx, uav_space); | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(gen->buffer, ", %s, %s);\n", image_coord.str->buffer, image_data->buffer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     vkd3d_string_buffer_release(&gen->string_buffers, image_data); | 
					
						
							|  |  |  |     glsl_src_cleanup(&image_coord, &gen->string_buffers); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-03 21:14:29 +02:00
										 |  |  | static void shader_glsl_unary_op(struct vkd3d_glsl_generator *gen, | 
					
						
							|  |  |  |         const struct vkd3d_shader_instruction *ins, const char *op) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     struct glsl_src src; | 
					
						
							|  |  |  |     struct glsl_dst dst; | 
					
						
							|  |  |  |     uint32_t mask; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     mask = glsl_dst_init(&dst, gen, ins, &ins->dst[0]); | 
					
						
							|  |  |  |     glsl_src_init(&src, gen, &ins->src[0], mask); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     shader_glsl_print_assignment(gen, &dst, "%s%s", op, src.str->buffer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     glsl_src_cleanup(&src, &gen->string_buffers); | 
					
						
							|  |  |  |     glsl_dst_cleanup(&dst, &gen->string_buffers); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  | static void shader_glsl_mov(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     struct glsl_src src; | 
					
						
							|  |  |  |     struct glsl_dst dst; | 
					
						
							|  |  |  |     uint32_t mask; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     mask = glsl_dst_init(&dst, gen, ins, &ins->dst[0]); | 
					
						
							|  |  |  |     glsl_src_init(&src, gen, &ins->src[0], mask); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     shader_glsl_print_assignment(gen, &dst, "%s", src.str->buffer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     glsl_src_cleanup(&src, &gen->string_buffers); | 
					
						
							|  |  |  |     glsl_dst_cleanup(&dst, &gen->string_buffers); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-29 15:32:47 +05:30
										 |  |  | static void shader_glsl_movc(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     unsigned int component_count; | 
					
						
							|  |  |  |     struct glsl_src src[3]; | 
					
						
							|  |  |  |     struct glsl_dst dst; | 
					
						
							|  |  |  |     uint32_t mask; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     mask = glsl_dst_init(&dst, gen, ins, &ins->dst[0]); | 
					
						
							|  |  |  |     glsl_src_init(&src[0], gen, &ins->src[0], mask); | 
					
						
							|  |  |  |     glsl_src_init(&src[1], gen, &ins->src[1], mask); | 
					
						
							|  |  |  |     glsl_src_init(&src[2], gen, &ins->src[2], mask); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((component_count = vsir_write_mask_component_count(mask)) > 1) | 
					
						
							|  |  |  |         shader_glsl_print_assignment(gen, &dst, "mix(%s, %s, bvec%u(%s))", | 
					
						
							|  |  |  |                 src[2].str->buffer, src[1].str->buffer, component_count, src[0].str->buffer); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         shader_glsl_print_assignment(gen, &dst, "mix(%s, %s, bool(%s))", | 
					
						
							|  |  |  |                 src[2].str->buffer, src[1].str->buffer, src[0].str->buffer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     glsl_src_cleanup(&src[2], &gen->string_buffers); | 
					
						
							|  |  |  |     glsl_src_cleanup(&src[1], &gen->string_buffers); | 
					
						
							|  |  |  |     glsl_src_cleanup(&src[0], &gen->string_buffers); | 
					
						
							|  |  |  |     glsl_dst_cleanup(&dst, &gen->string_buffers); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-29 23:51:43 +02:00
										 |  |  | static void shader_glsl_mul_extended(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     struct glsl_src src[2]; | 
					
						
							|  |  |  |     struct glsl_dst dst; | 
					
						
							|  |  |  |     uint32_t mask; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ins->dst[0].reg.type != VKD3DSPR_NULL) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         /* FIXME: imulExtended()/umulExtended() from ARB_gpu_shader5/GLSL 4.00+. */ | 
					
						
							|  |  |  |         mask = glsl_dst_init(&dst, gen, ins, &ins->dst[0]); | 
					
						
							|  |  |  |         shader_glsl_print_assignment(gen, &dst, "<unhandled 64-bit multiplication>"); | 
					
						
							|  |  |  |         glsl_dst_cleanup(&dst, &gen->string_buffers); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                 "Internal compiler error: Unhandled 64-bit integer multiplication."); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ins->dst[1].reg.type != VKD3DSPR_NULL) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         mask = glsl_dst_init(&dst, gen, ins, &ins->dst[1]); | 
					
						
							|  |  |  |         glsl_src_init(&src[0], gen, &ins->src[0], mask); | 
					
						
							|  |  |  |         glsl_src_init(&src[1], gen, &ins->src[1], mask); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         shader_glsl_print_assignment(gen, &dst, "%s * %s", src[0].str->buffer, src[1].str->buffer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         glsl_src_cleanup(&src[1], &gen->string_buffers); | 
					
						
							|  |  |  |         glsl_src_cleanup(&src[0], &gen->string_buffers); | 
					
						
							|  |  |  |         glsl_dst_cleanup(&dst, &gen->string_buffers); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 16:11:35 +01:00
										 |  |  | static void shader_glsl_print_sysval_name(struct vkd3d_string_buffer *buffer, struct vkd3d_glsl_generator *gen, | 
					
						
							|  |  |  |         enum vkd3d_shader_sysval_semantic sysval, unsigned int idx) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-04-14 14:10:04 +02:00
										 |  |  |     const struct vkd3d_shader_version *version = &gen->program->shader_version; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 16:11:35 +01:00
										 |  |  |     switch (sysval) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         case VKD3D_SHADER_SV_POSITION: | 
					
						
							| 
									
										
										
										
											2024-10-03 15:02:31 +02:00
										 |  |  |             if (version->type == VKD3D_SHADER_TYPE_COMPUTE) | 
					
						
							| 
									
										
										
										
											2023-12-16 16:11:35 +01:00
										 |  |  |             { | 
					
						
							|  |  |  |                 vkd3d_string_buffer_printf(buffer, "<unhandled sysval %#x>", sysval); | 
					
						
							|  |  |  |                 vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							| 
									
										
										
										
											2024-10-03 15:02:31 +02:00
										 |  |  |                         "Internal compiler error: Unhandled SV_POSITION in shader type #%x.", version->type); | 
					
						
							|  |  |  |                 break; | 
					
						
							| 
									
										
										
										
											2023-12-16 16:11:35 +01:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2024-10-03 15:02:31 +02:00
										 |  |  |             if (idx) | 
					
						
							|  |  |  |                 vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                         "Internal compiler error: Unhandled SV_POSITION index %u.", idx); | 
					
						
							|  |  |  |             if (version->type == VKD3D_SHADER_TYPE_PIXEL) | 
					
						
							| 
									
										
										
										
											2025-03-24 16:20:25 -05:00
										 |  |  |                 vkd3d_string_buffer_printf(buffer, "vec4(gl_FragCoord.xyz, 1.0 / gl_FragCoord.w)"); | 
					
						
							| 
									
										
										
										
											2023-12-16 16:11:35 +01:00
										 |  |  |             else | 
					
						
							|  |  |  |                 vkd3d_string_buffer_printf(buffer, "gl_Position"); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 00:35:41 +02:00
										 |  |  |         case VKD3D_SHADER_SV_VERTEX_ID: | 
					
						
							|  |  |  |             if (version->type != VKD3D_SHADER_TYPE_VERTEX) | 
					
						
							|  |  |  |                 vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                         "Internal compiler error: Unhandled SV_VERTEX_ID in shader type #%x.", version->type); | 
					
						
							|  |  |  |             vkd3d_string_buffer_printf(buffer, "intBitsToFloat(ivec4(gl_VertexID, 0, 0, 0))"); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-03 14:48:01 +02:00
										 |  |  |         case VKD3D_SHADER_SV_IS_FRONT_FACE: | 
					
						
							|  |  |  |             if (version->type != VKD3D_SHADER_TYPE_PIXEL) | 
					
						
							|  |  |  |                 vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                         "Internal compiler error: Unhandled SV_IS_FRONT_FACE in shader type #%x.", version->type); | 
					
						
							|  |  |  |             vkd3d_string_buffer_printf(buffer, | 
					
						
							|  |  |  |                     "uintBitsToFloat(uvec4(gl_FrontFacing ? 0xffffffffu : 0u, 0u, 0u, 0u))"); | 
					
						
							| 
									
										
										
										
											2024-10-25 14:42:58 +02:00
										 |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-05-03 14:48:01 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-25 14:42:58 +02:00
										 |  |  |         case VKD3D_SHADER_SV_SAMPLE_INDEX: | 
					
						
							|  |  |  |             if (version->type != VKD3D_SHADER_TYPE_PIXEL) | 
					
						
							|  |  |  |                 vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                         "Internal compiler error: Unhandled SV_SAMPLE_INDEX in shader type #%x.", version->type); | 
					
						
							|  |  |  |             vkd3d_string_buffer_printf(buffer, "intBitsToFloat(ivec4(gl_SampleID, 0, 0, 0))"); | 
					
						
							| 
									
										
										
										
											2024-05-03 14:48:01 +02:00
										 |  |  |             break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-14 14:10:04 +02:00
										 |  |  |         case VKD3D_SHADER_SV_TARGET: | 
					
						
							|  |  |  |             if (version->type != VKD3D_SHADER_TYPE_PIXEL) | 
					
						
							|  |  |  |                 vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                         "Internal compiler error: Unhandled SV_TARGET in shader type #%x.", version->type); | 
					
						
							|  |  |  |             vkd3d_string_buffer_printf(buffer, "shader_out_%u", idx); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 16:11:35 +01:00
										 |  |  |         default: | 
					
						
							|  |  |  |             vkd3d_string_buffer_printf(buffer, "<unhandled sysval %#x>", sysval); | 
					
						
							|  |  |  |             vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                     "Internal compiler error: Unhandled system value %#x.", sysval); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-22 14:33:18 +01:00
										 |  |  | static void shader_glsl_shader_prologue(struct vkd3d_glsl_generator *gen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const struct shader_signature *signature = &gen->program->input_signature; | 
					
						
							|  |  |  |     struct vkd3d_string_buffer *buffer = gen->buffer; | 
					
						
							|  |  |  |     const struct signature_element *e; | 
					
						
							|  |  |  |     unsigned int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < signature->element_count; ++i) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         e = &signature->elements[i]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         shader_glsl_print_indent(buffer, gen->indent); | 
					
						
							|  |  |  |         vkd3d_string_buffer_printf(buffer, "%s_in[%u]", gen->prefix, e->register_index); | 
					
						
							|  |  |  |         shader_glsl_print_write_mask(buffer, e->mask); | 
					
						
							|  |  |  |         if (e->sysval_semantic == VKD3D_SHADER_SV_NONE) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (gen->interstage_input) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 vkd3d_string_buffer_printf(buffer, " = shader_in.reg_%u", e->target_location); | 
					
						
							|  |  |  |                 if (e->target_location >= gen->limits.input_count) | 
					
						
							|  |  |  |                     vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                             "Internal compiler error: Input element %u specifies target location %u, " | 
					
						
							|  |  |  |                             "but only %u inputs are supported.", | 
					
						
							|  |  |  |                             i, e->target_location, gen->limits.input_count); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2024-10-03 15:43:33 +02:00
										 |  |  |                 switch (e->component_type) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     case VKD3D_SHADER_COMPONENT_UINT: | 
					
						
							|  |  |  |                         vkd3d_string_buffer_printf(buffer, " = uintBitsToFloat(shader_in_%u)", i); | 
					
						
							|  |  |  |                         break; | 
					
						
							| 
									
										
										
										
											2024-10-03 16:50:23 +02:00
										 |  |  |                     case VKD3D_SHADER_COMPONENT_INT: | 
					
						
							|  |  |  |                         vkd3d_string_buffer_printf(buffer, " = intBitsToFloat(shader_in_%u)", i); | 
					
						
							|  |  |  |                         break; | 
					
						
							| 
									
										
										
										
											2024-10-03 15:43:33 +02:00
										 |  |  |                     default: | 
					
						
							|  |  |  |                         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                                 "Internal compiler error: Unhandled input component type %#x.", e->component_type); | 
					
						
							|  |  |  |                         /* fall through */ | 
					
						
							|  |  |  |                     case VKD3D_SHADER_COMPONENT_FLOAT: | 
					
						
							|  |  |  |                         vkd3d_string_buffer_printf(buffer, " = shader_in_%u", i); | 
					
						
							|  |  |  |                         break; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2023-11-22 14:33:18 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2023-12-16 16:11:35 +01:00
										 |  |  |             vkd3d_string_buffer_printf(buffer, " = "); | 
					
						
							|  |  |  |             shader_glsl_print_sysval_name(buffer, gen, e->sysval_semantic, e->semantic_index); | 
					
						
							| 
									
										
										
										
											2023-11-22 14:33:18 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |         shader_glsl_print_write_mask(buffer, e->mask); | 
					
						
							|  |  |  |         vkd3d_string_buffer_printf(buffer, ";\n"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 16:11:35 +01:00
										 |  |  | static void shader_glsl_shader_epilogue(struct vkd3d_glsl_generator *gen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const struct shader_signature *signature = &gen->program->output_signature; | 
					
						
							|  |  |  |     struct vkd3d_string_buffer *buffer = gen->buffer; | 
					
						
							| 
									
										
										
										
											2024-10-03 14:23:00 +02:00
										 |  |  |     enum vkd3d_shader_component_type type; | 
					
						
							| 
									
										
										
										
											2023-12-16 16:11:35 +01:00
										 |  |  |     const struct signature_element *e; | 
					
						
							|  |  |  |     unsigned int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < signature->element_count; ++i) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         e = &signature->elements[i]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-03 14:23:00 +02:00
										 |  |  |         type = e->component_type; | 
					
						
							| 
									
										
										
										
											2023-12-16 16:11:35 +01:00
										 |  |  |         shader_glsl_print_indent(buffer, gen->indent); | 
					
						
							|  |  |  |         if (e->sysval_semantic == VKD3D_SHADER_SV_NONE) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (gen->interstage_output) | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2024-10-03 14:23:00 +02:00
										 |  |  |                 type = VKD3D_SHADER_COMPONENT_FLOAT; | 
					
						
							| 
									
										
										
										
											2023-12-16 16:11:35 +01:00
										 |  |  |                 vkd3d_string_buffer_printf(buffer, "shader_out.reg_%u", e->target_location); | 
					
						
							|  |  |  |                 if (e->target_location >= gen->limits.output_count) | 
					
						
							|  |  |  |                     vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                             "Internal compiler error: Output element %u specifies target location %u, " | 
					
						
							|  |  |  |                             "but only %u outputs are supported.", | 
					
						
							|  |  |  |                             i, e->target_location, gen->limits.output_count); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 vkd3d_string_buffer_printf(buffer, "<unhandled output %u>", e->target_location); | 
					
						
							|  |  |  |                 vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                         "Internal compiler error: Unhandled output."); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             shader_glsl_print_sysval_name(buffer, gen, e->sysval_semantic, e->semantic_index); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         shader_glsl_print_write_mask(buffer, e->mask); | 
					
						
							| 
									
										
										
										
											2024-10-03 14:23:00 +02:00
										 |  |  |         switch (type) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             case VKD3D_SHADER_COMPONENT_UINT: | 
					
						
							|  |  |  |                 vkd3d_string_buffer_printf(buffer, " = floatBitsToUint(%s_out[%u])", gen->prefix, e->register_index); | 
					
						
							|  |  |  |                 break; | 
					
						
							| 
									
										
										
										
											2024-10-25 15:48:08 +02:00
										 |  |  |             case VKD3D_SHADER_COMPONENT_INT: | 
					
						
							|  |  |  |                 vkd3d_string_buffer_printf(buffer, " = floatBitsToInt(%s_out[%u])", gen->prefix, e->register_index); | 
					
						
							|  |  |  |                 break; | 
					
						
							| 
									
										
										
										
											2024-10-03 14:23:00 +02:00
										 |  |  |             default: | 
					
						
							|  |  |  |                 vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                         "Internal compiler error: Unhandled output component type %#x.", e->component_type); | 
					
						
							|  |  |  |                 /* fall through */ | 
					
						
							|  |  |  |             case VKD3D_SHADER_COMPONENT_FLOAT: | 
					
						
							|  |  |  |                 vkd3d_string_buffer_printf(buffer, " = %s_out[%u]", gen->prefix, e->register_index); | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-12-16 16:11:35 +01:00
										 |  |  |         shader_glsl_print_write_mask(buffer, e->mask); | 
					
						
							|  |  |  |         vkd3d_string_buffer_printf(buffer, ";\n"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  | static void shader_glsl_ret(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) | 
					
						
							| 
									
										
										
										
											2021-08-19 20:18:16 +05:30
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  |     const struct vkd3d_shader_version *version = &gen->program->shader_version; | 
					
						
							| 
									
										
										
										
											2021-08-19 20:18:16 +05:30
										 |  |  | 
 | 
					
						
							|  |  |  |     if (version->major >= 4) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-12-16 16:11:35 +01:00
										 |  |  |         shader_glsl_shader_epilogue(gen); | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  |         shader_glsl_print_indent(gen->buffer, gen->indent); | 
					
						
							|  |  |  |         vkd3d_string_buffer_printf(gen->buffer, "return;\n"); | 
					
						
							| 
									
										
										
										
											2021-08-19 20:18:16 +05:30
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 21:11:57 +02:00
										 |  |  | static void shader_glsl_dcl_indexable_temp(struct vkd3d_glsl_generator *gen, | 
					
						
							|  |  |  |         const struct vkd3d_shader_instruction *ins) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     shader_glsl_print_indent(gen->buffer, gen->indent); | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(gen->buffer, "vec4 x%u[%u];\n", | 
					
						
							|  |  |  |             ins->declaration.indexable_temp.register_idx, | 
					
						
							|  |  |  |             ins->declaration.indexable_temp.register_size); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  | static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, | 
					
						
							|  |  |  |         const struct vkd3d_shader_instruction *ins) | 
					
						
							| 
									
										
										
										
											2021-08-19 20:18:13 +05:30
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  |     gen->location = ins->location; | 
					
						
							| 
									
										
										
										
											2023-11-17 18:13:02 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  |     switch (ins->opcode) | 
					
						
							| 
									
										
										
										
											2021-08-19 20:18:13 +05:30
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2021-08-28 14:32:54 +05:30
										 |  |  |         case VKD3DSIH_ADD: | 
					
						
							| 
									
										
										
										
											2024-09-30 12:15:08 +02:00
										 |  |  |         case VKD3DSIH_IADD: | 
					
						
							| 
									
										
										
										
											2021-08-28 14:32:54 +05:30
										 |  |  |             shader_glsl_binop(gen, ins, "+"); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2021-08-25 23:51:09 +05:30
										 |  |  |         case VKD3DSIH_AND: | 
					
						
							|  |  |  |             shader_glsl_binop(gen, ins, "&"); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-10-03 15:07:16 +02:00
										 |  |  |         case VKD3DSIH_BREAK: | 
					
						
							|  |  |  |             shader_glsl_break(gen); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-10-03 15:46:07 +02:00
										 |  |  |         case VKD3DSIH_CASE: | 
					
						
							|  |  |  |             shader_glsl_case(gen, ins); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-10-03 16:14:36 +02:00
										 |  |  |         case VKD3DSIH_CONTINUE: | 
					
						
							|  |  |  |             shader_glsl_continue(gen); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-09-30 21:11:57 +02:00
										 |  |  |         case VKD3DSIH_DCL_INDEXABLE_TEMP: | 
					
						
							|  |  |  |             shader_glsl_dcl_indexable_temp(gen, ins); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-02-24 16:28:41 +01:00
										 |  |  |         case VKD3DSIH_NOP: | 
					
						
							| 
									
										
										
										
											2021-08-19 20:18:14 +05:30
										 |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-10-03 15:46:07 +02:00
										 |  |  |         case VKD3DSIH_DEFAULT: | 
					
						
							|  |  |  |             shader_glsl_default(gen); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-04-27 00:32:12 +02:00
										 |  |  |         case VKD3DSIH_DIV: | 
					
						
							|  |  |  |             shader_glsl_binop(gen, ins, "/"); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-05-02 01:26:01 +02:00
										 |  |  |         case VKD3DSIH_DP2: | 
					
						
							|  |  |  |             shader_glsl_dot(gen, ins, vkd3d_write_mask_from_component_count(2)); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-05-02 01:15:29 +02:00
										 |  |  |         case VKD3DSIH_DP3: | 
					
						
							|  |  |  |             shader_glsl_dot(gen, ins, vkd3d_write_mask_from_component_count(3)); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-05-02 01:20:45 +02:00
										 |  |  |         case VKD3DSIH_DP4: | 
					
						
							|  |  |  |             shader_glsl_dot(gen, ins, VKD3DSP_WRITEMASK_ALL); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-05-03 21:35:39 +02:00
										 |  |  |         case VKD3DSIH_ELSE: | 
					
						
							|  |  |  |             shader_glsl_else(gen, ins); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-05-03 14:21:01 +02:00
										 |  |  |         case VKD3DSIH_ENDIF: | 
					
						
							| 
									
										
										
										
											2024-10-03 15:07:16 +02:00
										 |  |  |         case VKD3DSIH_ENDLOOP: | 
					
						
							| 
									
										
										
										
											2024-10-03 15:46:07 +02:00
										 |  |  |         case VKD3DSIH_ENDSWITCH: | 
					
						
							| 
									
										
										
										
											2024-10-03 15:07:16 +02:00
										 |  |  |             shader_glsl_end_block(gen); | 
					
						
							| 
									
										
										
										
											2024-05-03 14:21:01 +02:00
										 |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-09-30 00:03:15 +02:00
										 |  |  |         case VKD3DSIH_EQO: | 
					
						
							| 
									
										
										
										
											2024-05-03 01:11:06 +02:00
										 |  |  |         case VKD3DSIH_IEQ: | 
					
						
							|  |  |  |             shader_glsl_relop(gen, ins, "==", "equal"); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-05-03 01:19:55 +02:00
										 |  |  |         case VKD3DSIH_EXP: | 
					
						
							|  |  |  |             shader_glsl_intrinsic(gen, ins, "exp2"); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-04-28 18:53:51 +02:00
										 |  |  |         case VKD3DSIH_FRC: | 
					
						
							|  |  |  |             shader_glsl_intrinsic(gen, ins, "fract"); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-05-01 13:52:14 +02:00
										 |  |  |         case VKD3DSIH_FTOI: | 
					
						
							|  |  |  |             shader_glsl_cast(gen, ins, "int", "ivec"); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-05-01 23:58:20 +02:00
										 |  |  |         case VKD3DSIH_FTOU: | 
					
						
							|  |  |  |             shader_glsl_cast(gen, ins, "uint", "uvec"); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-10-19 17:21:01 +02:00
										 |  |  |         case VKD3DSIH_GATHER4: | 
					
						
							| 
									
										
										
										
											2024-10-19 19:03:54 +02:00
										 |  |  |         case VKD3DSIH_GATHER4_PO: | 
					
						
							| 
									
										
										
										
											2024-10-19 17:21:01 +02:00
										 |  |  |         case VKD3DSIH_SAMPLE: | 
					
						
							|  |  |  |         case VKD3DSIH_SAMPLE_B: | 
					
						
							|  |  |  |         case VKD3DSIH_SAMPLE_C: | 
					
						
							|  |  |  |         case VKD3DSIH_SAMPLE_C_LZ: | 
					
						
							|  |  |  |         case VKD3DSIH_SAMPLE_GRAD: | 
					
						
							|  |  |  |         case VKD3DSIH_SAMPLE_LOD: | 
					
						
							|  |  |  |             shader_glsl_sample(gen, ins); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-04-27 00:48:02 +02:00
										 |  |  |         case VKD3DSIH_GEO: | 
					
						
							| 
									
										
										
										
											2024-09-29 22:43:33 +02:00
										 |  |  |         case VKD3DSIH_IGE: | 
					
						
							| 
									
										
										
										
											2024-04-27 00:48:02 +02:00
										 |  |  |             shader_glsl_relop(gen, ins, ">=", "greaterThanEqual"); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-05-03 14:21:01 +02:00
										 |  |  |         case VKD3DSIH_IF: | 
					
						
							|  |  |  |             shader_glsl_if(gen, ins); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-09-29 19:44:32 +02:00
										 |  |  |         case VKD3DSIH_MAD: | 
					
						
							|  |  |  |             shader_glsl_intrinsic(gen, ins, "fma"); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-09-29 22:47:21 +02:00
										 |  |  |         case VKD3DSIH_ILT: | 
					
						
							|  |  |  |         case VKD3DSIH_LTO: | 
					
						
							| 
									
										
										
										
											2024-10-03 15:50:01 +02:00
										 |  |  |         case VKD3DSIH_ULT: | 
					
						
							| 
									
										
										
										
											2024-09-29 22:47:21 +02:00
										 |  |  |             shader_glsl_relop(gen, ins, "<", "lessThan"); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-10-03 16:42:41 +02:00
										 |  |  |         case VKD3DSIH_IMAX: | 
					
						
							| 
									
										
										
										
											2024-05-03 15:33:00 +02:00
										 |  |  |         case VKD3DSIH_MAX: | 
					
						
							| 
									
										
										
										
											2024-10-18 23:18:54 +02:00
										 |  |  |         case VKD3DSIH_UMAX: | 
					
						
							| 
									
										
										
										
											2024-05-03 15:33:00 +02:00
										 |  |  |             shader_glsl_intrinsic(gen, ins, "max"); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-05-03 15:43:42 +02:00
										 |  |  |         case VKD3DSIH_MIN: | 
					
						
							| 
									
										
										
										
											2024-10-18 23:18:54 +02:00
										 |  |  |         case VKD3DSIH_UMIN: | 
					
						
							| 
									
										
										
										
											2024-05-03 15:43:42 +02:00
										 |  |  |             shader_glsl_intrinsic(gen, ins, "min"); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-10-03 16:42:41 +02:00
										 |  |  |         case VKD3DSIH_IMUL: | 
					
						
							|  |  |  |             shader_glsl_mul_extended(gen, ins); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-04-26 23:50:31 +02:00
										 |  |  |         case VKD3DSIH_INE: | 
					
						
							| 
									
										
										
										
											2024-04-22 21:41:23 +02:00
										 |  |  |         case VKD3DSIH_NEU: | 
					
						
							|  |  |  |             shader_glsl_relop(gen, ins, "!=", "notEqual"); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-10-03 16:16:00 +02:00
										 |  |  |         case VKD3DSIH_INEG: | 
					
						
							|  |  |  |             shader_glsl_unary_op(gen, ins, "-"); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case VKD3DSIH_ISHL: | 
					
						
							|  |  |  |             shader_glsl_binop(gen, ins, "<<"); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case VKD3DSIH_ISHR: | 
					
						
							|  |  |  |         case VKD3DSIH_USHR: | 
					
						
							|  |  |  |             shader_glsl_binop(gen, ins, ">>"); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  |         case VKD3DSIH_ITOF: | 
					
						
							| 
									
										
										
										
											2021-08-23 20:36:54 +05:30
										 |  |  |         case VKD3DSIH_UTOF: | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  |             shader_glsl_cast(gen, ins, "float", "vec"); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |         case VKD3DSIH_LD: | 
					
						
							| 
									
										
										
										
											2024-10-09 13:34:21 +02:00
										 |  |  |         case VKD3DSIH_LD2DMS: | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |             shader_glsl_ld(gen, ins); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-10-06 20:58:25 +02:00
										 |  |  |         case VKD3DSIH_LD_UAV_TYPED: | 
					
						
							|  |  |  |             shader_glsl_load_uav_typed(gen, ins); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-05-03 15:18:16 +02:00
										 |  |  |         case VKD3DSIH_LOG: | 
					
						
							|  |  |  |             shader_glsl_intrinsic(gen, ins, "log2"); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-10-03 15:07:16 +02:00
										 |  |  |         case VKD3DSIH_LOOP: | 
					
						
							|  |  |  |             shader_glsl_loop(gen); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  |         case VKD3DSIH_MOV: | 
					
						
							|  |  |  |             shader_glsl_mov(gen, ins); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2021-08-29 15:32:47 +05:30
										 |  |  |         case VKD3DSIH_MOVC: | 
					
						
							|  |  |  |             shader_glsl_movc(gen, ins); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-04-26 23:38:20 +02:00
										 |  |  |         case VKD3DSIH_MUL: | 
					
						
							|  |  |  |             shader_glsl_binop(gen, ins, "*"); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-05-03 21:14:29 +02:00
										 |  |  |         case VKD3DSIH_NOT: | 
					
						
							|  |  |  |             shader_glsl_unary_op(gen, ins, "~"); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-04-27 00:20:49 +02:00
										 |  |  |         case VKD3DSIH_OR: | 
					
						
							|  |  |  |             shader_glsl_binop(gen, ins, "|"); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2021-08-19 20:18:16 +05:30
										 |  |  |         case VKD3DSIH_RET: | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  |             shader_glsl_ret(gen, ins); | 
					
						
							| 
									
										
										
										
											2021-08-19 20:18:16 +05:30
										 |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-05-03 14:32:31 +02:00
										 |  |  |         case VKD3DSIH_ROUND_NE: | 
					
						
							|  |  |  |             shader_glsl_intrinsic(gen, ins, "roundEven"); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-05-03 13:33:28 +02:00
										 |  |  |         case VKD3DSIH_ROUND_NI: | 
					
						
							|  |  |  |             shader_glsl_intrinsic(gen, ins, "floor"); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-05-02 00:10:26 +02:00
										 |  |  |         case VKD3DSIH_ROUND_PI: | 
					
						
							|  |  |  |             shader_glsl_intrinsic(gen, ins, "ceil"); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-05-02 00:33:15 +02:00
										 |  |  |         case VKD3DSIH_ROUND_Z: | 
					
						
							|  |  |  |             shader_glsl_intrinsic(gen, ins, "trunc"); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-05-03 16:03:21 +02:00
										 |  |  |         case VKD3DSIH_RSQ: | 
					
						
							|  |  |  |             shader_glsl_intrinsic(gen, ins, "inversesqrt"); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-05-02 01:39:25 +02:00
										 |  |  |         case VKD3DSIH_SQRT: | 
					
						
							|  |  |  |             shader_glsl_intrinsic(gen, ins, "sqrt"); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-10-05 20:48:51 +02:00
										 |  |  |         case VKD3DSIH_STORE_UAV_TYPED: | 
					
						
							|  |  |  |             shader_glsl_store_uav_typed(gen, ins); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-10-03 15:46:07 +02:00
										 |  |  |         case VKD3DSIH_SWITCH: | 
					
						
							|  |  |  |             shader_glsl_switch(gen, ins); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2025-03-12 12:21:55 +01:00
										 |  |  |         case VKD3DSIH_XOR: | 
					
						
							|  |  |  |             shader_glsl_binop(gen, ins, "^"); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2021-08-19 20:18:13 +05:30
										 |  |  |         default: | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  |             shader_glsl_unhandled(gen, ins); | 
					
						
							| 
									
										
										
										
											2021-08-19 20:18:13 +05:30
										 |  |  |             break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-25 00:35:48 +01:00
										 |  |  | static bool shader_glsl_check_shader_visibility(const struct vkd3d_glsl_generator *gen, | 
					
						
							|  |  |  |         enum vkd3d_shader_visibility visibility) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     enum vkd3d_shader_type t = gen->program->shader_version.type; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     switch (visibility) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         case VKD3D_SHADER_VISIBILITY_ALL: | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         case VKD3D_SHADER_VISIBILITY_VERTEX: | 
					
						
							|  |  |  |             return t == VKD3D_SHADER_TYPE_VERTEX; | 
					
						
							|  |  |  |         case VKD3D_SHADER_VISIBILITY_HULL: | 
					
						
							|  |  |  |             return t == VKD3D_SHADER_TYPE_HULL; | 
					
						
							|  |  |  |         case VKD3D_SHADER_VISIBILITY_DOMAIN: | 
					
						
							|  |  |  |             return t == VKD3D_SHADER_TYPE_DOMAIN; | 
					
						
							|  |  |  |         case VKD3D_SHADER_VISIBILITY_GEOMETRY: | 
					
						
							|  |  |  |             return t == VKD3D_SHADER_TYPE_GEOMETRY; | 
					
						
							|  |  |  |         case VKD3D_SHADER_VISIBILITY_PIXEL: | 
					
						
							|  |  |  |             return t == VKD3D_SHADER_TYPE_PIXEL; | 
					
						
							|  |  |  |         case VKD3D_SHADER_VISIBILITY_COMPUTE: | 
					
						
							|  |  |  |             return t == VKD3D_SHADER_TYPE_COMPUTE; | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             WARN("Invalid shader visibility %#x.\n", visibility); | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-05 20:48:51 +02:00
										 |  |  | static bool shader_glsl_get_uav_binding(const struct vkd3d_glsl_generator *gen, unsigned int register_space, | 
					
						
							|  |  |  |         unsigned int register_idx, enum vkd3d_shader_resource_type resource_type, unsigned int *binding_idx) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const struct vkd3d_shader_interface_info *interface_info = gen->interface_info; | 
					
						
							|  |  |  |     const struct vkd3d_shader_resource_binding *binding; | 
					
						
							|  |  |  |     enum vkd3d_shader_binding_flag resource_type_flag; | 
					
						
							|  |  |  |     unsigned int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!interface_info) | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resource_type_flag = resource_type == VKD3D_SHADER_RESOURCE_BUFFER | 
					
						
							|  |  |  |             ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < interface_info->binding_count; ++i) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         binding = &interface_info->bindings[i]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (binding->type != VKD3D_SHADER_DESCRIPTOR_TYPE_UAV) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         if (binding->register_space != register_space) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         if (binding->register_index != register_idx) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         if (!shader_glsl_check_shader_visibility(gen, binding->shader_visibility)) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         if (!(binding->flags & resource_type_flag)) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         *binding_idx = i; | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void shader_glsl_generate_uav_declaration(struct vkd3d_glsl_generator *gen, | 
					
						
							|  |  |  |         const struct vkd3d_shader_descriptor_info1 *uav) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const struct glsl_resource_type_info *resource_type_info; | 
					
						
							|  |  |  |     const char *image_type_prefix, *image_type, *read_format; | 
					
						
							|  |  |  |     const struct vkd3d_shader_descriptor_binding *binding; | 
					
						
							|  |  |  |     const struct vkd3d_shader_descriptor_offset *offset; | 
					
						
							|  |  |  |     struct vkd3d_string_buffer *buffer = gen->buffer; | 
					
						
							|  |  |  |     unsigned int binding_idx; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (uav->count != 1) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_UNSUPPORTED, | 
					
						
							|  |  |  |                 "UAV %u has unsupported descriptor array size %u.", uav->register_id, uav->count); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!shader_glsl_get_uav_binding(gen, uav->register_space, | 
					
						
							|  |  |  |             uav->register_index, uav->resource_type, &binding_idx)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_BINDING_NOT_FOUND, | 
					
						
							|  |  |  |                 "No descriptor binding specified for UAV %u.", uav->register_id); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     binding = &gen->interface_info->bindings[binding_idx].binding; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (binding->set != 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_BINDING_NOT_FOUND, | 
					
						
							|  |  |  |                 "Unsupported binding set %u specified for UAV %u.", binding->set, uav->register_id); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (binding->count != 1) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_BINDING_NOT_FOUND, | 
					
						
							|  |  |  |                 "Unsupported binding count %u specified for UAV %u.", binding->count, uav->register_id); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (gen->offset_info && gen->offset_info->binding_offsets) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         offset = &gen->offset_info->binding_offsets[binding_idx]; | 
					
						
							|  |  |  |         if (offset->static_offset || offset->dynamic_offset_index != ~0u) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                     "Internal compiler error: Unhandled descriptor offset specified for UAV %u.", | 
					
						
							|  |  |  |                     uav->register_id); | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((resource_type_info = shader_glsl_get_resource_type_info(uav->resource_type))) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         image_type = resource_type_info->type_suffix; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                 "Internal compiler error: Unhandled UAV type %#x.", uav->resource_type); | 
					
						
							|  |  |  |         image_type = "<unhandled image type>"; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-03 22:46:57 +02:00
										 |  |  |     switch (uav->resource_data_type) | 
					
						
							| 
									
										
										
										
											2024-10-05 20:48:51 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2025-04-03 22:46:57 +02:00
										 |  |  |         case VKD3D_DATA_UINT: | 
					
						
							| 
									
										
										
										
											2024-10-05 20:48:51 +02:00
										 |  |  |             image_type_prefix = "u"; | 
					
						
							|  |  |  |             read_format = "r32ui"; | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2025-04-03 22:46:57 +02:00
										 |  |  |         case VKD3D_DATA_INT: | 
					
						
							| 
									
										
										
										
											2024-10-05 20:48:51 +02:00
										 |  |  |             image_type_prefix = "i"; | 
					
						
							|  |  |  |             read_format = "r32i"; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							| 
									
										
										
										
											2025-04-03 22:46:57 +02:00
										 |  |  |                     "Internal compiler error: Unhandled data type %#x for UAV %u.", | 
					
						
							|  |  |  |                     uav->resource_data_type, uav->register_id); | 
					
						
							| 
									
										
										
										
											2024-10-05 20:48:51 +02:00
										 |  |  |             /* fall through */ | 
					
						
							| 
									
										
										
										
											2025-04-03 22:46:57 +02:00
										 |  |  |         case VKD3D_DATA_FLOAT: | 
					
						
							|  |  |  |         case VKD3D_DATA_UNORM: | 
					
						
							|  |  |  |         case VKD3D_DATA_SNORM: | 
					
						
							| 
									
										
										
										
											2024-10-05 20:48:51 +02:00
										 |  |  |             image_type_prefix = ""; | 
					
						
							|  |  |  |             read_format = "r32f"; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(buffer, "layout(binding = %u", binding->binding); | 
					
						
							|  |  |  |     if (uav->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ) | 
					
						
							|  |  |  |         vkd3d_string_buffer_printf(buffer, ", %s) ", read_format); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         vkd3d_string_buffer_printf(buffer, ") writeonly "); | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(buffer, "uniform %simage%s ", image_type_prefix, image_type); | 
					
						
							|  |  |  |     shader_glsl_print_image_name(buffer, gen, uav->register_index, uav->register_space); | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(buffer, ";\n"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-25 00:35:48 +01:00
										 |  |  | static bool shader_glsl_get_cbv_binding(const struct vkd3d_glsl_generator *gen, | 
					
						
							|  |  |  |         unsigned int register_space, unsigned int register_idx, unsigned int *binding_idx) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const struct vkd3d_shader_interface_info *interface_info = gen->interface_info; | 
					
						
							|  |  |  |     const struct vkd3d_shader_resource_binding *binding; | 
					
						
							|  |  |  |     unsigned int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!interface_info) | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < interface_info->binding_count; ++i) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         binding = &interface_info->bindings[i]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (binding->type != VKD3D_SHADER_DESCRIPTOR_TYPE_CBV) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         if (binding->register_space != register_space) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         if (binding->register_index != register_idx) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         if (!shader_glsl_check_shader_visibility(gen, binding->shader_visibility)) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         if (!(binding->flags & VKD3D_SHADER_BINDING_FLAG_BUFFER)) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         *binding_idx = i; | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void shader_glsl_generate_cbv_declaration(struct vkd3d_glsl_generator *gen, | 
					
						
							|  |  |  |         const struct vkd3d_shader_descriptor_info1 *cbv) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const struct vkd3d_shader_descriptor_binding *binding; | 
					
						
							|  |  |  |     const struct vkd3d_shader_descriptor_offset *offset; | 
					
						
							|  |  |  |     struct vkd3d_string_buffer *buffer = gen->buffer; | 
					
						
							|  |  |  |     const char *prefix = gen->prefix; | 
					
						
							|  |  |  |     unsigned int binding_idx; | 
					
						
							|  |  |  |     size_t size; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (cbv->count != 1) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-10-05 21:05:50 +02:00
										 |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_UNSUPPORTED, | 
					
						
							| 
									
										
										
										
											2024-02-25 00:35:48 +01:00
										 |  |  |                 "Constant buffer %u has unsupported descriptor array size %u.", cbv->register_id, cbv->count); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!shader_glsl_get_cbv_binding(gen, cbv->register_space, cbv->register_index, &binding_idx)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_BINDING_NOT_FOUND, | 
					
						
							|  |  |  |                 "No descriptor binding specified for constant buffer %u.", cbv->register_id); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     binding = &gen->interface_info->bindings[binding_idx].binding; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (binding->set != 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_BINDING_NOT_FOUND, | 
					
						
							|  |  |  |                 "Unsupported binding set %u specified for constant buffer %u.", binding->set, cbv->register_id); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (binding->count != 1) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_BINDING_NOT_FOUND, | 
					
						
							|  |  |  |                 "Unsupported binding count %u specified for constant buffer %u.", binding->count, cbv->register_id); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (gen->offset_info && gen->offset_info->binding_offsets) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         offset = &gen->offset_info->binding_offsets[binding_idx]; | 
					
						
							|  |  |  |         if (offset->static_offset || offset->dynamic_offset_index != ~0u) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                     "Internal compiler error: Unhandled descriptor offset specified for constant buffer %u.", | 
					
						
							|  |  |  |                     cbv->register_id); | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     size = align(cbv->buffer_size, VKD3D_VEC4_SIZE * sizeof(uint32_t)); | 
					
						
							|  |  |  |     size /= VKD3D_VEC4_SIZE * sizeof(uint32_t); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(buffer, | 
					
						
							|  |  |  |             "layout(std140, binding = %u) uniform block_%s_cb_%u { vec4 %s_cb_%u[%zu]; };\n", | 
					
						
							|  |  |  |             binding->binding, prefix, cbv->register_id, prefix, cbv->register_id, size); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  | static bool shader_glsl_get_combined_sampler_binding(const struct vkd3d_glsl_generator *gen, | 
					
						
							|  |  |  |         const struct vkd3d_shader_combined_resource_sampler_info *crs, | 
					
						
							|  |  |  |         enum vkd3d_shader_resource_type resource_type, unsigned int *binding_idx) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const struct vkd3d_shader_interface_info *interface_info = gen->interface_info; | 
					
						
							|  |  |  |     const struct vkd3d_shader_combined_resource_sampler *s; | 
					
						
							|  |  |  |     enum vkd3d_shader_binding_flag resource_type_flag; | 
					
						
							|  |  |  |     unsigned int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!interface_info) | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resource_type_flag = resource_type == VKD3D_SHADER_RESOURCE_BUFFER | 
					
						
							|  |  |  |             ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < interface_info->combined_sampler_count; ++i) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         s = &interface_info->combined_samplers[i]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (s->resource_space != crs->resource_space) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         if (s->resource_index != crs->resource_index) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         if (crs->sampler_index != VKD3D_SHADER_DUMMY_SAMPLER_INDEX) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (s->sampler_space != crs->sampler_space) | 
					
						
							|  |  |  |                 continue; | 
					
						
							|  |  |  |             if (s->sampler_index != crs->sampler_index) | 
					
						
							|  |  |  |                 continue; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (!shader_glsl_check_shader_visibility(gen, s->shader_visibility)) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         if (!(s->flags & resource_type_flag)) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         *binding_idx = i; | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void shader_glsl_generate_sampler_declaration(struct vkd3d_glsl_generator *gen, | 
					
						
							|  |  |  |         const struct vkd3d_shader_combined_resource_sampler_info *crs) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const struct vkd3d_shader_descriptor_info1 *sampler, *srv; | 
					
						
							|  |  |  |     const struct glsl_resource_type_info *resource_type_info; | 
					
						
							|  |  |  |     const struct vkd3d_shader_descriptor_binding *binding; | 
					
						
							|  |  |  |     struct vkd3d_string_buffer *buffer = gen->buffer; | 
					
						
							|  |  |  |     const char *sampler_type, *sampler_type_prefix; | 
					
						
							| 
									
										
										
										
											2024-10-09 13:34:21 +02:00
										 |  |  |     enum vkd3d_shader_resource_type resource_type; | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |     unsigned int binding_idx; | 
					
						
							|  |  |  |     bool shadow = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (crs->sampler_index != VKD3D_SHADER_DUMMY_SAMPLER_INDEX) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (!(sampler = shader_glsl_get_descriptor(gen, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, | 
					
						
							|  |  |  |                 crs->sampler_index, crs->sampler_space))) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                     "Internal compiler error: No descriptor found for sampler %u, space %u.", | 
					
						
							|  |  |  |                     crs->sampler_index, crs->sampler_space); | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         shadow = sampler->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!(srv = shader_glsl_get_descriptor(gen, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, | 
					
						
							|  |  |  |             crs->resource_index, crs->resource_space))) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                 "Internal compiler error: No descriptor found for resource %u, space %u.", | 
					
						
							|  |  |  |                 crs->resource_index, crs->resource_space); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-09 13:34:21 +02:00
										 |  |  |     resource_type = srv->resource_type; | 
					
						
							|  |  |  |     if (srv->sample_count == 1) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         /* The OpenGL API distinguishes between multi-sample textures with
 | 
					
						
							|  |  |  |          * sample count 1 and single-sample textures. Direct3D and Vulkan | 
					
						
							|  |  |  |          * don't make this distinction at the API level, but Direct3D shaders | 
					
						
							|  |  |  |          * are capable of expressing both. We therefore map such multi-sample | 
					
						
							|  |  |  |          * textures to their single-sample equivalents here. */ | 
					
						
							|  |  |  |         if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS) | 
					
						
							|  |  |  |             resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; | 
					
						
							|  |  |  |         else if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY) | 
					
						
							|  |  |  |             resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type))) | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-10-05 20:48:51 +02:00
										 |  |  |         sampler_type = resource_type_info->type_suffix; | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |         if (shadow && !resource_type_info->shadow) | 
					
						
							|  |  |  |             vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_UNSUPPORTED, | 
					
						
							| 
									
										
										
										
											2024-10-09 13:34:21 +02:00
										 |  |  |                     "Comparison samplers are not supported with resource type %#x.", resource_type); | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                 "Internal compiler error: Unhandled resource type %#x for combined resource/sampler " | 
					
						
							| 
									
										
										
										
											2024-10-09 13:34:21 +02:00
										 |  |  |                 "for resource %u, space %u and sampler %u, space %u.", resource_type, | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |                 crs->resource_index, crs->resource_space, crs->sampler_index, crs->sampler_space); | 
					
						
							|  |  |  |         sampler_type = "<unhandled sampler type>"; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-03 22:46:57 +02:00
										 |  |  |     switch (srv->resource_data_type) | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2025-04-03 22:46:57 +02:00
										 |  |  |         case VKD3D_DATA_UINT: | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |             sampler_type_prefix = "u"; | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2025-04-03 22:46:57 +02:00
										 |  |  |         case VKD3D_DATA_INT: | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |             sampler_type_prefix = "i"; | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2025-04-03 22:46:57 +02:00
										 |  |  |         case VKD3D_DATA_FLOAT: | 
					
						
							|  |  |  |         case VKD3D_DATA_UNORM: | 
					
						
							|  |  |  |         case VKD3D_DATA_SNORM: | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |             sampler_type_prefix = ""; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							| 
									
										
										
										
											2025-04-03 22:46:57 +02:00
										 |  |  |                     "Internal compiler error: Unhandled data type %#x for combined resource/sampler " | 
					
						
							|  |  |  |                     "for resource %u, space %u and sampler %u, space %u.", srv->resource_data_type, | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |                     crs->resource_index, crs->resource_space, crs->sampler_index, crs->sampler_space); | 
					
						
							|  |  |  |             sampler_type_prefix = ""; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-09 13:34:21 +02:00
										 |  |  |     if (!shader_glsl_get_combined_sampler_binding(gen, crs, resource_type, &binding_idx)) | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_BINDING_NOT_FOUND, | 
					
						
							|  |  |  |                 "No descriptor binding specified for combined resource/sampler " | 
					
						
							|  |  |  |                 "for resource %u, space %u and sampler %u, space %u.", | 
					
						
							|  |  |  |                 crs->resource_index, crs->resource_space, crs->sampler_index, crs->sampler_space); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     binding = &gen->interface_info->combined_samplers[binding_idx].binding; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (binding->set != 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_BINDING_NOT_FOUND, | 
					
						
							|  |  |  |                 "Unsupported binding set %u specified for combined resource/sampler " | 
					
						
							|  |  |  |                 "for resource %u, space %u and sampler %u, space %u.", binding->set, | 
					
						
							|  |  |  |                 crs->resource_index, crs->resource_space, crs->sampler_index, crs->sampler_space); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (binding->count != 1) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_BINDING_NOT_FOUND, | 
					
						
							|  |  |  |                 "Unsupported binding count %u specified for combined resource/sampler " | 
					
						
							|  |  |  |                 "for resource %u, space %u and sampler %u, space %u.", binding->count, | 
					
						
							|  |  |  |                 crs->resource_index, crs->resource_space, crs->sampler_index, crs->sampler_space); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-05 20:48:51 +02:00
										 |  |  |     vkd3d_string_buffer_printf(buffer, "layout(binding = %u) uniform %ssampler%s%s ", | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |             binding->binding, sampler_type_prefix, sampler_type, shadow ? "Shadow" : ""); | 
					
						
							|  |  |  |     shader_glsl_print_combined_sampler_name(buffer, gen, crs->resource_index, | 
					
						
							|  |  |  |             crs->resource_space, crs->sampler_index, crs->sampler_space); | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(buffer, ";\n"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-25 00:35:48 +01:00
										 |  |  | static void shader_glsl_generate_descriptor_declarations(struct vkd3d_glsl_generator *gen) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |     const struct vkd3d_shader_scan_combined_resource_sampler_info *sampler_info = gen->combined_sampler_info; | 
					
						
							| 
									
										
										
										
											2025-03-14 23:14:06 +01:00
										 |  |  |     const struct vkd3d_shader_scan_descriptor_info1 *info = &gen->program->descriptors; | 
					
						
							| 
									
										
										
										
											2024-02-25 00:35:48 +01:00
										 |  |  |     const struct vkd3d_shader_descriptor_info1 *descriptor; | 
					
						
							|  |  |  |     unsigned int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < info->descriptor_count; ++i) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         descriptor = &info->descriptors[i]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         switch (descriptor->type) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |             case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV: | 
					
						
							|  |  |  |             case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER: | 
					
						
							|  |  |  |                 /* GLSL uses combined resource/sampler descriptors.*/ | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-05 20:48:51 +02:00
										 |  |  |             case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV: | 
					
						
							|  |  |  |                 shader_glsl_generate_uav_declaration(gen, descriptor); | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-25 00:35:48 +01:00
										 |  |  |             case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV: | 
					
						
							|  |  |  |                 shader_glsl_generate_cbv_declaration(gen, descriptor); | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             default: | 
					
						
							|  |  |  |                 vkd3d_string_buffer_printf(gen->buffer, "/* <unhandled descriptor type %#x> */\n", descriptor->type); | 
					
						
							|  |  |  |                 vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                         "Internal compiler error: Unhandled descriptor type %#x.", descriptor->type); | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |     for (i = 0; i < sampler_info->combined_sampler_count; ++i) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         shader_glsl_generate_sampler_declaration(gen, &sampler_info->combined_samplers[i]); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-02-25 00:35:48 +01:00
										 |  |  |     if (info->descriptor_count) | 
					
						
							|  |  |  |         vkd3d_string_buffer_printf(gen->buffer, "\n"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 12:04:31 +02:00
										 |  |  | static const struct signature_element *signature_get_element_by_location( | 
					
						
							|  |  |  |         const struct shader_signature *signature, unsigned int location) | 
					
						
							| 
									
										
										
										
											2023-12-16 16:11:35 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-09-30 12:04:31 +02:00
										 |  |  |     const struct signature_element *e; | 
					
						
							|  |  |  |     unsigned int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < signature->element_count; ++i) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         e = &signature->elements[i]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (e->target_location != location) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return e; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const char *shader_glsl_get_interpolation(struct vkd3d_glsl_generator *gen, | 
					
						
							|  |  |  |         const struct shader_signature *signature, const char *type, unsigned int location) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     enum vkd3d_shader_interpolation_mode m; | 
					
						
							|  |  |  |     const struct signature_element *e; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((e = signature_get_element_by_location(signature, location))) | 
					
						
							|  |  |  |         m = e->interpolation_mode; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         m = VKD3DSIM_NONE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     switch (m) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         case VKD3DSIM_NONE: | 
					
						
							|  |  |  |         case VKD3DSIM_LINEAR: | 
					
						
							|  |  |  |             return ""; | 
					
						
							|  |  |  |         case VKD3DSIM_CONSTANT: | 
					
						
							|  |  |  |             return "flat "; | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                     "Internal compiler error: Unhandled interpolation mode %#x for %s location %u.", m, type, location); | 
					
						
							|  |  |  |             return ""; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void shader_glsl_generate_interface_block(struct vkd3d_glsl_generator *gen, | 
					
						
							|  |  |  |         const struct shader_signature *signature, const char *type, unsigned int count) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     struct vkd3d_string_buffer *buffer = gen->buffer; | 
					
						
							|  |  |  |     const char *interpolation; | 
					
						
							| 
									
										
										
										
											2023-12-16 16:11:35 +01:00
										 |  |  |     unsigned int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(buffer, "%s shader_in_out\n{\n", type); | 
					
						
							|  |  |  |     for (i = 0; i < count; ++i) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-09-30 12:04:31 +02:00
										 |  |  |         interpolation = shader_glsl_get_interpolation(gen, signature, type, i); | 
					
						
							|  |  |  |         vkd3d_string_buffer_printf(buffer, "    %svec4 reg_%u;\n", interpolation, i); | 
					
						
							| 
									
										
										
										
											2023-12-16 16:11:35 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(buffer, "} shader_%s;\n", type); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-22 14:33:18 +01:00
										 |  |  | static void shader_glsl_generate_input_declarations(struct vkd3d_glsl_generator *gen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const struct shader_signature *signature = &gen->program->input_signature; | 
					
						
							|  |  |  |     struct vkd3d_string_buffer *buffer = gen->buffer; | 
					
						
							|  |  |  |     const struct signature_element *e; | 
					
						
							| 
									
										
										
										
											2024-10-03 15:43:33 +02:00
										 |  |  |     unsigned int i, count; | 
					
						
							| 
									
										
										
										
											2023-11-22 14:33:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (!gen->interstage_input) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-10-03 15:43:33 +02:00
										 |  |  |         for (i = 0, count = 0; i < signature->element_count; ++i) | 
					
						
							| 
									
										
										
										
											2023-11-22 14:33:18 +01:00
										 |  |  |         { | 
					
						
							|  |  |  |             e = &signature->elements[i]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 00:35:41 +02:00
										 |  |  |             if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED || e->sysval_semantic) | 
					
						
							| 
									
										
										
										
											2023-11-22 14:33:18 +01:00
										 |  |  |                 continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (e->min_precision != VKD3D_SHADER_MINIMUM_PRECISION_NONE) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                         "Internal compiler error: Unhandled minimum precision %#x.", e->min_precision); | 
					
						
							|  |  |  |                 continue; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (e->interpolation_mode != VKD3DSIM_NONE) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                         "Internal compiler error: Unhandled interpolation mode %#x.", e->interpolation_mode); | 
					
						
							|  |  |  |                 continue; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-03 15:43:33 +02:00
										 |  |  |             vkd3d_string_buffer_printf(buffer, "layout(location = %u) in ", e->target_location); | 
					
						
							|  |  |  |             switch (e->component_type) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 case VKD3D_SHADER_COMPONENT_UINT: | 
					
						
							|  |  |  |                     vkd3d_string_buffer_printf(buffer, "uvec4"); | 
					
						
							|  |  |  |                     break; | 
					
						
							| 
									
										
										
										
											2024-10-03 16:50:23 +02:00
										 |  |  |                 case VKD3D_SHADER_COMPONENT_INT: | 
					
						
							|  |  |  |                     vkd3d_string_buffer_printf(buffer, "ivec4"); | 
					
						
							|  |  |  |                     break; | 
					
						
							| 
									
										
										
										
											2024-10-03 15:43:33 +02:00
										 |  |  |                 case VKD3D_SHADER_COMPONENT_FLOAT: | 
					
						
							|  |  |  |                     vkd3d_string_buffer_printf(buffer, "vec4"); | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 default: | 
					
						
							|  |  |  |                     vkd3d_string_buffer_printf(buffer, "<unhandled type %#x>", e->component_type); | 
					
						
							|  |  |  |                     vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                             "Internal compiler error: Unhandled input component type %#x.", e->component_type); | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             vkd3d_string_buffer_printf(buffer, " shader_in_%u;\n", i); | 
					
						
							|  |  |  |             ++count; | 
					
						
							| 
									
										
										
										
											2023-11-22 14:33:18 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-10-03 15:43:33 +02:00
										 |  |  |         if (count) | 
					
						
							|  |  |  |             vkd3d_string_buffer_printf(buffer, "\n"); | 
					
						
							| 
									
										
										
										
											2023-11-22 14:33:18 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |     else if (gen->limits.input_count) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-09-30 12:04:31 +02:00
										 |  |  |         shader_glsl_generate_interface_block(gen, signature, "in", gen->limits.input_count); | 
					
						
							| 
									
										
										
										
											2024-10-03 15:43:33 +02:00
										 |  |  |         vkd3d_string_buffer_printf(buffer, "\n"); | 
					
						
							| 
									
										
										
										
											2023-12-16 16:11:35 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void shader_glsl_generate_output_declarations(struct vkd3d_glsl_generator *gen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const struct shader_signature *signature = &gen->program->output_signature; | 
					
						
							|  |  |  |     struct vkd3d_string_buffer *buffer = gen->buffer; | 
					
						
							|  |  |  |     const struct signature_element *e; | 
					
						
							| 
									
										
										
										
											2024-10-03 14:23:00 +02:00
										 |  |  |     unsigned int i, count; | 
					
						
							| 
									
										
										
										
											2023-12-16 16:11:35 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (!gen->interstage_output) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-10-03 14:23:00 +02:00
										 |  |  |         for (i = 0, count = 0; i < signature->element_count; ++i) | 
					
						
							| 
									
										
										
										
											2023-11-22 14:33:18 +01:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2023-12-16 16:11:35 +01:00
										 |  |  |             e = &signature->elements[i]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED) | 
					
						
							|  |  |  |                 continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (e->sysval_semantic != VKD3D_SHADER_SV_TARGET) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                         "Internal compiler error: Unhandled system value %#x.", e->sysval_semantic); | 
					
						
							|  |  |  |                 continue; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (e->min_precision != VKD3D_SHADER_MINIMUM_PRECISION_NONE) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                         "Internal compiler error: Unhandled minimum precision %#x.", e->min_precision); | 
					
						
							|  |  |  |                 continue; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (e->interpolation_mode != VKD3DSIM_NONE) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                         "Internal compiler error: Unhandled interpolation mode %#x.", e->interpolation_mode); | 
					
						
							|  |  |  |                 continue; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-03 14:23:00 +02:00
										 |  |  |             vkd3d_string_buffer_printf(buffer, "layout(location = %u) out ", e->target_location); | 
					
						
							|  |  |  |             switch (e->component_type) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 case VKD3D_SHADER_COMPONENT_UINT: | 
					
						
							|  |  |  |                     vkd3d_string_buffer_printf(buffer, "uvec4"); | 
					
						
							|  |  |  |                     break; | 
					
						
							| 
									
										
										
										
											2024-10-25 15:48:08 +02:00
										 |  |  |                 case VKD3D_SHADER_COMPONENT_INT: | 
					
						
							|  |  |  |                     vkd3d_string_buffer_printf(buffer, "ivec4"); | 
					
						
							|  |  |  |                     break; | 
					
						
							| 
									
										
										
										
											2024-10-03 14:23:00 +02:00
										 |  |  |                 case VKD3D_SHADER_COMPONENT_FLOAT: | 
					
						
							|  |  |  |                     vkd3d_string_buffer_printf(buffer, "vec4"); | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 default: | 
					
						
							|  |  |  |                     vkd3d_string_buffer_printf(buffer, "<unhandled type %#x>", e->component_type); | 
					
						
							|  |  |  |                     vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                             "Internal compiler error: Unhandled output component type %#x.", e->component_type); | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2024-10-05 21:10:04 +02:00
										 |  |  |             vkd3d_string_buffer_printf(buffer, " shader_out_%u;\n", e->semantic_index); | 
					
						
							| 
									
										
										
										
											2024-10-03 14:23:00 +02:00
										 |  |  |             ++count; | 
					
						
							| 
									
										
										
										
											2023-11-22 14:33:18 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-10-03 14:23:00 +02:00
										 |  |  |         if (count) | 
					
						
							|  |  |  |             vkd3d_string_buffer_printf(buffer, "\n"); | 
					
						
							| 
									
										
										
										
											2023-12-16 16:11:35 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |     else if (gen->limits.output_count) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-09-30 12:04:31 +02:00
										 |  |  |         shader_glsl_generate_interface_block(gen, signature, "out", gen->limits.output_count); | 
					
						
							| 
									
										
										
										
											2024-10-03 14:23:00 +02:00
										 |  |  |         vkd3d_string_buffer_printf(buffer, "\n"); | 
					
						
							| 
									
										
										
										
											2023-11-22 14:33:18 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-18 22:52:13 +02:00
										 |  |  | static void shader_glsl_handle_global_flags(struct vkd3d_string_buffer *buffer, | 
					
						
							|  |  |  |         struct vkd3d_glsl_generator *gen, enum vsir_global_flags flags) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (flags & VKD3DSGF_FORCE_EARLY_DEPTH_STENCIL) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         vkd3d_string_buffer_printf(buffer, "layout(early_fragment_tests) in;\n"); | 
					
						
							|  |  |  |         flags &= ~VKD3DSGF_FORCE_EARLY_DEPTH_STENCIL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-29 22:04:25 +02:00
										 |  |  |     if (flags & ~VKD3DSGF_REFACTORING_ALLOWED) | 
					
						
							| 
									
										
										
										
											2024-10-18 22:52:13 +02:00
										 |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                 "Internal compiler error: Unhandled global flags %#"PRIx64".", (uint64_t)flags); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-23 21:02:31 +05:30
										 |  |  | static void shader_glsl_generate_declarations(struct vkd3d_glsl_generator *gen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const struct vsir_program *program = gen->program; | 
					
						
							|  |  |  |     struct vkd3d_string_buffer *buffer = gen->buffer; | 
					
						
							| 
									
										
										
										
											2024-10-06 00:10:19 +02:00
										 |  |  |     const struct vsir_thread_group_size *group_size; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (program->shader_version.type == VKD3D_SHADER_TYPE_COMPUTE) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         group_size = &program->thread_group_size; | 
					
						
							|  |  |  |         vkd3d_string_buffer_printf(buffer, "layout(local_size_x = %u, local_size_y = %u, local_size_z = %u) in;\n\n", | 
					
						
							|  |  |  |                 group_size->x, group_size->y, group_size->z); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-08-23 21:02:31 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-18 22:52:13 +02:00
										 |  |  |     shader_glsl_handle_global_flags(buffer, gen, program->global_flags); | 
					
						
							| 
									
										
										
										
											2024-10-18 22:38:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-25 00:35:48 +01:00
										 |  |  |     shader_glsl_generate_descriptor_declarations(gen); | 
					
						
							| 
									
										
										
										
											2023-11-22 14:33:18 +01:00
										 |  |  |     shader_glsl_generate_input_declarations(gen); | 
					
						
							| 
									
										
										
										
											2023-12-16 16:11:35 +01:00
										 |  |  |     shader_glsl_generate_output_declarations(gen); | 
					
						
							| 
									
										
										
										
											2023-11-22 14:33:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (gen->limits.input_count) | 
					
						
							|  |  |  |         vkd3d_string_buffer_printf(buffer, "vec4 %s_in[%u];\n", gen->prefix, gen->limits.input_count); | 
					
						
							| 
									
										
										
										
											2023-12-16 16:11:35 +01:00
										 |  |  |     if (gen->limits.output_count) | 
					
						
							|  |  |  |         vkd3d_string_buffer_printf(buffer, "vec4 %s_out[%u];\n", gen->prefix, gen->limits.output_count); | 
					
						
							| 
									
										
										
										
											2021-08-23 21:02:31 +05:30
										 |  |  |     if (program->temp_count) | 
					
						
							| 
									
										
										
										
											2023-11-22 14:33:18 +01:00
										 |  |  |         vkd3d_string_buffer_printf(buffer, "vec4 r[%u];\n", program->temp_count); | 
					
						
							|  |  |  |     vkd3d_string_buffer_printf(buffer, "\n"); | 
					
						
							| 
									
										
										
										
											2021-08-23 21:02:31 +05:30
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-21 19:28:22 +02:00
										 |  |  | static int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *gen, struct vkd3d_shader_code *out) | 
					
						
							| 
									
										
										
										
											2021-08-19 20:18:13 +05:30
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-10-21 19:28:22 +02:00
										 |  |  |     const struct vkd3d_shader_instruction_array *instructions = &gen->program->instructions; | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  |     struct vkd3d_string_buffer *buffer = gen->buffer; | 
					
						
							| 
									
										
										
										
											2023-01-20 12:24:20 +10:00
										 |  |  |     unsigned int i; | 
					
						
							| 
									
										
										
										
											2021-08-19 20:18:13 +05:30
										 |  |  |     void *code; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-18 15:17:33 +02:00
										 |  |  |     MESSAGE("Generating a GLSL shader. This is unsupported; you get to keep all the pieces if it breaks.\n"); | 
					
						
							| 
									
										
										
										
											2024-03-07 20:55:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-21 19:28:22 +02:00
										 |  |  |     vkd3d_string_buffer_printf(buffer, "#version 440\n\n"); | 
					
						
							| 
									
										
										
										
											2021-08-19 20:18:13 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-21 19:28:22 +02:00
										 |  |  |     vkd3d_string_buffer_printf(buffer, "/* Generated by %s. */\n\n", vkd3d_shader_get_version(NULL, NULL)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-23 21:02:31 +05:30
										 |  |  |     shader_glsl_generate_declarations(gen); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-21 19:28:22 +02:00
										 |  |  |     vkd3d_string_buffer_printf(buffer, "void main()\n{\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ++gen->indent; | 
					
						
							| 
									
										
										
										
											2023-11-22 14:33:18 +01:00
										 |  |  |     shader_glsl_shader_prologue(gen); | 
					
						
							| 
									
										
										
										
											2023-11-17 18:39:48 +01:00
										 |  |  |     for (i = 0; i < instructions->count; ++i) | 
					
						
							| 
									
										
										
										
											2021-08-19 20:18:13 +05:30
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2021-10-21 19:28:22 +02:00
										 |  |  |         vkd3d_glsl_handle_instruction(gen, &instructions->elements[i]); | 
					
						
							| 
									
										
										
										
											2021-08-19 20:18:13 +05:30
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-21 19:28:22 +02:00
										 |  |  |     vkd3d_string_buffer_printf(buffer, "}\n"); | 
					
						
							| 
									
										
										
										
											2023-11-17 06:59:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (TRACE_ON()) | 
					
						
							| 
									
										
										
										
											2021-10-21 19:28:22 +02:00
										 |  |  |         vkd3d_string_buffer_trace(buffer); | 
					
						
							| 
									
										
										
										
											2023-11-17 06:59:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-21 19:28:22 +02:00
										 |  |  |     if (gen->failed) | 
					
						
							| 
									
										
										
										
											2021-10-06 17:11:45 +02:00
										 |  |  |         return VKD3D_ERROR_INVALID_SHADER; | 
					
						
							| 
									
										
										
										
											2021-08-19 20:18:13 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-21 19:28:22 +02:00
										 |  |  |     if ((code = vkd3d_malloc(buffer->buffer_size))) | 
					
						
							| 
									
										
										
										
											2021-08-19 20:18:13 +05:30
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2021-10-21 19:28:22 +02:00
										 |  |  |         memcpy(code, buffer->buffer, buffer->content_size); | 
					
						
							|  |  |  |         out->size = buffer->content_size; | 
					
						
							| 
									
										
										
										
											2021-08-19 20:18:13 +05:30
										 |  |  |         out->code = code; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else return VKD3D_ERROR_OUT_OF_MEMORY; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return VKD3D_OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-17 18:36:33 +01:00
										 |  |  | static void vkd3d_glsl_generator_cleanup(struct vkd3d_glsl_generator *gen) | 
					
						
							| 
									
										
										
										
											2021-08-19 20:18:13 +05:30
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  |     vkd3d_string_buffer_release(&gen->string_buffers, gen->buffer); | 
					
						
							|  |  |  |     vkd3d_string_buffer_cache_cleanup(&gen->string_buffers); | 
					
						
							| 
									
										
										
										
											2023-11-17 18:36:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-22 14:33:18 +01:00
										 |  |  | static void shader_glsl_init_limits(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_version *version) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     struct shader_limits *limits = &gen->limits; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (version->major < 4 || version->major >= 6) | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                 "Internal compiler error: Unhandled shader version %u.%u.", version->major, version->minor); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     switch (version->type) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         case VKD3D_SHADER_TYPE_VERTEX: | 
					
						
							|  |  |  |             limits->input_count = 32; | 
					
						
							| 
									
										
										
										
											2023-12-16 16:11:35 +01:00
										 |  |  |             limits->output_count = 32; | 
					
						
							| 
									
										
										
										
											2023-11-22 14:33:18 +01:00
										 |  |  |             break; | 
					
						
							|  |  |  |         case VKD3D_SHADER_TYPE_PIXEL: | 
					
						
							|  |  |  |             limits->input_count = 32; | 
					
						
							| 
									
										
										
										
											2023-12-16 16:11:35 +01:00
										 |  |  |             limits->output_count = 8; | 
					
						
							| 
									
										
										
										
											2023-11-22 14:33:18 +01:00
										 |  |  |             break; | 
					
						
							| 
									
										
										
										
											2024-10-06 00:10:19 +02:00
										 |  |  |         case VKD3D_SHADER_TYPE_COMPUTE: | 
					
						
							|  |  |  |             limits->input_count = 0; | 
					
						
							|  |  |  |             limits->output_count = 0; | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2023-11-22 14:33:18 +01:00
										 |  |  |         default: | 
					
						
							|  |  |  |             vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                     "Internal compiler error: Unhandled shader type %#x.", version->type); | 
					
						
							|  |  |  |             limits->input_count = 0; | 
					
						
							| 
									
										
										
										
											2023-12-16 16:11:35 +01:00
										 |  |  |             limits->output_count = 0; | 
					
						
							| 
									
										
										
										
											2023-11-22 14:33:18 +01:00
										 |  |  |             break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-17 18:36:33 +01:00
										 |  |  | static void vkd3d_glsl_generator_init(struct vkd3d_glsl_generator *gen, | 
					
						
							| 
									
										
										
										
											2024-02-25 00:35:48 +01:00
										 |  |  |         struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info, | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |         const struct vkd3d_shader_scan_combined_resource_sampler_info *combined_sampler_info, | 
					
						
							| 
									
										
										
										
											2024-02-25 00:35:48 +01:00
										 |  |  |         struct vkd3d_shader_message_context *message_context) | 
					
						
							| 
									
										
										
										
											2023-11-17 18:36:33 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-11-22 14:33:18 +01:00
										 |  |  |     enum vkd3d_shader_type type = program->shader_version.type; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-17 18:36:33 +01:00
										 |  |  |     memset(gen, 0, sizeof(*gen)); | 
					
						
							| 
									
										
										
										
											2023-11-17 18:39:48 +01:00
										 |  |  |     gen->program = program; | 
					
						
							| 
									
										
										
										
											2021-07-14 03:41:32 +05:30
										 |  |  |     vkd3d_string_buffer_cache_init(&gen->string_buffers); | 
					
						
							|  |  |  |     gen->buffer = vkd3d_string_buffer_get(&gen->string_buffers); | 
					
						
							| 
									
										
										
										
											2024-02-25 00:35:48 +01:00
										 |  |  |     gen->location.source_name = compile_info->source_name; | 
					
						
							| 
									
										
										
										
											2023-11-17 18:36:33 +01:00
										 |  |  |     gen->message_context = message_context; | 
					
						
							| 
									
										
										
										
											2023-11-22 14:33:18 +01:00
										 |  |  |     if (!(gen->prefix = shader_glsl_get_prefix(type))) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, | 
					
						
							|  |  |  |                 "Internal compiler error: Unhandled shader type %#x.", type); | 
					
						
							|  |  |  |         gen->prefix = "unknown"; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     shader_glsl_init_limits(gen, &program->shader_version); | 
					
						
							| 
									
										
										
										
											2024-10-06 00:10:19 +02:00
										 |  |  |     gen->interstage_input = type != VKD3D_SHADER_TYPE_VERTEX && type != VKD3D_SHADER_TYPE_COMPUTE; | 
					
						
							|  |  |  |     gen->interstage_output = type != VKD3D_SHADER_TYPE_PIXEL && type != VKD3D_SHADER_TYPE_COMPUTE; | 
					
						
							| 
									
										
										
										
											2024-02-25 00:35:48 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     gen->interface_info = vkd3d_find_struct(compile_info->next, INTERFACE_INFO); | 
					
						
							|  |  |  |     gen->offset_info = vkd3d_find_struct(compile_info->next, DESCRIPTOR_OFFSET_INFO); | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |     gen->combined_sampler_info = combined_sampler_info; | 
					
						
							| 
									
										
										
										
											2023-11-17 18:36:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-24 15:13:06 +01:00
										 |  |  | int glsl_compile(struct vsir_program *program, uint64_t config_flags, | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |         const struct vkd3d_shader_scan_combined_resource_sampler_info *combined_sampler_info, | 
					
						
							| 
									
										
										
										
											2024-02-25 00:35:48 +01:00
										 |  |  |         const struct vkd3d_shader_compile_info *compile_info, | 
					
						
							|  |  |  |         struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) | 
					
						
							| 
									
										
										
										
											2023-11-17 18:36:33 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     struct vkd3d_glsl_generator generator; | 
					
						
							|  |  |  |     int ret; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-05 20:20:03 +02:00
										 |  |  |     if ((ret = vsir_program_transform(program, config_flags, compile_info, message_context)) < 0) | 
					
						
							| 
									
										
										
										
											2024-02-24 15:13:06 +01:00
										 |  |  |         return ret; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-10 20:18:07 +01:00
										 |  |  |     VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM6); | 
					
						
							| 
									
										
										
										
											2025-03-15 16:03:50 +01:00
										 |  |  |     VKD3D_ASSERT(program->has_descriptor_info); | 
					
						
							| 
									
										
										
										
											2024-10-02 14:44:38 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-06 14:00:58 +02:00
										 |  |  |     vkd3d_glsl_generator_init(&generator, program, compile_info, | 
					
						
							| 
									
										
										
										
											2025-03-14 23:14:06 +01:00
										 |  |  |             combined_sampler_info, message_context); | 
					
						
							| 
									
										
										
										
											2023-11-17 18:39:48 +01:00
										 |  |  |     ret = vkd3d_glsl_generator_generate(&generator, out); | 
					
						
							| 
									
										
										
										
											2023-11-17 18:36:33 +01:00
										 |  |  |     vkd3d_glsl_generator_cleanup(&generator); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return ret; | 
					
						
							| 
									
										
										
										
											2021-08-19 20:18:13 +05:30
										 |  |  | } |