mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
wip
This commit is contained in:
parent
f1b515caaf
commit
2bea495981
4 changed files with 61 additions and 6 deletions
|
@ -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.
|
||||
};
|
||||
|
||||
|
|
|
@ -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]);
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
@ -119,9 +119,12 @@ private:
|
|||
|
||||
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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -156,6 +160,9 @@ 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");
|
||||
|
@ -163,7 +170,7 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
|
|||
|
||||
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) {
|
||||
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue