mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-15 07:29:17 +01:00
[dxvk] Refactor resolve shaders
Removes some code duplication while adding support for non-AVERAGE resolves for plain color images. Also nuke the AMD path since it is no longer used.
This commit is contained in:
parent
6596ae1dc1
commit
54b0b09cc9
@ -8,7 +8,6 @@
|
|||||||
#include <dxvk_resolve_frag_d.h>
|
#include <dxvk_resolve_frag_d.h>
|
||||||
#include <dxvk_resolve_frag_ds.h>
|
#include <dxvk_resolve_frag_ds.h>
|
||||||
#include <dxvk_resolve_frag_f.h>
|
#include <dxvk_resolve_frag_f.h>
|
||||||
#include <dxvk_resolve_frag_f_amd.h>
|
|
||||||
#include <dxvk_resolve_frag_u.h>
|
#include <dxvk_resolve_frag_u.h>
|
||||||
#include <dxvk_resolve_frag_i.h>
|
#include <dxvk_resolve_frag_i.h>
|
||||||
|
|
||||||
@ -52,9 +51,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxvkMetaResolveObjects::DxvkMetaResolveObjects(const DxvkDevice* device)
|
DxvkMetaResolveObjects::DxvkMetaResolveObjects(const DxvkDevice* device)
|
||||||
: m_vkd (device->vkd()),
|
: m_vkd (device->vkd()),
|
||||||
m_shaderFragF (device->features().amdShaderFragmentMask
|
m_shaderFragF (createShaderModule(dxvk_resolve_frag_f)),
|
||||||
? createShaderModule(dxvk_resolve_frag_f_amd)
|
|
||||||
: createShaderModule(dxvk_resolve_frag_f)),
|
|
||||||
m_shaderFragU (createShaderModule(dxvk_resolve_frag_u)),
|
m_shaderFragU (createShaderModule(dxvk_resolve_frag_u)),
|
||||||
m_shaderFragI (createShaderModule(dxvk_resolve_frag_i)),
|
m_shaderFragI (createShaderModule(dxvk_resolve_frag_i)),
|
||||||
m_shaderFragD (createShaderModule(dxvk_resolve_frag_d)) {
|
m_shaderFragD (createShaderModule(dxvk_resolve_frag_d)) {
|
||||||
|
@ -50,7 +50,6 @@ dxvk_shaders = files([
|
|||||||
'shaders/dxvk_resolve_frag_d.frag',
|
'shaders/dxvk_resolve_frag_d.frag',
|
||||||
'shaders/dxvk_resolve_frag_ds.frag',
|
'shaders/dxvk_resolve_frag_ds.frag',
|
||||||
'shaders/dxvk_resolve_frag_f.frag',
|
'shaders/dxvk_resolve_frag_f.frag',
|
||||||
'shaders/dxvk_resolve_frag_f_amd.frag',
|
|
||||||
'shaders/dxvk_resolve_frag_i.frag',
|
'shaders/dxvk_resolve_frag_i.frag',
|
||||||
'shaders/dxvk_resolve_frag_u.frag',
|
'shaders/dxvk_resolve_frag_u.frag',
|
||||||
|
|
||||||
|
35
src/dxvk/shaders/dxvk_resolve_common.glsl
Normal file
35
src/dxvk/shaders/dxvk_resolve_common.glsl
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#define VK_RESOLVE_MODE_NONE (0)
|
||||||
|
#define VK_RESOLVE_MODE_SAMPLE_ZERO_BIT (1 << 0)
|
||||||
|
#define VK_RESOLVE_MODE_AVERAGE_BIT (1 << 1)
|
||||||
|
#define VK_RESOLVE_MODE_MIN_BIT (1 << 2)
|
||||||
|
#define VK_RESOLVE_MODE_MAX_BIT (1 << 3)
|
||||||
|
|
||||||
|
#define resolve_fn(name, type, load_fn) \
|
||||||
|
type name(ivec3 coord, int samples, uint mode) { \
|
||||||
|
if (mode == VK_RESOLVE_MODE_NONE) \
|
||||||
|
return type(0); \
|
||||||
|
type value = load_fn(coord, 0); \
|
||||||
|
\
|
||||||
|
switch (mode) { \
|
||||||
|
case VK_RESOLVE_MODE_SAMPLE_ZERO_BIT: \
|
||||||
|
return value; \
|
||||||
|
\
|
||||||
|
case VK_RESOLVE_MODE_AVERAGE_BIT: \
|
||||||
|
for (int i = 1; i < samples; i++) \
|
||||||
|
value += load_fn(coord, i); \
|
||||||
|
value /= type(c_samples); \
|
||||||
|
break; \
|
||||||
|
\
|
||||||
|
case VK_RESOLVE_MODE_MIN_BIT: \
|
||||||
|
for (int i = 1; i < samples; i++) \
|
||||||
|
value = min(value, load_fn(coord, i)); \
|
||||||
|
break; \
|
||||||
|
\
|
||||||
|
case VK_RESOLVE_MODE_MAX_BIT: \
|
||||||
|
for (int i = 1; i < c_samples; i++) \
|
||||||
|
value = min(value, load_fn(coord, i)); \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
return value; \
|
||||||
|
}
|
@ -1,56 +1,28 @@
|
|||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
#extension GL_EXT_samplerless_texture_functions : enable
|
#extension GL_EXT_samplerless_texture_functions : enable
|
||||||
|
|
||||||
#define VK_RESOLVE_MODE_NONE (0)
|
#include "dxvk_resolve_common.glsl"
|
||||||
#define VK_RESOLVE_MODE_SAMPLE_ZERO_BIT (1 << 0)
|
|
||||||
#define VK_RESOLVE_MODE_AVERAGE_BIT (1 << 1)
|
|
||||||
#define VK_RESOLVE_MODE_MIN_BIT (1 << 2)
|
|
||||||
#define VK_RESOLVE_MODE_MAX_BIT (1 << 3)
|
|
||||||
|
|
||||||
layout(constant_id = 0) const int c_samples = 1;
|
layout(constant_id = 0) const int c_samples = 1;
|
||||||
layout(constant_id = 1) const int c_mode_d = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT;
|
layout(constant_id = 1) const int c_mode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT;
|
||||||
|
|
||||||
layout(binding = 0) uniform texture2DMSArray s_depth;
|
layout(binding = 0) uniform texture2DMSArray s_depth;
|
||||||
|
|
||||||
|
float load_depth(ivec3 coord, int s) {
|
||||||
|
return texelFetch(s_depth, coord, s).r;
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve_fn(resolve_depth, float, load_depth)
|
||||||
|
|
||||||
layout(push_constant)
|
layout(push_constant)
|
||||||
uniform u_info_t {
|
uniform u_info_t {
|
||||||
ivec2 offset;
|
ivec2 offset;
|
||||||
} u_info;
|
} u_info;
|
||||||
|
|
||||||
float resolve_depth(ivec3 coord) {
|
|
||||||
float depth = 0.0f;
|
|
||||||
|
|
||||||
switch (c_mode_d) {
|
|
||||||
case VK_RESOLVE_MODE_SAMPLE_ZERO_BIT:
|
|
||||||
depth = texelFetch(s_depth, coord, 0).r;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VK_RESOLVE_MODE_AVERAGE_BIT:
|
|
||||||
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:
|
|
||||||
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:
|
|
||||||
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() {
|
void main() {
|
||||||
ivec3 coord = ivec3(gl_FragCoord.xy + u_info.offset, gl_Layer);
|
ivec3 coord = ivec3(gl_FragCoord.xy + u_info.offset, gl_Layer);
|
||||||
|
|
||||||
gl_FragDepth = resolve_depth(coord);
|
gl_FragDepth = resolve_depth(coord, c_samples, c_mode);
|
||||||
}
|
}
|
@ -1,13 +1,10 @@
|
|||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
#extension GL_ARB_shader_stencil_export : enable
|
#extension GL_ARB_shader_stencil_export : enable
|
||||||
#extension GL_EXT_samplerless_texture_functions : enable
|
#extension GL_EXT_samplerless_texture_functions : enable
|
||||||
|
|
||||||
#define VK_RESOLVE_MODE_NONE (0)
|
#include "dxvk_resolve_common.glsl"
|
||||||
#define VK_RESOLVE_MODE_SAMPLE_ZERO_BIT (1 << 0)
|
|
||||||
#define VK_RESOLVE_MODE_AVERAGE_BIT (1 << 1)
|
|
||||||
#define VK_RESOLVE_MODE_MIN_BIT (1 << 2)
|
|
||||||
#define VK_RESOLVE_MODE_MAX_BIT (1 << 3)
|
|
||||||
|
|
||||||
layout(constant_id = 0) const int c_samples = 1;
|
layout(constant_id = 0) const int c_samples = 1;
|
||||||
layout(constant_id = 1) const int c_mode_d = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT;
|
layout(constant_id = 1) const int c_mode_d = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT;
|
||||||
@ -16,69 +13,25 @@ layout(constant_id = 2) const int c_mode_s = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT;
|
|||||||
layout(binding = 0) uniform texture2DMSArray s_depth;
|
layout(binding = 0) uniform texture2DMSArray s_depth;
|
||||||
layout(binding = 1) uniform utexture2DMSArray s_stencil;
|
layout(binding = 1) uniform utexture2DMSArray s_stencil;
|
||||||
|
|
||||||
|
float load_depth(ivec3 coord, int s) {
|
||||||
|
return texelFetch(s_depth, coord, s).r;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint load_stencil(ivec3 coord, int s) {
|
||||||
|
return texelFetch(s_stencil, coord, s).r;
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve_fn(resolve_depth, float, load_depth)
|
||||||
|
resolve_fn(resolve_stencil, uint, load_stencil)
|
||||||
|
|
||||||
layout(push_constant)
|
layout(push_constant)
|
||||||
uniform u_info_t {
|
uniform u_info_t {
|
||||||
ivec2 offset;
|
ivec2 offset;
|
||||||
} u_info;
|
} u_info;
|
||||||
|
|
||||||
float resolve_depth(ivec3 coord) {
|
|
||||||
float depth = 0.0f;
|
|
||||||
|
|
||||||
switch (c_mode_d) {
|
|
||||||
case VK_RESOLVE_MODE_SAMPLE_ZERO_BIT:
|
|
||||||
depth = texelFetch(s_depth, coord, 0).r;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VK_RESOLVE_MODE_AVERAGE_BIT:
|
|
||||||
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:
|
|
||||||
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:
|
|
||||||
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:
|
|
||||||
stencil = texelFetch(s_stencil, coord, 0).r;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VK_RESOLVE_MODE_MIN_BIT:
|
|
||||||
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:
|
|
||||||
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() {
|
void main() {
|
||||||
ivec3 coord = ivec3(gl_FragCoord.xy + u_info.offset, gl_Layer);
|
ivec3 coord = ivec3(gl_FragCoord.xy + u_info.offset, gl_Layer);
|
||||||
|
|
||||||
gl_FragDepth = resolve_depth(coord);
|
gl_FragDepth = resolve_depth(coord, c_samples, c_mode_d);
|
||||||
gl_FragStencilRefARB = resolve_stencil(coord);
|
gl_FragStencilRefARB = int(resolve_stencil(coord, c_samples, c_mode_s));
|
||||||
}
|
}
|
@ -1,13 +1,23 @@
|
|||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
#extension GL_EXT_samplerless_texture_functions : enable
|
#extension GL_EXT_samplerless_texture_functions : enable
|
||||||
|
|
||||||
|
#include "dxvk_resolve_common.glsl"
|
||||||
|
|
||||||
layout(constant_id = 0) const int c_samples = 1;
|
layout(constant_id = 0) const int c_samples = 1;
|
||||||
|
layout(constant_id = 1) const int c_mode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT;
|
||||||
|
|
||||||
layout(binding = 0) uniform texture2DMSArray s_image;
|
layout(binding = 0) uniform texture2DMSArray s_image;
|
||||||
|
|
||||||
layout(location = 0) out vec4 o_color;
|
layout(location = 0) out vec4 o_color;
|
||||||
|
|
||||||
|
vec4 load_color(ivec3 coord, int s) {
|
||||||
|
return texelFetch(s_image, coord, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve_fn(resolve_color, vec4, load_color)
|
||||||
|
|
||||||
layout(push_constant)
|
layout(push_constant)
|
||||||
uniform u_info_t {
|
uniform u_info_t {
|
||||||
ivec2 offset;
|
ivec2 offset;
|
||||||
@ -15,8 +25,5 @@ uniform u_info_t {
|
|||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
ivec3 coord = ivec3(gl_FragCoord.xy + u_info.offset, gl_Layer);
|
ivec3 coord = ivec3(gl_FragCoord.xy + u_info.offset, gl_Layer);
|
||||||
vec4 color = vec4(0.0f);
|
o_color = resolve_color(coord, c_samples, c_mode);
|
||||||
for (int i = 0; i < c_samples; i++)
|
|
||||||
color += texelFetch(s_image, coord, i);
|
|
||||||
o_color = color / float(c_samples);
|
|
||||||
}
|
}
|
@ -1,56 +0,0 @@
|
|||||||
#version 450
|
|
||||||
|
|
||||||
#extension GL_EXT_samplerless_texture_functions : enable
|
|
||||||
#extension GL_EXT_spirv_intrinsics : enable
|
|
||||||
|
|
||||||
// GL_AMD_shader_fragment_mask was never updated to support
|
|
||||||
// sampler-less functions, so we have to define these manually
|
|
||||||
spirv_instruction(extensions = ["SPV_AMD_shader_fragment_mask"], capabilities = [5010], id = 5011)
|
|
||||||
uint fragment_mask_fetch(texture2DMSArray tex, ivec3 coord);
|
|
||||||
|
|
||||||
spirv_instruction(extensions = ["SPV_AMD_shader_fragment_mask"], capabilities = [5010], id = 5012)
|
|
||||||
vec4 fragment_fetch(texture2DMSArray tex, ivec3 coord, uint index);
|
|
||||||
|
|
||||||
layout(constant_id = 0) const int c_samples = 1;
|
|
||||||
|
|
||||||
layout(set = 0, binding = 0)
|
|
||||||
uniform texture2DMSArray s_image;
|
|
||||||
|
|
||||||
layout(location = 0) out vec4 o_color;
|
|
||||||
|
|
||||||
layout(push_constant)
|
|
||||||
uniform u_info_t {
|
|
||||||
ivec2 offset;
|
|
||||||
} u_info;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
ivec3 coord = ivec3(gl_FragCoord.xy + u_info.offset, gl_Layer);
|
|
||||||
|
|
||||||
// get a four-bit fragment index for each sample
|
|
||||||
uint fragMask = fragment_mask_fetch(s_image, coord);
|
|
||||||
|
|
||||||
// count number of occurences of each fragment
|
|
||||||
// index in one four-bit counter for each sample
|
|
||||||
uint fragCount = 0u;
|
|
||||||
|
|
||||||
for (int i = 0; i < 4 * c_samples; i += 4) {
|
|
||||||
uint fragIndex = bitfieldExtract(fragMask, i, 4);
|
|
||||||
fragCount += 1u << (fragIndex << 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// perform necessary texture lookups to compute
|
|
||||||
// final fragment color
|
|
||||||
o_color = vec4(0.0f);
|
|
||||||
|
|
||||||
while (fragCount != 0) {
|
|
||||||
int fragIndex = findLSB(fragCount) >> 2;
|
|
||||||
int fragShift = fragIndex << 2;
|
|
||||||
|
|
||||||
o_color += fragment_fetch(s_image, coord, fragIndex)
|
|
||||||
* float(bitfieldExtract(fragCount, fragShift, 4));
|
|
||||||
|
|
||||||
fragCount = bitfieldInsert(fragCount, 0, fragShift, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
o_color /= float(c_samples);
|
|
||||||
}
|
|
@ -1,11 +1,23 @@
|
|||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
#extension GL_EXT_samplerless_texture_functions : enable
|
#extension GL_EXT_samplerless_texture_functions : enable
|
||||||
|
|
||||||
|
#include "dxvk_resolve_common.glsl"
|
||||||
|
|
||||||
|
layout(constant_id = 0) const int c_samples = 1;
|
||||||
|
layout(constant_id = 1) const int c_mode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT;
|
||||||
|
|
||||||
layout(binding = 0) uniform itexture2DMSArray s_image;
|
layout(binding = 0) uniform itexture2DMSArray s_image;
|
||||||
|
|
||||||
layout(location = 0) out ivec4 o_color;
|
layout(location = 0) out ivec4 o_color;
|
||||||
|
|
||||||
|
ivec4 load_color(ivec3 coord, int s) {
|
||||||
|
return texelFetch(s_image, coord, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve_fn(resolve_color, ivec4, load_color)
|
||||||
|
|
||||||
layout(push_constant)
|
layout(push_constant)
|
||||||
uniform u_info_t {
|
uniform u_info_t {
|
||||||
ivec2 offset;
|
ivec2 offset;
|
||||||
@ -13,5 +25,5 @@ uniform u_info_t {
|
|||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
ivec3 coord = ivec3(gl_FragCoord.xy + u_info.offset, gl_Layer);
|
ivec3 coord = ivec3(gl_FragCoord.xy + u_info.offset, gl_Layer);
|
||||||
o_color = texelFetch(s_image, coord, 0);
|
o_color = resolve_color(coord, c_samples, c_mode);
|
||||||
}
|
}
|
@ -1,10 +1,22 @@
|
|||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
#extension GL_EXT_samplerless_texture_functions : enable
|
#extension GL_EXT_samplerless_texture_functions : enable
|
||||||
|
|
||||||
|
#include "dxvk_resolve_common.glsl"
|
||||||
|
|
||||||
|
layout(constant_id = 0) const int c_samples = 1;
|
||||||
|
layout(constant_id = 1) const int c_mode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT;
|
||||||
|
|
||||||
layout(binding = 0) uniform utexture2DMSArray s_image;
|
layout(binding = 0) uniform utexture2DMSArray s_image;
|
||||||
|
|
||||||
layout(location = 0) out uvec4 o_color;
|
layout(location = 0) out vec4 o_color;
|
||||||
|
|
||||||
|
uvec4 load_color(ivec3 coord, int s) {
|
||||||
|
return texelFetch(s_image, coord, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve_fn(resolve_color, uvec4, load_color)
|
||||||
|
|
||||||
layout(push_constant)
|
layout(push_constant)
|
||||||
uniform u_info_t {
|
uniform u_info_t {
|
||||||
@ -13,5 +25,5 @@ uniform u_info_t {
|
|||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
ivec3 coord = ivec3(gl_FragCoord.xy + u_info.offset, gl_Layer);
|
ivec3 coord = ivec3(gl_FragCoord.xy + u_info.offset, gl_Layer);
|
||||||
o_color = texelFetch(s_image, coord, 0);
|
o_color = resolve_color(coord, c_samples, c_mode);
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user