mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	video_core: Add vulkan shaders (#6619)
This commit is contained in:
		
							parent
							
								
									7c11b9b689
								
							
						
					
					
						commit
						3faddd5e03
					
				
					 13 changed files with 263 additions and 10 deletions
				
			
		|  | @ -4,13 +4,12 @@ | |||
| 
 | ||||
| set(SHADER_FILES | ||||
|     format_reinterpreter/d24s8_to_rgba8.frag | ||||
|     format_reinterpreter/fullscreen_quad.vert | ||||
|     format_reinterpreter/rgba4_to_rgb5a1.frag | ||||
|     format_reinterpreter/vulkan_d24s8_to_rgba8.comp | ||||
|     texture_filtering/bicubic.frag | ||||
|     texture_filtering/nearest_neighbor.frag | ||||
|     texture_filtering/refine.frag | ||||
|     texture_filtering/scale_force.frag | ||||
|     texture_filtering/tex_coord.vert | ||||
|     texture_filtering/xbrz_freescale.frag | ||||
|     texture_filtering/mmpx.frag | ||||
|     texture_filtering/x_gradient.frag | ||||
|  | @ -20,8 +19,22 @@ set(SHADER_FILES | |||
|     opengl_present.vert | ||||
|     opengl_present_anaglyph.frag | ||||
|     opengl_present_interlaced.frag | ||||
|     vulkan_depth_to_buffer.comp | ||||
|     vulkan_present.frag | ||||
|     vulkan_present.vert | ||||
|     vulkan_present_anaglyph.frag | ||||
|     vulkan_present_interlaced.frag | ||||
|     vulkan_blit_depth_stencil.frag | ||||
| ) | ||||
| 
 | ||||
| find_program(GLSLANGVALIDATOR "glslangValidator") | ||||
| if ("${GLSLANGVALIDATOR}" STREQUAL "GLSLANGVALIDATOR-NOTFOUND") | ||||
|     message(FATAL_ERROR "Required program `glslangValidator` not found.") | ||||
| endif() | ||||
| 
 | ||||
| set(MACROS "-Dgl_VertexID=gl_VertexIndex") | ||||
| set(QUIET_FLAG "--quiet") | ||||
| 
 | ||||
| set(SHADER_INCLUDE ${CMAKE_CURRENT_BINARY_DIR}/include) | ||||
| set(SHADER_DIR ${SHADER_INCLUDE}/video_core/host_shaders) | ||||
| set(HOST_SHADERS_INCLUDE ${SHADER_INCLUDE} PARENT_SCOPE) | ||||
|  | @ -29,6 +42,23 @@ set(HOST_SHADERS_INCLUDE ${SHADER_INCLUDE} PARENT_SCOPE) | |||
| set(INPUT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/source_shader.h.in) | ||||
| set(HEADER_GENERATOR ${CMAKE_CURRENT_SOURCE_DIR}/StringShaderHeader.cmake) | ||||
| 
 | ||||
| # Check if `--quiet` is available on host's glslangValidator version | ||||
| # glslangValidator prints to STDERR iff an unrecognized flag is passed to it | ||||
| execute_process( | ||||
|     COMMAND | ||||
|         ${GLSLANGVALIDATOR} ${QUIET_FLAG} | ||||
|     ERROR_VARIABLE | ||||
|         GLSLANG_ERROR | ||||
|     # STDOUT variable defined to silence unnecessary output during CMake configuration | ||||
|     OUTPUT_VARIABLE | ||||
|         GLSLANG_OUTPUT | ||||
| ) | ||||
| 
 | ||||
| if (NOT GLSLANG_ERROR STREQUAL "") | ||||
|     message(WARNING "Refusing to use unavailable flag `${QUIET_FLAG}` on `${GLSLANGVALIDATOR}`") | ||||
|     set(QUIET_FLAG "") | ||||
| endif() | ||||
| 
 | ||||
| foreach(FILENAME IN ITEMS ${SHADER_FILES}) | ||||
|     string(REPLACE "." "_" SHADER_NAME ${FILENAME}) | ||||
|     set(SOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}) | ||||
|  | @ -48,6 +78,21 @@ foreach(FILENAME IN ITEMS ${SHADER_FILES}) | |||
|         ) | ||||
|         set(SHADER_HEADERS ${SHADER_HEADERS} ${SOURCE_HEADER_FILE}) | ||||
|     endif() | ||||
|     # Skip compiling to SPIR-V OpenGL exclusive files | ||||
|     if (NOT ${FILENAME} MATCHES "opengl.*") | ||||
|         get_filename_component(FILE_NAME ${SHADER_NAME} NAME) | ||||
|         string(TOUPPER ${FILE_NAME}_SPV SPIRV_VARIABLE_NAME) | ||||
|         set(SPIRV_HEADER_FILE ${SHADER_DIR}/${SHADER_NAME}_spv.h) | ||||
|         add_custom_command( | ||||
|             OUTPUT | ||||
|                 ${SPIRV_HEADER_FILE} | ||||
|             COMMAND | ||||
|                 ${GLSLANGVALIDATOR} --target-env vulkan1.1 --glsl-version 450 ${QUIET_FLAG} ${MACROS} --variable-name ${SPIRV_VARIABLE_NAME} -o ${SPIRV_HEADER_FILE} ${SOURCE_FILE} | ||||
|             MAIN_DEPENDENCY | ||||
|                 ${SOURCE_FILE} | ||||
|         ) | ||||
|         set(SHADER_HEADERS ${SHADER_HEADERS} ${SPIRV_HEADER_FILE}) | ||||
|     endif() | ||||
| endforeach() | ||||
| 
 | ||||
