Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
hrydgard committed Oct 27, 2022
1 parent f1b515c commit 2bea495
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 6 deletions.
1 change: 1 addition & 0 deletions Common/GPU/Shader.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ struct UniformDef {
struct SamplerDef {
int binding; // Might only be used by some backends.
const char *name;
bool array;
// TODO: Might need unsigned samplers, 3d samplers, or other types in the future.
};

Expand Down
43 changes: 39 additions & 4 deletions Common/GPU/ShaderWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ void ShaderWriter::Preamble(Slice<const char *> extensions) {
switch (lang_.shaderLanguage) {
case GLSL_VULKAN:
C("#version 450\n");
if (flags_ & ShaderWriterFlags::FS_AUTO_STEREO) {
C("#extension GL_EXT_multiview : enable\n");
}
// IMPORTANT! Extensions must be the first thing after #version.
for (size_t i = 0; i < extensions.size(); i++) {
F("%s\n", extensions[i]);
Expand Down Expand Up @@ -462,6 +465,15 @@ void ShaderWriter::DeclareSamplers(Slice<SamplerDef> samplers) {
samplerDefs_ = samplers;
}

const SamplerDef *ShaderWriter::GetSamplerDef(const char *name) const {
for (int i = 0; i < (int)samplers_.size(); i++) {
if (!strcmp(samplers_[i].name, name)) {
return &samplers_[i];
}
}
return nullptr;
}

void ShaderWriter::DeclareTexture2D(const SamplerDef &def) {
switch (lang_.shaderLanguage) {
case HLSL_D3D11:
Expand All @@ -472,7 +484,11 @@ void ShaderWriter::DeclareTexture2D(const SamplerDef &def) {
break;
case GLSL_VULKAN:
// In the thin3d descriptor set layout, textures start at 1 in set 0. Hence the +1.
F("layout(set = 0, binding = %d) uniform sampler2D %s;\n", def.binding + texBindingBase_, def.name);
if ((flags_ & ShaderWriterFlags::FS_AUTO_STEREO) && def.array) {
F("layout(set = 0, binding = %d) uniform sampler2DArray %s;\n", def.binding + texBindingBase_, def.name);
} else {
F("layout(set = 0, binding = %d) uniform sampler2D %s;\n", def.binding + texBindingBase_, def.name);
}
break;
default:
F("uniform sampler2D %s;\n", def.name);
Expand All @@ -492,6 +508,7 @@ void ShaderWriter::DeclareSampler2D(const SamplerDef &def) {
}

ShaderWriter &ShaderWriter::SampleTexture2D(const char *sampName, const char *uv) {
const SamplerDef *samp = GetSamplerDef(sampName);
switch (lang_.shaderLanguage) {
case HLSL_D3D11:
F("%s.Sample(%sSamp, %s)", sampName, sampName, uv);
Expand All @@ -501,13 +518,20 @@ ShaderWriter &ShaderWriter::SampleTexture2D(const char *sampName, const char *uv
break;
default:
// Note: we ignore the sampler. make sure you bound samplers to the textures correctly.
F("%s(%s, %s)", lang_.texture, sampName, uv);
if (samp && samp->array) {
const char *index = (flags_ & ShaderWriterFlags::FS_AUTO_STEREO) ? "float(gl_ViewIndex)" : "0.0";
F("%s(%s, vec3(%s, %s))", lang_.texture, sampName, uv, index);
} else {
F("%s(%s, %s)", lang_.texture, sampName, uv);
}
break;
}
return *this;
}

ShaderWriter &ShaderWriter::SampleTexture2DOffset(const char *sampName, const char *uv, int offX, int offY) {
const SamplerDef *samp = GetSamplerDef(sampName);

switch (lang_.shaderLanguage) {
case HLSL_D3D11:
F("%s.Sample(%sSamp, %s, int2(%d, %d))", sampName, sampName, uv, offX, offY);
Expand All @@ -518,13 +542,20 @@ ShaderWriter &ShaderWriter::SampleTexture2DOffset(const char *sampName, const ch
break;
default:
// Note: we ignore the sampler. make sure you bound samplers to the textures correctly.
F("%sOffset(%s, %s, ivec2(%d, %d))", lang_.texture, sampName, uv, offX, offY);
if (samp->array) {
const char *index = (flags_ & ShaderWriterFlags::FS_AUTO_STEREO) ? "float(gl_ViewIndex)" : "0.0";
F("%sOffset(%s, vec3(%s, %s), ivec3(%d, %d))", lang_.texture, sampName, uv, index, offX, offY);
} else {
F("%sOffset(%s, %s, ivec2(%d, %d))", lang_.texture, sampName, uv, offX, offY);
}
break;
}
return *this;
}

ShaderWriter &ShaderWriter::LoadTexture2D(const char *sampName, const char *uv, int level) {
const SamplerDef *samp = GetSamplerDef(sampName);

switch (lang_.shaderLanguage) {
case HLSL_D3D11:
F("%s.Load(ivec3(%s, %d))", sampName, uv, level);
Expand All @@ -535,7 +566,11 @@ ShaderWriter &ShaderWriter::LoadTexture2D(const char *sampName, const char *uv,
break;
default:
// Note: we ignore the sampler. make sure you bound samplers to the textures correctly.
F("texelFetch(%s, %s, %d)", sampName, uv, level);
if ((flags_ & ShaderWriterFlags::FS_AUTO_STEREO) && samp->array) {
F("texelFetch(%s, %s, %d)", sampName, uv, level);
} else {
F("texelFetch(%s, %s, %d)", sampName, uv, level);
}
break;
}
return *this;
Expand Down
5 changes: 4 additions & 1 deletion Common/GPU/ShaderWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ struct VaryingDef {
enum class ShaderWriterFlags {
NONE = 0,
FS_WRITE_DEPTH = 1,
FS_AUTO_STEREO = 2,
FS_AUTO_STEREO = 2, // Automatically makes sampler 0 an array sampler, and samples it by gl_ViewIndex. Useful for stereo rendering.
};
ENUM_CLASS_BITOPS(ShaderWriterFlags);

Expand Down Expand Up @@ -119,9 +119,12 @@ class ShaderWriter {

void Preamble(Slice<const char *> extensions);

const SamplerDef *GetSamplerDef(const char *name) const;

char *p_;
const ShaderLanguageDesc &lang_;
const ShaderStage stage_;
Slice<SamplerDef> samplers_;
ShaderWriterFlags flags_ = ShaderWriterFlags::NONE;
Slice<SamplerDef> samplerDefs_;
int texBindingBase_ = 1;
Expand Down
18 changes: 17 additions & 1 deletion GPU/Common/FragmentShaderGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
bool doTextureAlpha = id.Bit(FS_BIT_TEXALPHA);

bool arrayTexture = id.Bit(FS_BIT_SAMPLE_ARRAY_TEXTURE);
if (texture3D && arrayTexture) {
*errorString = "Invalid combination of 3D texture and array texture, shouldn't happen";
return false;
}

bool flatBug = bugs.Has(Draw::Bugs::BROKEN_FLAT_IN_SHADER) && g_Config.bVendorBugChecksEnabled;

Expand Down Expand Up @@ -156,14 +160,17 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
return false;
}

// Currently only used by Vulkan.
std::vector<SamplerDef> samplers;

if (compat.shaderLanguage == ShaderLanguage::GLSL_VULKAN) {
if (useDiscardStencilBugWorkaround && !gstate_c.Use(GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT)) {
WRITE(p, "layout (depth_unchanged) out float gl_FragDepth;\n");
}

WRITE(p, "layout (std140, set = 0, binding = 3) uniform baseUBO {\n%s};\n", ub_baseStr);
if (doTexture) {
WRITE(p, "layout (binding = 0) uniform %s%s tex;\n", texture3D ? "sampler3D" : "sampler2D", arrayTexture ? "array" : "");
WRITE(p, "layout (binding = 0) uniform %s%s tex;\n", texture3D ? "sampler3D" : "sampler2D", arrayTexture ? "Array" : "");
}

if (readFramebufferTex) {
Expand Down Expand Up @@ -639,6 +646,15 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
} else {
WRITE(p, " vec4 t = %s(tex, vec3(%s.xy, u_mipBias));\n", compat.texture3D, texcoord);
}
} else if (arrayTexture) {
// Used for stereo rendering.
if (doTextureProjection) {
if (doTextureProjection) {
WRITE(p, " vec4 t = %sProj(tex, %s);\n", compat.texture, texcoord);
} else {
WRITE(p, " vec4 t = %s(tex, %s.xy);\n", compat.texture, texcoord);
}
}
} else {
if (doTextureProjection) {
WRITE(p, " vec4 t = %sProj(tex, %s);\n", compat.texture, texcoord);
Expand Down

0 comments on commit 2bea495

Please sign in to comment.