From a516ca5b85d419c0ab8b79bfca92d4fc319d47dc Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 13 Aug 2019 11:17:46 +0200 Subject: [PATCH] [dxvk] Add meta shaders for depth-stencil resolve --- src/dxvk/meson.build | 2 + src/dxvk/shaders/dxvk_resolve_frag_d.frag | 54 ++++++++++++++ src/dxvk/shaders/dxvk_resolve_frag_ds.frag | 83 ++++++++++++++++++++++ 3 files changed, 139 insertions(+) create mode 100644 src/dxvk/shaders/dxvk_resolve_frag_d.frag create mode 100644 src/dxvk/shaders/dxvk_resolve_frag_ds.frag diff --git a/src/dxvk/meson.build b/src/dxvk/meson.build index d24bfd05..867f3002 100644 --- a/src/dxvk/meson.build +++ b/src/dxvk/meson.build @@ -33,6 +33,8 @@ dxvk_shaders = files([ 'shaders/dxvk_pack_d24s8.comp', 'shaders/dxvk_pack_d32s8.comp', + 'shaders/dxvk_resolve_frag_d.frag', + 'shaders/dxvk_resolve_frag_ds.frag', 'shaders/dxvk_resolve_frag_f.frag', 'shaders/dxvk_resolve_frag_f_amd.frag', 'shaders/dxvk_resolve_frag_i.frag', diff --git a/src/dxvk/shaders/dxvk_resolve_frag_d.frag b/src/dxvk/shaders/dxvk_resolve_frag_d.frag new file mode 100644 index 00000000..0b726c97 --- /dev/null +++ b/src/dxvk/shaders/dxvk_resolve_frag_d.frag @@ -0,0 +1,54 @@ +#version 450 + +#define VK_RESOLVE_MODE_NONE_KHR (0) +#define VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR (1 << 0) +#define VK_RESOLVE_MODE_AVERAGE_BIT_KHR (1 << 1) +#define VK_RESOLVE_MODE_MIN_BIT_KHR (1 << 2) +#define VK_RESOLVE_MODE_MAX_BIT_KHR (1 << 3) + +layout(constant_id = 0) const int c_samples = 1; +layout(constant_id = 1) const int c_mode_d = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR; + +layout(binding = 0) uniform sampler2DMSArray s_depth; + +layout(push_constant) +uniform u_info_t { + ivec2 offset; +} u_info; + +float resolve_depth(ivec3 coord) { + float depth = 0.0f; + + switch (c_mode_d) { + case VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR: + depth = texelFetch(s_depth, coord, 0).r; + break; + + case VK_RESOLVE_MODE_AVERAGE_BIT_KHR: + depth = texelFetch(s_depth, coord, 0).r; + for (int i = 1; i < c_samples; i++) + depth += texelFetch(s_depth, coord, i).r; + depth /= float(c_samples); + break; + + case VK_RESOLVE_MODE_MIN_BIT_KHR: + depth = texelFetch(s_depth, coord, 0).r; + for (int i = 1; i < c_samples; i++) + depth = min(depth, texelFetch(s_depth, coord, i).r); + break; + + case VK_RESOLVE_MODE_MAX_BIT_KHR: + depth = texelFetch(s_depth, coord, 0).r; + for (int i = 1; i < c_samples; i++) + depth = max(depth, texelFetch(s_depth, coord, i).r); + break; + } + + return depth; +} + +void main() { + ivec3 coord = ivec3(gl_FragCoord.xy + u_info.offset, gl_Layer); + + gl_FragDepth = resolve_depth(coord); +} \ No newline at end of file diff --git a/src/dxvk/shaders/dxvk_resolve_frag_ds.frag b/src/dxvk/shaders/dxvk_resolve_frag_ds.frag new file mode 100644 index 00000000..734fe0fb --- /dev/null +++ b/src/dxvk/shaders/dxvk_resolve_frag_ds.frag @@ -0,0 +1,83 @@ +#version 450 + +#extension GL_ARB_shader_stencil_export : enable + +#define VK_RESOLVE_MODE_NONE_KHR (0) +#define VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR (1 << 0) +#define VK_RESOLVE_MODE_AVERAGE_BIT_KHR (1 << 1) +#define VK_RESOLVE_MODE_MIN_BIT_KHR (1 << 2) +#define VK_RESOLVE_MODE_MAX_BIT_KHR (1 << 3) + +layout(constant_id = 0) const int c_samples = 1; +layout(constant_id = 1) const int c_mode_d = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR; +layout(constant_id = 2) const int c_mode_s = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR; + +layout(binding = 0) uniform sampler2DMSArray s_depth; +layout(binding = 1) uniform usampler2DMSArray s_stencil; + +layout(push_constant) +uniform u_info_t { + ivec2 offset; +} u_info; + +float resolve_depth(ivec3 coord) { + float depth = 0.0f; + + switch (c_mode_d) { + case VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR: + depth = texelFetch(s_depth, coord, 0).r; + break; + + case VK_RESOLVE_MODE_AVERAGE_BIT_KHR: + depth = texelFetch(s_depth, coord, 0).r; + for (int i = 1; i < c_samples; i++) + depth += texelFetch(s_depth, coord, i).r; + depth /= float(c_samples); + break; + + case VK_RESOLVE_MODE_MIN_BIT_KHR: + depth = texelFetch(s_depth, coord, 0).r; + for (int i = 1; i < c_samples; i++) + depth = min(depth, texelFetch(s_depth, coord, i).r); + break; + + case VK_RESOLVE_MODE_MAX_BIT_KHR: + depth = texelFetch(s_depth, coord, 0).r; + for (int i = 1; i < c_samples; i++) + depth = max(depth, texelFetch(s_depth, coord, i).r); + break; + } + + return depth; +} + +int resolve_stencil(ivec3 coord) { + uint stencil = 0u; + + switch (c_mode_s) { + case VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR: + stencil = texelFetch(s_stencil, coord, 0).r; + break; + + case VK_RESOLVE_MODE_MIN_BIT_KHR: + stencil = texelFetch(s_stencil, coord, 0).r; + for (int i = 1; i < c_samples; i++) + stencil = min(stencil, texelFetch(s_stencil, coord, i).r); + break; + + case VK_RESOLVE_MODE_MAX_BIT_KHR: + stencil = texelFetch(s_stencil, coord, 0).r; + for (int i = 1; i < c_samples; i++) + stencil = max(stencil, texelFetch(s_stencil, coord, i).r); + break; + } + + return int(stencil); +} + +void main() { + ivec3 coord = ivec3(gl_FragCoord.xy + u_info.offset, gl_Layer); + + gl_FragDepth = resolve_depth(coord); + gl_FragStencilRefARB = resolve_stencil(coord); +} \ No newline at end of file