diff --git a/rpcs3/Emu/RSX/Program/GLSLSnippets/GenericVSPassthrough.glsl b/rpcs3/Emu/RSX/Program/GLSLSnippets/GenericVSPassthrough.glsl index 0428dc16c4..b57ad58cbc 100644 --- a/rpcs3/Emu/RSX/Program/GLSLSnippets/GenericVSPassthrough.glsl +++ b/rpcs3/Emu/RSX/Program/GLSLSnippets/GenericVSPassthrough.glsl @@ -1,5 +1,7 @@ R"( #version 420 +#extension GL_ARB_separate_shader_objects: enable + layout(location=0) out vec2 tc0; #ifdef VULKAN diff --git a/rpcs3/Emu/RSX/Program/MSAA/ColorResolvePass.glsl b/rpcs3/Emu/RSX/Program/MSAA/ColorResolvePass.glsl new file mode 100644 index 0000000000..d2e1c25b60 --- /dev/null +++ b/rpcs3/Emu/RSX/Program/MSAA/ColorResolvePass.glsl @@ -0,0 +1,37 @@ +R"( +#version 430 + +layout(local_size_x=%WORKGROUP_SIZE_X, local_size_y=%WORKGROUP_SIZE_Y, local_size_z=1) in; + +#ifdef VULKAN +layout(set=0, binding=0, %IMAGE_FORMAT) uniform readonly restrict image2DMS multisampled; +layout(set=0, binding=1) uniform writeonly restrict image2D resolve; +#else +layout(binding=0, %IMAGE_FORMAT) uniform readonly restrict image2DMS multisampled; +layout(binding=1) uniform writeonly restrict image2D resolve; +#endif + +#if %BGRA_SWAP +#define shuffle(x) (x.bgra) +#else +#define shuffle(x) (x) +#endif + +void main() +{ + ivec2 resolve_size = imageSize(resolve); + ivec2 aa_size = imageSize(multisampled); + ivec2 sample_count = resolve_size / aa_size; + + if (any(greaterThanEqual(gl_GlobalInvocationID.xy, uvec2(resolve_size)))) return; + + ivec2 resolve_coords = ivec2(gl_GlobalInvocationID.xy); + ivec2 aa_coords = resolve_coords / sample_count; + ivec2 sample_loc = ivec2(resolve_coords % sample_count); + int sample_index = sample_loc.x + (sample_loc.y * sample_count.y); + + vec4 aa_sample = imageLoad(multisampled, aa_coords, sample_index); + imageStore(resolve, resolve_coords, shuffle(aa_sample)); +} + +)" diff --git a/rpcs3/Emu/RSX/Program/MSAA/ColorUnresolvePass.glsl b/rpcs3/Emu/RSX/Program/MSAA/ColorUnresolvePass.glsl new file mode 100644 index 0000000000..201314e8c1 --- /dev/null +++ b/rpcs3/Emu/RSX/Program/MSAA/ColorUnresolvePass.glsl @@ -0,0 +1,37 @@ +R"( +#version 430 + +layout(local_size_x=%WORKGROUP_SIZE_X, local_size_y=%WORKGROUP_SIZE_Y, local_size_z=1) in; + +#ifdef VULKAN +layout(set=0, binding=0) uniform writeonly restrict image2DMS multisampled; +layout(set=0, binding=1, %IMAGE_FORMAT) uniform readonly restrict image2D resolve; +#else +layout(binding=30) uniform readonly restrict image2DMS multisampled; +layout(binding=31, %IMAGE_FORMAT) uniform readonly restrict image2D resolve; +#endif + +#if %BGRA_SWAP +#define shuffle(x) (x.bgra) +#else +#define shuffle(x) (x) +#endif + +void main() +{ + ivec2 resolve_size = imageSize(resolve); + ivec2 aa_size = imageSize(multisampled); + ivec2 sample_count = resolve_size / aa_size; + + if (any(greaterThanEqual(gl_GlobalInvocationID.xy, uvec2(resolve_size)))) return; + + ivec2 resolve_coords = ivec2(gl_GlobalInvocationID.xy); + ivec2 aa_coords = resolve_coords / sample_count; + ivec2 sample_loc = ivec2(resolve_coords % sample_count); + int sample_index = sample_loc.x + (sample_loc.y * sample_count.y); + + vec4 resolved_sample = imageLoad(resolve, resolve_coords); + imageStore(multisampled, aa_coords, sample_index, shuffle(resolved_sample)); +} + +)" diff --git a/rpcs3/Emu/RSX/Program/MSAA/DepthResolvePass.glsl b/rpcs3/Emu/RSX/Program/MSAA/DepthResolvePass.glsl new file mode 100644 index 0000000000..cc957aa0ac --- /dev/null +++ b/rpcs3/Emu/RSX/Program/MSAA/DepthResolvePass.glsl @@ -0,0 +1,23 @@ +R"( +#version 420 +#extension GL_ARB_separate_shader_objects: enable + +#ifdef VULKAN +layout(set=0, binding=0) uniform sampler2DMS fs0; +layout(push_constant) uniform static_data { ivec2 sample_count; }; +#else +layout(binding=31) uniform sampler2DMS fs0; +uniform ivec2 sample_count; +#endif + +void main() +{ + ivec2 out_coord = ivec2(gl_FragCoord.xy); + ivec2 in_coord = (out_coord / sample_count.xy); + ivec2 sample_loc = out_coord % sample_count.xy; + int sample_index = sample_loc.x + (sample_loc.y * sample_count.y); + float frag_depth = texelFetch(fs0, in_coord, sample_index).x; + gl_FragDepth = frag_depth; +} + +)" diff --git a/rpcs3/Emu/RSX/Program/MSAA/DepthStencilResolvePass.glsl b/rpcs3/Emu/RSX/Program/MSAA/DepthStencilResolvePass.glsl new file mode 100644 index 0000000000..c547cc46b8 --- /dev/null +++ b/rpcs3/Emu/RSX/Program/MSAA/DepthStencilResolvePass.glsl @@ -0,0 +1,28 @@ +R"( +#version 420 +#extension GL_ARB_separate_shader_objects: enable +#extension GL_ARB_shader_stencil_export : enable + +#ifdef VULKAN +layout(set=0, binding=0) uniform sampler2DMS fs0; +layout(set=0, binding=1) uniform usampler2DMS fs1; +layout(push_constant) uniform static_data { ivec2 sample_count; }; +#else +layout(binding=31) uniform sampler2DMS fs0; +layout(binding=30) uniform usampler2DMS fs1; +uniform ivec2 sample_count; +#endif + +void main() +{ + ivec2 out_coord = ivec2(gl_FragCoord.xy); + ivec2 in_coord = (out_coord / sample_count.xy); + ivec2 sample_loc = out_coord % ivec2(sample_count.xy); + int sample_index = sample_loc.x + (sample_loc.y * sample_count.y); + float frag_depth = texelFetch(fs0, in_coord, sample_index).x; + uint frag_stencil = texelFetch(fs1, in_coord, sample_index).x; + gl_FragDepth = frag_depth; + gl_FragStencilRefARB = int(frag_stencil); +} + +)" diff --git a/rpcs3/Emu/RSX/Program/MSAA/DepthStencilUnresolvePass.glsl b/rpcs3/Emu/RSX/Program/MSAA/DepthStencilUnresolvePass.glsl new file mode 100644 index 0000000000..de10cc351b --- /dev/null +++ b/rpcs3/Emu/RSX/Program/MSAA/DepthStencilUnresolvePass.glsl @@ -0,0 +1,28 @@ +R"( +#version 420 +#extension GL_ARB_separate_shader_objects: enable +#extension GL_ARB_shader_stencil_export : enable + +#ifdef VULKAN +layout(set=0, binding=0) uniform sampler2D fs0; +layout(set=0, binding=1) uniform usampler2D fs1; +layout(push_constant) uniform static_data { ivec2 sample_count; }; +#else +layout(binding=31) uniform sampler2D fs0; +layout(binding=30) uniform usampler2D fs1; +uniform ivec2 sample_count; +#endif + +void main() +{ + ivec2 pixel_coord = ivec2(gl_FragCoord.xy); + pixel_coord *= sample_count.xy; + pixel_coord.x += (gl_SampleID % sample_count.x); + pixel_coord.y += (gl_SampleID / sample_count.x); + float frag_depth = texelFetch(fs0, pixel_coord, 0).x; + uint frag_stencil = texelFetch(fs1, pixel_coord, 0).x; + gl_FragDepth = frag_depth; + gl_FragStencilRefARB = int(frag_stencil); +} + +)" diff --git a/rpcs3/Emu/RSX/Program/MSAA/DepthUnresolvePass.glsl b/rpcs3/Emu/RSX/Program/MSAA/DepthUnresolvePass.glsl new file mode 100644 index 0000000000..c4e5ee2f63 --- /dev/null +++ b/rpcs3/Emu/RSX/Program/MSAA/DepthUnresolvePass.glsl @@ -0,0 +1,23 @@ +R"( +#version 420 +#extension GL_ARB_separate_shader_objects: enable + +#ifdef VULKAN +layout(set=0, binding=0) uniform sampler2D fs0; +layout(push_constant) uniform static_data { ivec2 sample_count; }; +#else +layout(binding=31) uniform sampler2D fs0; +uniform ivec2 sample_count; +#endif + +void main() +{ + ivec2 pixel_coord = ivec2(gl_FragCoord.xy); + pixel_coord *= sample_count.xy; + pixel_coord.x += (gl_SampleID % sample_count.x); + pixel_coord.y += (gl_SampleID / sample_count.x); + float frag_depth = texelFetch(fs0, pixel_coord, 0).x; + gl_FragDepth = frag_depth; +} + +)" diff --git a/rpcs3/Emu/RSX/Program/MSAA/StencilResolvePass.glsl b/rpcs3/Emu/RSX/Program/MSAA/StencilResolvePass.glsl new file mode 100644 index 0000000000..cd81f4b093 --- /dev/null +++ b/rpcs3/Emu/RSX/Program/MSAA/StencilResolvePass.glsl @@ -0,0 +1,28 @@ +R"( +#version 420 +#extension GL_ARB_separate_shader_objects: enable + +#ifdef VULKAN +layout(set=0, binding=0) uniform usampler2DMS fs0; +layout(push_constant) uniform static_data +{ + layout(offset=0) ivec2 sample_count; + layout(offset=8) int stencil_mask; +} +#else +layout(binding=31) uniform usampler2DMS fs0; +uniform ivec2 sample_count; +uniform int stencil_mask; +#endif + +void main() +{ + ivec2 out_coord = ivec2(gl_FragCoord.xy); + ivec2 in_coord = (out_coord / sample_count.xy); + ivec2 sample_loc = out_coord % sample_count.xy; + int sample_index = sample_loc.x + (sample_loc.y * sample_count.y); + uint frag_stencil = texelFetch(fs0, in_coord, sample_index).x; + if ((frag_stencil & uint(stencil_mask)) == 0) discard; +} + +)" diff --git a/rpcs3/Emu/RSX/Program/MSAA/StencilUnresolvePass.glsl b/rpcs3/Emu/RSX/Program/MSAA/StencilUnresolvePass.glsl new file mode 100644 index 0000000000..02a74538a8 --- /dev/null +++ b/rpcs3/Emu/RSX/Program/MSAA/StencilUnresolvePass.glsl @@ -0,0 +1,28 @@ +R"( +#version 420 +#extension GL_ARB_separate_shader_objects: enable + +#ifdef VULKAN +layout(set=0, binding=0) uniform usampler2D fs0; +layout(push_constant) uniform static_data +{ + layout(offset=0) ivec2 sample_count; + layout(offset=8) int stencil_mask; +} +#else +layout(binding=31) uniform usampler2D fs0; +uniform ivec2 sample_count; +uniform int stencil_mask; +#endif + +void main() +{ + ivec2 pixel_coord = ivec2(gl_FragCoord.xy); + pixel_coord *= sample_count.xy; + pixel_coord.x += (gl_SampleID % sample_count.x); + pixel_coord.y += (gl_SampleID / sample_count.x); + uint frag_stencil = texelFetch(fs0, pixel_coord, 0).x; + if ((frag_stencil & uint(stencil_mask)) == 0) discard; +} + +)" diff --git a/rpcs3/Emu/RSX/VK/VKResolveHelper.cpp b/rpcs3/Emu/RSX/VK/VKResolveHelper.cpp index ca30abfc06..75a013ddfd 100644 --- a/rpcs3/Emu/RSX/VK/VKResolveHelper.cpp +++ b/rpcs3/Emu/RSX/VK/VKResolveHelper.cpp @@ -253,4 +253,90 @@ namespace vk if (g_depthstencil_resolver) g_depthstencil_resolver->free_resources(); if (g_depthstencil_unresolver) g_depthstencil_unresolver->free_resources(); } + + + void cs_resolve_base::build(const std::string& format_prefix, bool unresolve, bool bgra_swap) + { + create(); + + switch (optimal_group_size) + { + default: + case 64: + cs_wave_x = 8; + cs_wave_y = 8; + break; + case 32: + cs_wave_x = 8; + cs_wave_y = 4; + break; + } + + static const char* resolve_kernel = + #include "Emu/RSX/Program/MSAA/ColorResolvePass.glsl" + ; + + static const char* unresolve_kernel = + #include "Emu/RSX/Program/MSAA/ColorUnresolvePass.glsl" + ; + + const std::pair syntax_replace[] = + { + { "%WORKGROUP_SIZE_X", std::to_string(cs_wave_x) }, + { "%WORKGROUP_SIZE_Y", std::to_string(cs_wave_y) }, + { "%IMAGE_FORMAT", format_prefix }, + { "%BGRA_SWAP", bgra_swap ? "1" : "0" } + }; + + m_src = unresolve ? unresolve_kernel : resolve_kernel; + m_src = fmt::replace_all(m_src, syntax_replace); + + rsx_log.notice("Compute shader:\n%s", m_src); + } + + void depth_resolve_base::build(bool resolve_depth, bool resolve_stencil, bool is_unresolve) + { + vs_src = + #include "Emu/RSX/Program/GLSLSnippets/GenericVSPassthrough.glsl" + ; + + static const char* depth_resolver = + #include "Emu/RSX/Program/MSAA/DepthResolvePass.glsl" + ; + + static const char* depth_unresolver = + #include "Emu/RSX/Program/MSAA/DepthUnresolvePass.glsl" + ; + + static const char* stencil_resolver = + #include "Emu/RSX/Program/MSAA/StencilResolvePass.glsl" + ; + + static const char* stencil_unresolver = + #include "Emu/RSX/Program/MSAA/StencilUnresolvePass.glsl" + ; + + static const char* depth_stencil_resolver = + #include "Emu/RSX/Program/MSAA/DepthStencilResolvePass.glsl" + ; + + static const char* depth_stencil_unresolver = + #include "Emu/RSX/Program/MSAA/DepthStencilUnresolvePass.glsl" + ; + + if (resolve_depth && resolve_stencil) + { + fs_src = is_unresolve ? depth_stencil_unresolver : depth_stencil_resolver; + } + else if (resolve_depth) + { + fs_src = is_unresolve ? depth_unresolver : depth_resolver; + } + else if (resolve_stencil) + { + fs_src = is_unresolve ? stencil_unresolver : stencil_resolver; + } + + rsx_log.notice("Resolve shader:\n%s", fs_src); + } } \ No newline at end of file diff --git a/rpcs3/Emu/RSX/VK/VKResolveHelper.h b/rpcs3/Emu/RSX/VK/VKResolveHelper.h index 6b83a5af9c..edc48a91cd 100644 --- a/rpcs3/Emu/RSX/VK/VKResolveHelper.h +++ b/rpcs3/Emu/RSX/VK/VKResolveHelper.h @@ -21,70 +21,7 @@ namespace vk virtual ~cs_resolve_base() {} - // FIXME: move body to cpp - void build(const std::string& kernel, const std::string& format_prefix, int direction) - { - create(); - - // TODO: Tweak occupancy - switch (optimal_group_size) - { - default: - case 64: - cs_wave_x = 8; - cs_wave_y = 8; - break; - case 32: - cs_wave_x = 8; - cs_wave_y = 4; - break; - } - - const std::pair syntax_replace[] = - { - { "%wx", std::to_string(cs_wave_x) }, - { "%wy", std::to_string(cs_wave_y) }, - }; - - m_src = - "#version 430\n" - "layout(local_size_x=%wx, local_size_y=%wy, local_size_z=1) in;\n" - "\n"; - - m_src = fmt::replace_all(m_src, syntax_replace); - - if (direction == 0) - { - m_src += - "layout(set=0, binding=0, " + format_prefix + ") uniform readonly restrict image2DMS multisampled;\n" - "layout(set=0, binding=1) uniform writeonly restrict image2D resolve;\n"; - } - else - { - m_src += - "layout(set=0, binding=0) uniform writeonly restrict image2DMS multisampled;\n" - "layout(set=0, binding=1, " + format_prefix + ") uniform readonly restrict image2D resolve;\n"; - } - - m_src += - "\n" - "void main()\n" - "{\n" - " ivec2 resolve_size = imageSize(resolve);\n" - " ivec2 aa_size = imageSize(multisampled);\n" - " ivec2 sample_count = resolve_size / aa_size;\n" - "\n" - " if (any(greaterThanEqual(gl_GlobalInvocationID.xy, uvec2(resolve_size)))) return;" - "\n" - " ivec2 resolve_coords = ivec2(gl_GlobalInvocationID.xy);\n" - " ivec2 aa_coords = resolve_coords / sample_count;\n" - " ivec2 sample_loc = ivec2(resolve_coords % sample_count);\n" - " int sample_index = sample_loc.x + (sample_loc.y * sample_count.y);\n" - + kernel + - "}\n"; - - rsx_log.notice("Compute shader:\n%s", m_src); - } + void build(const std::string& format_prefix, bool unresolve, bool bgra_swap); std::vector> get_descriptor_layout() override { @@ -144,14 +81,8 @@ namespace vk { cs_resolve_task(const std::string& format_prefix, bool bgra_swap = false) { - // Allow rgba->bgra transformation for old GeForce cards - const std::string swizzle = bgra_swap? ".bgra" : ""; - - std::string kernel = - " vec4 aa_sample = imageLoad(multisampled, aa_coords, sample_index);\n" - " imageStore(resolve, resolve_coords, aa_sample" + swizzle + ");\n"; - - build(kernel, format_prefix, 0); + // BGRA-swap flag is a workaround to swap channels for old GeForce cards with broken compute image handling + build(format_prefix, false, bgra_swap); } }; @@ -159,14 +90,8 @@ namespace vk { cs_unresolve_task(const std::string& format_prefix, bool bgra_swap = false) { - // Allow rgba->bgra transformation for old GeForce cards - const std::string swizzle = bgra_swap? ".bgra" : ""; - - std::string kernel = - " vec4 resolved_sample = imageLoad(resolve, resolve_coords);\n" - " imageStore(multisampled, aa_coords, sample_index, resolved_sample" + swizzle + ");\n"; - - build(kernel, format_prefix, 1); + // BGRA-swap flag is a workaround to swap channels for old GeForce cards with broken compute image handling + build(format_prefix, true, bgra_swap); } }; @@ -186,41 +111,7 @@ namespace vk m_sampler_filter = VK_FILTER_NEAREST; } - void build(const std::string& kernel, const std::string& extensions, const std::vector& inputs) - { - vs_src = - "#version 450\n" - "#extension GL_ARB_separate_shader_objects : enable\n\n" - "\n" - "void main()\n" - "{\n" - " vec2 positions[] = {vec2(-1., -1.), vec2(1., -1.), vec2(-1., 1.), vec2(1., 1.)};\n" - " gl_Position = vec4(positions[gl_VertexIndex % 4], 0., 1.);\n" - "}\n"; - - fs_src = - "#version 420\n" - "#extension GL_ARB_separate_shader_objects : enable\n"; - fs_src += extensions + - "\n" - "layout(push_constant) uniform static_data{ ivec" + std::to_string(static_parameters_width) + " regs[1]; };\n"; - - int binding = 1; - for (const auto& input : inputs) - { - fs_src += "layout(set=0, binding=" + std::to_string(binding++) + ") uniform " + input + ";\n"; - } - - fs_src += - "//layout(pixel_center_integer) in vec4 gl_FragCoord;\n" - "\n" - "void main()\n" - "{\n"; - fs_src += kernel + - "}\n"; - - rsx_log.notice("Resolve shader:\n%s", fs_src); - } + void build(bool resolve_depth, bool resolve_stencil, bool unresolve); std::vector get_push_constants() override { @@ -263,15 +154,7 @@ namespace vk { depthonly_resolve() { - build( - " ivec2 out_coord = ivec2(gl_FragCoord.xy);\n" - " ivec2 in_coord = (out_coord / regs[0].xy);\n" - " ivec2 sample_loc = out_coord % regs[0].xy;\n" - " int sample_index = sample_loc.x + (sample_loc.y * regs[0].y);\n" - " float frag_depth = texelFetch(fs0, in_coord, sample_index).x;\n" - " gl_FragDepth = frag_depth;\n", - "", - { "sampler2DMS fs0" }); + build(true, false, false); } void run(vk::command_buffer& cmd, vk::viewable_image* msaa_image, vk::viewable_image* resolve_image, VkRenderPass render_pass) @@ -291,15 +174,7 @@ namespace vk { depthonly_unresolve() { - build( - " ivec2 pixel_coord = ivec2(gl_FragCoord.xy);\n" - " pixel_coord *= regs[0].xy;\n" - " pixel_coord.x += (gl_SampleID % regs[0].x);\n" - " pixel_coord.y += (gl_SampleID / regs[0].x);\n" - " float frag_depth = texelFetch(fs0, pixel_coord, 0).x;\n" - " gl_FragDepth = frag_depth;\n", - "", - { "sampler2D fs0" }); + build(true, false, true); } void run(vk::command_buffer& cmd, vk::viewable_image* msaa_image, vk::viewable_image* resolve_image, VkRenderPass render_pass) @@ -340,15 +215,7 @@ namespace vk static_parameters_width = 3; - build( - " ivec2 out_coord = ivec2(gl_FragCoord.xy);\n" - " ivec2 in_coord = (out_coord / regs[0].xy);\n" - " ivec2 sample_loc = out_coord % regs[0].xy;\n" - " int sample_index = sample_loc.x + (sample_loc.y * regs[0].y);\n" - " uint frag_stencil = texelFetch(fs0, in_coord, sample_index).x;\n" - " if ((frag_stencil & uint(regs[0].z)) == 0) discard;\n", - "", - {"usampler2DMS fs0"}); + build(false, true, false); } void get_dynamic_state_entries(std::vector& state_descriptors) override @@ -407,15 +274,7 @@ namespace vk static_parameters_width = 3; - build( - " ivec2 pixel_coord = ivec2(gl_FragCoord.xy);\n" - " pixel_coord *= regs[0].xy;\n" - " pixel_coord.x += (gl_SampleID % regs[0].x);\n" - " pixel_coord.y += (gl_SampleID / regs[0].x);\n" - " uint frag_stencil = texelFetch(fs0, pixel_coord, 0).x;\n" - " if ((frag_stencil & uint(regs[0].z)) == 0) discard;\n", - "", - { "usampler2D fs0" }); + build(false, true, false); } void get_dynamic_state_entries(std::vector& state_descriptors) override @@ -468,19 +327,7 @@ namespace vk renderpass_config.set_stencil_mask(0xFF); m_num_usable_samplers = 2; - build( - " ivec2 out_coord = ivec2(gl_FragCoord.xy);\n" - " ivec2 in_coord = (out_coord / regs[0].xy);\n" - " ivec2 sample_loc = out_coord % ivec2(regs[0].xy);\n" - " int sample_index = sample_loc.x + (sample_loc.y * regs[0].y);\n" - " float frag_depth = texelFetch(fs0, in_coord, sample_index).x;\n" - " uint frag_stencil = texelFetch(fs1, in_coord, sample_index).x;\n" - " gl_FragDepth = frag_depth;\n" - " gl_FragStencilRefARB = int(frag_stencil);\n", - - "#extension GL_ARB_shader_stencil_export : enable\n", - - { "sampler2DMS fs0", "usampler2DMS fs1" }); + build(true, true, false); } void run(vk::command_buffer& cmd, vk::viewable_image* msaa_image, vk::viewable_image* resolve_image, VkRenderPass render_pass) @@ -510,19 +357,7 @@ namespace vk renderpass_config.set_stencil_mask(0xFF); m_num_usable_samplers = 2; - build( - " ivec2 pixel_coord = ivec2(gl_FragCoord.xy);\n" - " pixel_coord *= regs[0].xy;\n" - " pixel_coord.x += (gl_SampleID % regs[0].x);\n" - " pixel_coord.y += (gl_SampleID / regs[0].x);\n" - " float frag_depth = texelFetch(fs0, pixel_coord, 0).x;\n" - " uint frag_stencil = texelFetch(fs1, pixel_coord, 0).x;\n" - " gl_FragDepth = frag_depth;\n" - " gl_FragStencilRefARB = int(frag_stencil);\n", - - "#extension GL_ARB_shader_stencil_export : enable\n", - - { "sampler2D fs0", "usampler2D fs1" }); + build(true, true, true); } void run(vk::command_buffer& cmd, vk::viewable_image* msaa_image, vk::viewable_image* resolve_image, VkRenderPass render_pass) diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index e946326e05..049dc05ab2 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -1030,6 +1030,14 @@ + + + + + + + + diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index 23c7c34fb6..53038d5652 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -130,6 +130,9 @@ {caf84300-5c45-4340-bd9a-8ac859409351} + + {ce6d6b90-8313-4273-b46c-d92bd450c002} + @@ -2802,5 +2805,29 @@ Emu\CPU\Backends\AArch64 + + Emu\GPU\RSX\Program\MSAA + + + Emu\GPU\RSX\Program\MSAA + + + Emu\GPU\RSX\Program\MSAA + + + Emu\GPU\RSX\Program\MSAA + + + Emu\GPU\RSX\Program\MSAA + + + Emu\GPU\RSX\Program\MSAA + + + Emu\GPU\RSX\Program\MSAA + + + Emu\GPU\RSX\Program\MSAA + \ No newline at end of file