| set(SHADER_SOURCES ${SHADER_FILES}) | ||||
|  |  | |||
|  | @ -0,0 +1,26 @@ | |||
| // Copyright 2023 Citra Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
| 
 | ||||
| #version 450 core | ||||
| #extension GL_EXT_samplerless_texture_functions : require | ||||
| 
 | ||||
| layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; | ||||
| layout(set = 0, binding = 0) uniform highp texture2D depth; | ||||
| layout(set = 0, binding = 1) uniform lowp utexture2D stencil; | ||||
| layout(set = 0, binding = 2, rgba8) uniform highp writeonly image2D color; | ||||
| 
 | ||||
| layout(push_constant, std140) uniform ComputeInfo { | ||||
|     mediump ivec2 src_offset; | ||||
|     mediump ivec2 extent; | ||||
| }; | ||||
| 
 | ||||
| void main() { | ||||
|     ivec2 tex_coord = src_offset + ivec2(gl_GlobalInvocationID.xy); | ||||
|     highp uint depth_val = | ||||
|         uint(texelFetch(depth, tex_coord, 0).x * (exp2(32.0) - 1.0)); | ||||
|     lowp uint stencil_val = texelFetch(stencil, tex_coord, 0).x; | ||||
|     highp uvec4 components = | ||||
|         uvec4(stencil_val, (uvec3(depth_val) >> uvec3(24u, 16u, 8u)) & 0x000000FFu); | ||||
|     imageStore(color, tex_coord, vec4(components) / (exp2(8.0) - 1.0)); | ||||
| } | ||||
|  | @ -9,8 +9,20 @@ out gl_PerVertex { | |||
| 
 | ||||
| layout(location = 0) out vec2 texcoord; | ||||
| 
 | ||||
| layout (location = 0) uniform vec2 tex_scale; | ||||
| layout (location = 1) uniform vec2 tex_offset; | ||||
| #ifdef VULKAN | ||||
| #define BEGIN_PUSH_CONSTANTS layout(push_constant) uniform PushConstants { | ||||
| #define END_PUSH_CONSTANTS }; | ||||
| #define UNIFORM(n) | ||||
| #else // if OpenGL | ||||
| #define BEGIN_PUSH_CONSTANTS | ||||
| #define END_PUSH_CONSTANTS | ||||
| #define UNIFORM(n) layout (location = n) uniform | ||||
| #endif | ||||
| 
 | ||||
| BEGIN_PUSH_CONSTANTS | ||||
| UNIFORM(0) vec2 tex_scale; | ||||
| UNIFORM(1) vec2 tex_offset; | ||||
| END_PUSH_CONSTANTS | ||||
| 
 | ||||
| void main() { | ||||
|     float x = float((gl_VertexID & 1) << 2); | ||||
|  |  | |||
|  | @ -9,7 +9,14 @@ layout(location = 0) in vec2 tex_coord; | |||
| layout(location = 0) out vec4 frag_color; | ||||
| 
 | ||||
| layout(binding = 0) uniform sampler2D tex; | ||||
| layout(location = 2) uniform lowp float scale; | ||||
| 
 | ||||
| #ifdef VULKAN | ||||
| layout(push_constant, std140) uniform XbrzInfo { | ||||
|     float scale; | ||||
| }; | ||||
| #else | ||||
| layout(location = 2) uniform float scale; | ||||
| #endif | ||||
| 
 | ||||
| const int BLEND_NONE = 0; | ||||
| const int BLEND_NORMAL = 1; | ||||
|  |  | |||
							
								
								
									
										16
									
								
								src/video_core/host_shaders/vulkan_blit_depth_stencil.frag
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/video_core/host_shaders/vulkan_blit_depth_stencil.frag
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,16 @@ | |||
| // Copyright 2022 Citra Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
| 
 | ||||
| #version 450 core | ||||
| #extension GL_ARB_shader_stencil_export : require | ||||
| 
 | ||||
| layout(binding = 0) uniform sampler2D depth_tex; | ||||
| layout(binding = 1) uniform usampler2D stencil_tex; | ||||
| 
 | ||||
| layout(location = 0) in vec2 texcoord; | ||||
| 
 | ||||
| void main() { | ||||
|     gl_FragDepth = textureLod(depth_tex, texcoord, 0).r; | ||||
|     gl_FragStencilRefARB = int(textureLod(stencil_tex, texcoord, 0).r); | ||||
| } | ||||
							
								
								
									
										29
									
								
								src/video_core/host_shaders/vulkan_depth_to_buffer.comp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/video_core/host_shaders/vulkan_depth_to_buffer.comp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,29 @@ | |||
| // Copyright 2023 Citra Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
| 
 | ||||
| #version 450 core | ||||
| 
 | ||||
| layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; | ||||
| layout(binding = 0) uniform highp sampler2D depth; | ||||
| layout(binding = 1) uniform lowp usampler2D stencil; | ||||
| 
 | ||||
| layout(binding = 2) writeonly buffer OutputBuffer{ | ||||
|     uint pixels[]; | ||||
| } staging; | ||||
| 
 | ||||
| layout(push_constant, std140) uniform ComputeInfo { | ||||
|     mediump ivec2 src_offset; | ||||
|     mediump ivec2 extent; | ||||
| }; | ||||
| 
 | ||||
| void main() { | ||||
|     ivec2 rect = ivec2(gl_NumWorkGroups.xy) * ivec2(8); | ||||
|     ivec2 dst_coord = ivec2(gl_GlobalInvocationID.xy); | ||||
|     ivec2 tex_icoord = src_offset + dst_coord; | ||||
|     highp vec2 tex_coord = vec2(tex_icoord) / vec2(extent); | ||||
|     highp uint depth_val = uint(texture(depth, tex_coord).x * (exp2(24.0) - 1.0)); | ||||
|     lowp uint stencil_val = texture(stencil, tex_coord).x; | ||||
|     highp uint value = stencil_val | (depth_val << 8); | ||||
|     staging.pixels[dst_coord.y * rect.x + dst_coord.x] = value; | ||||
| } | ||||
							
								
								
									
										25
									
								
								src/video_core/host_shaders/vulkan_present.frag
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/video_core/host_shaders/vulkan_present.frag
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,25 @@ | |||
| // Copyright 2022 Citra Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
| 
 | ||||
| #version 450 core | ||||
| #extension GL_ARB_separate_shader_objects : enable | ||||
| 
 | ||||
| layout (location = 0) in vec2 frag_tex_coord; | ||||
| layout (location = 0) out vec4 color; | ||||
| 
 | ||||
| layout (push_constant, std140) uniform DrawInfo { | ||||
|     mat4 modelview_matrix; | ||||
|     vec4 i_resolution; | ||||
|     vec4 o_resolution; | ||||
|     int screen_id_l; | ||||
|     int screen_id_r; | ||||
|     int layer; | ||||
|     int reverse_interlaced; | ||||
| }; | ||||
| 
 | ||||
| layout (set = 0, binding = 0) uniform sampler2D screen_textures[3]; | ||||
| 
 | ||||
| void main() { | ||||
|     color = texture(screen_textures[screen_id_l], frag_tex_coord); | ||||
| } | ||||
							
								
								
									
										25
									
								
								src/video_core/host_shaders/vulkan_present.vert
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/video_core/host_shaders/vulkan_present.vert
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,25 @@ | |||
| // Copyright 2022 Citra Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
| 
 | ||||
| #version 450 core | ||||
| #extension GL_ARB_separate_shader_objects : enable | ||||
| 
 | ||||
| layout (location = 0) in vec2 vert_position; | ||||
| layout (location = 1) in vec2 vert_tex_coord; | ||||
| layout (location = 0) out vec2 frag_tex_coord; | ||||
| 
 | ||||
| layout (push_constant, std140) uniform DrawInfo { | ||||
|     mat4 modelview_matrix; | ||||
|     vec4 i_resolution; | ||||
|     vec4 o_resolution; | ||||
|     int screen_id_l; | ||||
|     int screen_id_r; | ||||
|     int layer; | ||||
| }; | ||||
| 
 | ||||
| void main() { | ||||
|     vec4 position = vec4(vert_position, 0.0, 1.0) * modelview_matrix; | ||||
|     gl_Position = vec4(position.x, position.y, 0.0, 1.0); | ||||
|     frag_tex_coord = vert_tex_coord; | ||||
| } | ||||
							
								
								
									
										39
									
								
								src/video_core/host_shaders/vulkan_present_anaglyph.frag
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								src/video_core/host_shaders/vulkan_present_anaglyph.frag
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,39 @@ | |||
| // Copyright 2022 Citra Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
| 
 | ||||
| #version 450 core | ||||
| #extension GL_ARB_separate_shader_objects : enable | ||||
| 
 | ||||
| layout (location = 0) in vec2 frag_tex_coord; | ||||
| layout (location = 0) out vec4 color; | ||||
| 
 | ||||
| // Anaglyph Red-Cyan shader based on Dubois algorithm | ||||
| // Constants taken from the paper: | ||||
| // "Conversion of a Stereo Pair to Anaglyph with | ||||
| // the Least-Squares Projection Method" | ||||
| // Eric Dubois, March 2009 | ||||
| const mat3 l = mat3( 0.437, 0.449, 0.164, | ||||
|               -0.062,-0.062,-0.024, | ||||
|               -0.048,-0.050,-0.017); | ||||
| const mat3 r = mat3(-0.011,-0.032,-0.007, | ||||
|                0.377, 0.761, 0.009, | ||||
|               -0.026,-0.093, 1.234); | ||||
| 
 | ||||
| layout (push_constant, std140) uniform DrawInfo { | ||||
|     mat4 modelview_matrix; | ||||
|     vec4 i_resolution; | ||||
|     vec4 o_resolution; | ||||
|     int screen_id_l; | ||||
|     int screen_id_r; | ||||
|     int layer; | ||||
|     int reverse_interlaced; | ||||
| }; | ||||
| 
 | ||||
| layout (set = 0, binding = 0) uniform sampler2D screen_textures[3]; | ||||
| 
 | ||||
| void main() { | ||||
|     vec4 color_tex_l = texture(screen_textures[screen_id_l], frag_tex_coord); | ||||
|     vec4 color_tex_r = texture(screen_textures[screen_id_r], frag_tex_coord); | ||||
|     color = vec4(color_tex_l.rgb*l+color_tex_r.rgb*r, color_tex_l.a); | ||||
| } | ||||
							
								
								
									
										29
									
								
								src/video_core/host_shaders/vulkan_present_interlaced.frag
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/video_core/host_shaders/vulkan_present_interlaced.frag
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,29 @@ | |||
| // Copyright 2022 Citra Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
| 
 | ||||
| #version 450 core | ||||
| #extension GL_ARB_separate_shader_objects : enable | ||||
| 
 | ||||
| layout (location = 0) in vec2 frag_tex_coord; | ||||
| layout (location = 0) out vec4 color; | ||||
| 
 | ||||
| layout (push_constant, std140) uniform DrawInfo { | ||||
|     mat4 modelview_matrix; | ||||
|     vec4 i_resolution; | ||||
|     vec4 o_resolution; | ||||
|     int screen_id_l; | ||||
|     int screen_id_r; | ||||
|     int layer; | ||||
|     int reverse_interlaced; | ||||
| }; | ||||
| 
 | ||||
| layout (set = 0, binding = 0) uniform sampler2D screen_textures[3]; | ||||
| 
 | ||||
| void main() { | ||||
|     float screen_row = o_resolution.x * frag_tex_coord.x; | ||||
|     if (int(screen_row) % 2 == reverse_interlaced) | ||||
|         color = texture(screen_textures[screen_id_l], frag_tex_coord); | ||||
|     else | ||||
|         color = texture(screen_textures[screen_id_r], frag_tex_coord); | ||||
| } | ||||
|  | @ -1000,7 +1000,7 @@ void RasterizerCache<T>::UploadSurface(Surface& surface, SurfaceInterval interva | |||
|     } | ||||
| 
 | ||||
|     const BufferTextureCopy upload = { | ||||
|         .buffer_offset = 0, | ||||
|         .buffer_offset = staging.offset, | ||||
|         .buffer_size = staging.size, | ||||
|         .texture_rect = surface.GetSubRect(load_info), | ||||
|         .texture_level = surface.LevelOf(load_info.addr), | ||||
|  | @ -1080,7 +1080,7 @@ void RasterizerCache<T>::DownloadSurface(Surface& surface, SurfaceInterval inter | |||
|         flush_info.width * flush_info.height * surface.GetInternalBytesPerPixel(), false); | ||||
| 
 | ||||
|     const BufferTextureCopy download = { | ||||
|         .buffer_offset = 0, | ||||
|         .buffer_offset = staging.offset, | ||||
|         .buffer_size = staging.size, | ||||
|         .texture_rect = surface.GetSubRect(flush_info), | ||||
|         .texture_level = surface.LevelOf(flush_start), | ||||
|  | @ -1137,7 +1137,7 @@ bool RasterizerCache<T>::ValidateByReinterpretation(Surface& surface, SurfacePar | |||
|     if (reinterpret_id) { | ||||
|         Surface& src_surface = slot_surfaces[reinterpret_id]; | ||||
|         const SurfaceInterval copy_interval = src_surface.GetCopyableInterval(params); | ||||
|         if (boost::icl::is_empty(copy_interval)) { | ||||
|         if (boost::icl::is_empty(copy_interval & interval)) { | ||||
|             return false; | ||||
|         } | ||||
|         const PAddr addr = boost::icl::lower(interval); | ||||
|  |  | |||
|  | @ -75,8 +75,8 @@ struct BufferTextureCopy { | |||
| 
 | ||||
| struct StagingData { | ||||
|     u32 size; | ||||
|     u32 offset; | ||||
|     std::span<u8> mapped; | ||||
|     u64 buffer_offset; | ||||
| }; | ||||
| 
 | ||||
| struct TextureCubeConfig { | ||||
|  |  | |||
|  | @ -144,8 +144,8 @@ VideoCore::StagingData TextureRuntime::FindStaging(u32 size, bool upload) { | |||
|     } | ||||
|     return VideoCore::StagingData{ | ||||
|         .size = size, | ||||
|         .offset = 0, | ||||
|         .mapped = std::span{staging_buffer.data(), size}, | ||||
|         .buffer_offset = 0, | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue