mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-22 10:21:21 +00:00
[vulkan] Rework shaders and pipelines for bindless textures
Smashing everything in the process :P (need to work on the C side). However, while bindless is supposedly good for performance, the biggest gain this will bring is portability: the texture counts are automatically limited to what the hardware can handle, and the reliance on push descriptors is removed (though they were nice and did help get things up and running).
This commit is contained in:
parent
3a742f59f7
commit
ff6d6f6dd6
6 changed files with 74 additions and 131 deletions
|
@ -4,6 +4,7 @@
|
|||
//needs to agree on the size, so it might as well set maxSamplers
|
||||
//directly (and any other such variable)
|
||||
maxSamplers = "min (256u, $physDevLimits.maxPerStageDescriptorSamplers)";
|
||||
maxImages = "min (256u, $physDevLimits.maxPerStageDescriptorSampledImages - 8u)";
|
||||
};
|
||||
samplers = {
|
||||
quakepic = {
|
||||
|
@ -159,7 +160,6 @@
|
|||
);
|
||||
};
|
||||
quakebsp_set = {
|
||||
flags = push_descriptor;
|
||||
bindings = (
|
||||
{
|
||||
binding = 0;
|
||||
|
@ -200,7 +200,6 @@
|
|||
);
|
||||
};
|
||||
alias_set = {
|
||||
flags = push_descriptor;
|
||||
bindings = (
|
||||
{
|
||||
binding = 0;
|
||||
|
@ -210,7 +209,13 @@
|
|||
},
|
||||
{
|
||||
binding = 1;
|
||||
descriptorType = combined_image_sampler;
|
||||
descriptorType = sampled_image;
|
||||
descriptorCount = $properties.limits.maxImages;
|
||||
stageFlags = fragment;
|
||||
},
|
||||
{
|
||||
binding = 2;
|
||||
descriptorType = sampler;
|
||||
descriptorCount = 1;
|
||||
stageFlags = fragment;
|
||||
},
|
||||
|
@ -227,7 +232,6 @@
|
|||
);
|
||||
};
|
||||
alias_textures = {
|
||||
flags = push_descriptor;
|
||||
bindings = (
|
||||
{
|
||||
binding = 0;
|
||||
|
@ -367,7 +371,7 @@
|
|||
{
|
||||
stageFlags = fragment;
|
||||
offset = 68;
|
||||
size = "3 * 4 + 2 * 4 * 4";
|
||||
size = "3 * 4 + 2 * 4 * 4 + 4";
|
||||
},
|
||||
);
|
||||
};
|
||||
|
@ -651,9 +655,10 @@
|
|||
module = $builtin/alias_gbuf.frag;
|
||||
specializationInfo = {
|
||||
mapEntries = (
|
||||
// MaxTextures
|
||||
{ size = 4; offset = 0; constantID = 0; },
|
||||
);
|
||||
data = <00000008>;
|
||||
data = "array(uint($properties.limits.maxImages))";
|
||||
};
|
||||
},
|
||||
);
|
||||
|
@ -726,12 +731,10 @@
|
|||
module = $builtin/bsp_gbuf.frag;
|
||||
specializationInfo = {
|
||||
mapEntries = (
|
||||
// MaxTextures
|
||||
{ size = 4; offset = 0; constantID = 0; },
|
||||
{ size = 4; offset = 0; constantID = 1; },
|
||||
{ size = 4; offset = 0; constantID = 2; },
|
||||
{ size = 4; offset = 0; constantID = 3; },
|
||||
);
|
||||
data = <00000000ffffffff>;
|
||||
data = "array(uint($properties.limits.maxImages))";
|
||||
};
|
||||
},
|
||||
);
|
||||
|
@ -770,10 +773,14 @@
|
|||
module = $builtin/bsp_sky.frag;
|
||||
specializationInfo = {
|
||||
mapEntries = (
|
||||
{ size = 4; offset = 0; constantID = 1; },
|
||||
{ size = 4; offset = 4; constantID = 0; },
|
||||
// MaxTextures
|
||||
{ size = 4; offset = 8; constantID = 0; },
|
||||
// doSkyBox
|
||||
{ size = 4; offset = 4; constantID = 1; },
|
||||
// doSkySheet
|
||||
{ size = 4; offset = 0; constantID = 2; },
|
||||
);
|
||||
data = <00000000ffffffff>;
|
||||
data = "array(0, 1, uint($properties.limits.maxImages))";
|
||||
};
|
||||
},
|
||||
);
|
||||
|
@ -807,10 +814,14 @@
|
|||
module = $builtin/bsp_sky.frag;
|
||||
specializationInfo = {
|
||||
mapEntries = (
|
||||
{ size = 4; offset = 0; constantID = 0; },
|
||||
{ size = 4; offset = 4; constantID = 1; },
|
||||
// MaxTextures
|
||||
{ size = 4; offset = 8; constantID = 0; },
|
||||
// doSkyBox
|
||||
{ size = 4; offset = 0; constantID = 1; },
|
||||
// doSkySheet
|
||||
{ size = 4; offset = 4; constantID = 2; },
|
||||
);
|
||||
data = <00000000ffffffff>;
|
||||
data = "array(0, 1, uint($properties.limits.maxImages))";
|
||||
};
|
||||
},
|
||||
);
|
||||
|
@ -844,10 +855,10 @@
|
|||
module = $builtin/bsp_turb.frag;
|
||||
specializationInfo = {
|
||||
mapEntries = (
|
||||
// MaxTextures
|
||||
{ size = 4; offset = 0; constantID = 0; },
|
||||
{ size = 4; offset = 4; constantID = 1; },
|
||||
);
|
||||
data = <00000000ffffffff>;
|
||||
data = "array(uint($properties.limits.maxImages))";
|
||||
};
|
||||
},
|
||||
);
|
||||
|
@ -913,7 +924,7 @@
|
|||
mapEntries = (
|
||||
{ size = 4; offset = 0; constantID = 0; },
|
||||
);
|
||||
data = "array($properties.limits.maxSamplers)";
|
||||
data = "array(uint($properties.limits.maxSamplers))";
|
||||
};
|
||||
},
|
||||
);
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
#version 450
|
||||
layout (set = 0, binding = 1) uniform sampler2DArray Skin;
|
||||
|
||||
layout (constant_id = 0) const int MaxTextures = 256;
|
||||
|
||||
layout (set = 0, binding = 1) uniform texture2DArray skins[MaxTextures];
|
||||
layout (set = 0, binding = 2) uniform sampler samp;
|
||||
|
||||
layout (push_constant) uniform PushConstants {
|
||||
layout (offset = 68)
|
||||
|
@ -8,6 +12,7 @@ layout (push_constant) uniform PushConstants {
|
|||
uint colorB;
|
||||
vec4 fog;
|
||||
vec4 color;
|
||||
int texind;
|
||||
};
|
||||
|
||||
layout (location = 0) in vec2 st;
|
||||
|
@ -26,10 +31,10 @@ main (void)
|
|||
vec4 e;
|
||||
int i;
|
||||
vec3 light = vec3 (0);
|
||||
c = texture (Skin, vec3 (st, 0)) * unpackUnorm4x8(base_color);
|
||||
c += texture (Skin, vec3 (st, 1)) * unpackUnorm4x8(colorA);
|
||||
c += texture (Skin, vec3 (st, 2)) * unpackUnorm4x8(colorB);
|
||||
e = texture (Skin, vec3 (st, 3));
|
||||
c = texture (sampler2DArray(skins[texind], samp), vec3 (st, 0)) * unpackUnorm4x8(base_color);
|
||||
c += texture (sampler2DArray(skins[texind], samp), vec3 (st, 1)) * unpackUnorm4x8(colorA);
|
||||
c += texture (sampler2DArray(skins[texind], samp), vec3 (st, 2)) * unpackUnorm4x8(colorB);
|
||||
e = texture (sampler2DArray(skins[texind], samp), vec3 (st, 3));
|
||||
|
||||
frag_color = c;
|
||||
frag_emission = e;
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
#version 450
|
||||
|
||||
layout (constant_id = 0) const int MaxTextures = 256;
|
||||
|
||||
layout (set = 0, binding = 1) uniform texture2DArray textures[MaxTextures];
|
||||
layout (set = 0, binding = 2) uniform sampler samp;
|
||||
|
||||
layout (set = 0, binding = 1) uniform sampler2D Texture;
|
||||
layout (set = 0, binding = 2) uniform sampler2D GlowMap;
|
||||
layout (set = 0, binding = 3) uniform sampler2D LightMap;
|
||||
layout (set = 0, binding = 4) uniform sampler2DArray SkySheet;
|
||||
layout (set = 0, binding = 5) uniform samplerCube SkyCube;
|
||||
|
||||
layout (push_constant) uniform PushConstants {
|
||||
layout (offset = 64)
|
||||
vec4 fog;
|
||||
float time;
|
||||
int texind;
|
||||
};
|
||||
|
||||
layout (location = 0) in vec4 tl_st;
|
||||
|
@ -22,26 +25,6 @@ layout (location = 1) out vec4 frag_emission;
|
|||
layout (location = 2) out vec4 frag_normal;
|
||||
layout (location = 3) out vec4 frag_position;
|
||||
|
||||
layout (constant_id = 0) const bool doWarp = false;
|
||||
layout (constant_id = 1) const bool doLight = true;
|
||||
layout (constant_id = 2) const bool doSkyCube = false;
|
||||
layout (constant_id = 3) const bool doSkySheet = false;
|
||||
|
||||
const float PI = 3.14159265;
|
||||
const float SPEED = 20.0;
|
||||
const float CYCLE = 128.0;
|
||||
const float FACTOR = PI * 2.0 / CYCLE;
|
||||
const vec2 BIAS = vec2 (1.0, 1.0);
|
||||
const float SCALE = 8.0;
|
||||
|
||||
vec2
|
||||
warp_st (vec2 st, float time)
|
||||
{
|
||||
vec2 angle = st.ts * CYCLE / 2.0;
|
||||
vec2 phase = vec2 (time, time) * SPEED;
|
||||
return st + (sin ((angle + phase) * FACTOR) + BIAS) / SCALE;
|
||||
}
|
||||
|
||||
vec4
|
||||
fogBlend (vec4 color)
|
||||
{
|
||||
|
@ -52,79 +35,16 @@ fogBlend (vec4 color)
|
|||
return vec4 (mix (fog_color.rgb, color.rgb, fog_factor), color.a);
|
||||
}
|
||||
|
||||
vec4
|
||||
sky_sheet (vec3 dir, float time)
|
||||
{
|
||||
float len;
|
||||
vec2 flow = vec2 (1.0, 1.0);
|
||||
vec2 base;
|
||||
vec3 st1, st2;
|
||||
vec4 c1, c2, c;
|
||||
|
||||
dir.z *= 3.0;
|
||||
len = dot (dir, dir);
|
||||
len = SCALE * inversesqrt (len);
|
||||
base = dir.yx * vec2(1.0, -1.0) * len;
|
||||
|
||||
st1 = vec3 (base + flow * time / 8.0, 0);
|
||||
st2 = vec3 (base + flow * time / 16.0, 1);
|
||||
|
||||
c1 = texture (SkySheet, st1);
|
||||
c2 = texture (SkySheet, st2);
|
||||
|
||||
c = vec4 (mix (c2.rgb, c1.rgb, c1.a), max (c1.a, c2.a));
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
vec4
|
||||
sky_cube (vec3 dir, float time)
|
||||
{
|
||||
// NOTE: quake's world is right-handed with Z up and X forward, but
|
||||
// Vulkan's cube maps are left-handed with Y up and Z forward. The
|
||||
// rotation to X foward is done by the Sky matrix so all that's left
|
||||
// to do here is swizzle the Y and Z coordinates
|
||||
return texture (SkyCube, dir.xzy);
|
||||
}
|
||||
|
||||
vec4
|
||||
sky_color (vec3 dir, float time)
|
||||
{
|
||||
if (!doSkySheet) {
|
||||
return vec4 (1, 0, 1, 1);
|
||||
//return sky_cube (dir, time);
|
||||
} if (!doSkyCube) {
|
||||
return sky_sheet (dir, time);
|
||||
} else {
|
||||
// can see through the sheet (may look funny when looking down)
|
||||
// maybe have 4 sheet layers instead of 2?
|
||||
vec4 c1 = sky_sheet (dir, time);
|
||||
vec4 c2 = sky_cube (dir, time);
|
||||
return vec4 (mix (c2.rgb, c1.rgb, c1.a), max (c1.a, c2.a));
|
||||
return vec4 (1, 0, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
main (void)
|
||||
{
|
||||
vec4 c = vec4 (0);
|
||||
vec4 e;
|
||||
vec2 t_st = tl_st.xy;
|
||||
vec2 l_st = tl_st.zw;
|
||||
vec3 t_st = vec3 (tl_st.xy, 0);
|
||||
vec3 l_st = vec3 (tl_st.zw, 1);
|
||||
|
||||
if (doWarp) {
|
||||
t_st = warp_st (t_st, time);
|
||||
}
|
||||
if (doSkyCube || doSkySheet) {
|
||||
e = sky_color (direction, time);
|
||||
} else {
|
||||
c = texture (Texture, t_st);
|
||||
if (doLight) {
|
||||
c *= vec4 (texture (LightMap, l_st).xyz, 1);
|
||||
}
|
||||
e = texture (GlowMap, t_st);
|
||||
}
|
||||
c = texture (sampler2DArray (textures[texind], samp), t_st);
|
||||
e = texture (sampler2DArray (textures[texind], samp), t_st);
|
||||
frag_color = c;//fogBlend (c);
|
||||
frag_emission = e;
|
||||
frag_normal = vec4 (normal, 0);
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
#version 450
|
||||
|
||||
layout (set = 0, binding = 4) uniform sampler2DArray SkySheet;
|
||||
layout (set = 0, binding = 5) uniform samplerCube SkyCube;
|
||||
layout (constant_id = 0) const int MaxTextures = 256;
|
||||
layout (constant_id = 1) const bool doSkyBox = false;
|
||||
layout (constant_id = 2) const bool doSkySheet = false;
|
||||
|
||||
layout (set = 0, binding = 1) uniform texture2DArray sheet_tex[MaxTextures];
|
||||
layout (set = 0, binding = 1) uniform textureCube cube_tex[MaxTextures];
|
||||
layout (set = 0, binding = 2) uniform sampler samp;
|
||||
|
||||
layout (push_constant) uniform PushConstants {
|
||||
layout (offset = 64)
|
||||
vec4 fog;
|
||||
float time;
|
||||
int sheet_ind;
|
||||
int cube_ind;
|
||||
};
|
||||
|
||||
layout (location = 0) in vec4 tl_st;
|
||||
|
@ -14,9 +21,6 @@ layout (location = 1) in vec3 direction;
|
|||
|
||||
layout (location = 0) out vec4 frag_color;
|
||||
|
||||
layout (constant_id = 0) const bool doSkyBox = false;
|
||||
layout (constant_id = 1) const bool doSkySheet = false;
|
||||
|
||||
const float SCALE = 189.0 / 64.0;
|
||||
|
||||
vec4
|
||||
|
@ -30,7 +34,7 @@ fogBlend (vec4 color)
|
|||
}
|
||||
|
||||
vec4
|
||||
sky_sheet (vec3 dir, float time)
|
||||
sky_sheet (vec3 dir, float time, texture2DArray tex)
|
||||
{
|
||||
float len;
|
||||
vec2 flow = vec2 (1.0, 1.0);
|
||||
|
@ -46,8 +50,8 @@ sky_sheet (vec3 dir, float time)
|
|||
st1 = vec3 (base + flow * time / 8.0, 0);
|
||||
st2 = vec3 (base + flow * time / 16.0, 1);
|
||||
|
||||
c1 = texture (SkySheet, st1);
|
||||
c2 = texture (SkySheet, st2);
|
||||
c1 = texture (sampler2DArray(tex, samp), st1);
|
||||
c2 = texture (sampler2DArray(tex, samp), st2);
|
||||
|
||||
c = vec4 (mix (c2.rgb, c1.rgb, c1.a), max (c1.a, c2.a));
|
||||
|
||||
|
@ -55,7 +59,7 @@ sky_sheet (vec3 dir, float time)
|
|||
}
|
||||
|
||||
vec4
|
||||
sky_box (vec3 dir, float time)
|
||||
sky_box (vec3 dir, float time, textureCube tex)
|
||||
{
|
||||
// NOTE: quake's world is right-handed with Z up and X forward, but
|
||||
// Vulkan's cube maps are left-handed with Y up and Z forward. The
|
||||
|
@ -63,21 +67,21 @@ sky_box (vec3 dir, float time)
|
|||
// to do here is swizzle the Y and Z coordinates
|
||||
dir = normalize(dir);
|
||||
//return vec4(dir.xyz, 1) * 0.5 + vec4(0.5);
|
||||
return texture (SkyCube, dir.xzy);
|
||||
return texture (samplerCube (tex, samp), dir.xzy);
|
||||
}
|
||||
|
||||
vec4
|
||||
sky_color (vec3 dir, float time)
|
||||
{
|
||||
if (!doSkySheet) {
|
||||
return sky_box (dir, time);
|
||||
return sky_box (dir, time, cube_tex[cube_ind]);
|
||||
} if (!doSkyBox) {
|
||||
return sky_sheet (dir, time);
|
||||
return sky_sheet (dir, time, sheet_tex[sheet_ind]);
|
||||
} else {
|
||||
// can see through the sheet (may look funny when looking down)
|
||||
// maybe have 4 sheet layers instead of 2?
|
||||
vec4 c1 = sky_sheet (dir, time);
|
||||
vec4 c2 = sky_box (dir, time);
|
||||
vec4 c1 = sky_sheet (dir, time, sheet_tex[sheet_ind]);
|
||||
vec4 c2 = sky_box (dir, time, cube_tex[cube_ind]);
|
||||
return vec4 (mix (c2.rgb, c1.rgb, c1.a), max (c1.a, c2.a));
|
||||
return vec4 (1, 0, 1, 1);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
#version 450
|
||||
|
||||
layout (set = 0, binding = 1) uniform sampler2D Texture;
|
||||
layout (constant_id = 0) const int MaxTextures = 256;
|
||||
|
||||
layout (set = 0, binding = 1) uniform texture2D textures[MaxTextures];
|
||||
layout (set = 0, binding = 2) uniform sampler samp;
|
||||
|
||||
layout (push_constant) uniform PushConstants {
|
||||
layout (offset = 64)
|
||||
vec4 fog;
|
||||
float time;
|
||||
int texind;
|
||||
};
|
||||
|
||||
layout (location = 0) in vec4 tl_st;
|
||||
|
@ -47,6 +51,6 @@ main (void)
|
|||
vec2 l_st = tl_st.zw;
|
||||
|
||||
t_st = warp_st (t_st, time);
|
||||
c = texture (Texture, t_st);
|
||||
c = texture (sampler2D (textures[texind], samp), t_st);
|
||||
frag_color = c;//fogBlend (c);
|
||||
}
|
||||
|
|
|
@ -190,7 +190,6 @@ static const char *instance_extensions[] = {
|
|||
|
||||
static const char *device_extensions[] = {
|
||||
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
|
||||
VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME,
|
||||
0,
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue