Complete implementation of post shaders for D3D11. All work except 5x scale one which looks wrong.
This commit is contained in:
parent
731026c199
commit
ccef648d3d
2 changed files with 110 additions and 6 deletions
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
// DbgNew is not compatible with Glslang
|
// DbgNew is not compatible with Glslang
|
||||||
#ifdef DBG_NEW
|
#ifdef DBG_NEW
|
||||||
|
@ -26,6 +27,8 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
|
#include "base/basictypes.h"
|
||||||
|
#include "base/stringutil.h"
|
||||||
#include "ShaderTranslation.h"
|
#include "ShaderTranslation.h"
|
||||||
#include "ext/glslang/SPIRV/GlslangToSpv.h"
|
#include "ext/glslang/SPIRV/GlslangToSpv.h"
|
||||||
#include "thin3d/thin3d.h"
|
#include "thin3d/thin3d.h"
|
||||||
|
@ -58,13 +61,105 @@ void ShaderTranslationShutdown() {
|
||||||
glslang::FinalizeProcess();
|
glslang::FinalizeProcess();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Preprocess(std::string code, ShaderLanguage lang) {
|
std::string Preprocess(std::string code, ShaderLanguage lang, Draw::ShaderStage stage) {
|
||||||
// This takes GL up to the version we need.
|
// This takes GL up to the version we need.
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Postprocess(std::string code, ShaderLanguage lang) {
|
struct Builtin {
|
||||||
|
const char *needle;
|
||||||
|
const char *replacement;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Workaround for deficiency in SPIRV-Cross
|
||||||
|
static const Builtin builtins[] = {
|
||||||
|
{"lessThan",
|
||||||
|
R"(
|
||||||
|
bool2 lessThan(float2 a, float2 b) { return bool2(a.x < b.x, a.y < b.y); }
|
||||||
|
bool3 lessThan(float3 a, float3 b) { return bool3(a.x < b.x, a.y < b.y, a.z < b.z); }
|
||||||
|
bool4 lessThan(float4 a, float4 b) { return bool4(a.x < b.x, a.y < b.y, a.z < b.z, a.w < b.w); }
|
||||||
|
)"},
|
||||||
|
{ "lessThanEqual",
|
||||||
|
R"(
|
||||||
|
bool2 lessThanEqual(float2 a, float2 b) { return bool2(a.x <= b.x, a.y <= b.y); }
|
||||||
|
bool3 lessThanEqual(float3 a, float3 b) { return bool3(a.x <= b.x, a.y <= b.y, a.z <= b.z); }
|
||||||
|
bool4 lessThanEqual(float4 a, float4 b) { return bool4(a.x <= b.x, a.y <= b.y, a.z <= b.z, a.w <= b.w); }
|
||||||
|
)" },
|
||||||
|
{ "greaterThan",
|
||||||
|
R"(
|
||||||
|
bool2 greaterThan(float2 a, float2 b) { return bool2(a.x > b.x, a.y > b.y); }
|
||||||
|
bool3 greaterThan(float3 a, float3 b) { return bool3(a.x > b.x, a.y > b.y, a.z > b.z); }
|
||||||
|
bool4 greaterThan(float4 a, float4 b) { return bool4(a.x > b.x, a.y > b.y, a.z > b.z, a.w > b.w); }
|
||||||
|
)" },
|
||||||
|
{ "greaterThanEqual",
|
||||||
|
R"(
|
||||||
|
bool2 greaterThanEqual(float2 a, float2 b) { return bool2(a.x >= b.x, a.y >= b.y); }
|
||||||
|
bool3 greaterThanEqual(float3 a, float3 b) { return bool3(a.x >= b.x, a.y >= b.y, a.z >= b.z); }
|
||||||
|
bool4 greaterThanEqual(float4 a, float4 b) { return bool4(a.x >= b.x, a.y >= b.y, a.z >= b.z, a.w >= b.w); }
|
||||||
|
)" },
|
||||||
|
{ "equal",
|
||||||
|
R"(
|
||||||
|
bool2 equal(float2 a, float2 b) { return bool2(a.x == b.x, a.y == b.y); }
|
||||||
|
bool3 equal(float3 a, float3 b) { return bool3(a.x == b.x, a.y == b.y, a.z == b.z); }
|
||||||
|
bool4 equal(float4 a, float4 b) { return bool4(a.x == b.x, a.y == b.y, a.z == b.z, a.w == b.w); }
|
||||||
|
)" },
|
||||||
|
{ "notEqual",
|
||||||
|
R"(
|
||||||
|
bool2 notEqual(float2 a, float2 b) { return bool2(a.x != b.x, a.y != b.y); }
|
||||||
|
bool3 notEqual(float3 a, float3 b) { return bool3(a.x != b.x, a.y != b.y, a.z != b.z); }
|
||||||
|
bool4 notEqual(float4 a, float4 b) { return bool4(a.x != b.x, a.y != b.y, a.z != b.z, a.w != b.w); }
|
||||||
|
)" },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const Builtin replacements[] = {
|
||||||
|
{ "mix(", "lerp(" },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *cbufferDecl = R"(
|
||||||
|
cbuffer data : register(b0) {
|
||||||
|
float2 u_texelDelta;
|
||||||
|
float2 u_pixelDelta;
|
||||||
|
float4 u_time;
|
||||||
|
};
|
||||||
|
)";
|
||||||
|
|
||||||
|
// SPIRV-Cross' HLSL output has some deficiencies we need to work around.
|
||||||
|
// Also we need to rip out single uniforms and replace them with blocks.
|
||||||
|
// Should probably do it in the source shader instead and then back translate to old style GLSL, but
|
||||||
|
// SPIRV-Cross currently won't compile with the Android NDK so I can't be bothered.
|
||||||
|
std::string Postprocess(std::string code, ShaderLanguage lang, Draw::ShaderStage stage) {
|
||||||
|
if (lang != HLSL_D3D11)
|
||||||
return code;
|
return code;
|
||||||
|
|
||||||
|
std::stringstream out;
|
||||||
|
|
||||||
|
// Output the uniform buffer.
|
||||||
|
out << cbufferDecl;
|
||||||
|
|
||||||
|
// Add the builtins if required.
|
||||||
|
for (int i = 0; i < ARRAY_SIZE(builtins); i++) {
|
||||||
|
if (!builtins[i].needle)
|
||||||
|
continue;
|
||||||
|
if (code.find(builtins[i].needle) != std::string::npos) {
|
||||||
|
out << builtins[i].replacement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform some replacements
|
||||||
|
for (int i = 0; i < ARRAY_SIZE(replacements); i++) {
|
||||||
|
code = ReplaceAll(code, replacements[i].needle, replacements[i].replacement);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alright, now let's go through it line by line and zap the single uniforms.
|
||||||
|
std::string line;
|
||||||
|
std::stringstream instream(code);
|
||||||
|
while (std::getline(instream, line)) {
|
||||||
|
if (line.find("uniform float") != std::string::npos)
|
||||||
|
continue;
|
||||||
|
out << line << "\n";
|
||||||
|
}
|
||||||
|
std::string output = out.str();
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslateShader(std::string *dest, ShaderLanguage destLang, TranslatedShaderMetadata *destMetadata, std::string src, ShaderLanguage srcLang, Draw::ShaderStage stage, std::string *errorMessage) {
|
bool TranslateShader(std::string *dest, ShaderLanguage destLang, TranslatedShaderMetadata *destMetadata, std::string src, ShaderLanguage srcLang, Draw::ShaderStage stage, std::string *errorMessage) {
|
||||||
|
@ -83,7 +178,7 @@ bool TranslateShader(std::string *dest, ShaderLanguage destLang, TranslatedShade
|
||||||
EShLanguage shaderStage = GetLanguage(stage);
|
EShLanguage shaderStage = GetLanguage(stage);
|
||||||
glslang::TShader shader(shaderStage);
|
glslang::TShader shader(shaderStage);
|
||||||
|
|
||||||
std::string preprocessed = Preprocess(src, srcLang);
|
std::string preprocessed = Preprocess(src, srcLang, stage);
|
||||||
|
|
||||||
shaderStrings[0] = src.c_str();
|
shaderStrings[0] = src.c_str();
|
||||||
shader.setStrings(shaderStrings, 1);
|
shader.setStrings(shaderStrings, 1);
|
||||||
|
@ -146,7 +241,7 @@ bool TranslateShader(std::string *dest, ShaderLanguage destLang, TranslatedShade
|
||||||
options.shader_model = 50;
|
options.shader_model = 50;
|
||||||
hlsl.set_options(options);
|
hlsl.set_options(options);
|
||||||
std::string raw = hlsl.compile();
|
std::string raw = hlsl.compile();
|
||||||
*dest = Postprocess(raw, destLang);
|
*dest = Postprocess(raw, destLang, stage);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -125,6 +125,7 @@ FramebufferManagerD3D11::FramebufferManagerD3D11(Draw::DrawContext *draw)
|
||||||
device_->CreateBuffer(&vb, nullptr, &quadBuffer_);
|
device_->CreateBuffer(&vb, nullptr, &quadBuffer_);
|
||||||
vb.ByteWidth = ROUND_UP(sizeof(PostShaderUniforms), 16);
|
vb.ByteWidth = ROUND_UP(sizeof(PostShaderUniforms), 16);
|
||||||
vb.Usage = D3D11_USAGE_DYNAMIC;
|
vb.Usage = D3D11_USAGE_DYNAMIC;
|
||||||
|
vb.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||||
device_->CreateBuffer(&vb, nullptr, &postConstants_);
|
device_->CreateBuffer(&vb, nullptr, &postConstants_);
|
||||||
|
|
||||||
ShaderTranslationInit();
|
ShaderTranslationInit();
|
||||||
|
@ -156,6 +157,7 @@ FramebufferManagerD3D11::~FramebufferManagerD3D11() {
|
||||||
quadInputLayout_->Release();
|
quadInputLayout_->Release();
|
||||||
quadBuffer_->Release();
|
quadBuffer_->Release();
|
||||||
fsQuadBuffer_->Release();
|
fsQuadBuffer_->Release();
|
||||||
|
postConstants_->Release();
|
||||||
|
|
||||||
if (drawPixelsTex_)
|
if (drawPixelsTex_)
|
||||||
drawPixelsTex_->Release();
|
drawPixelsTex_->Release();
|
||||||
|
@ -454,6 +456,13 @@ void FramebufferManagerD3D11::BindPostShader(const PostShaderUniforms &uniforms)
|
||||||
context_->IASetInputLayout(postInputLayout_);
|
context_->IASetInputLayout(postInputLayout_);
|
||||||
context_->PSSetShader(postPixelShader_, 0, 0);
|
context_->PSSetShader(postPixelShader_, 0, 0);
|
||||||
context_->VSSetShader(postVertexShader_, 0, 0);
|
context_->VSSetShader(postVertexShader_, 0, 0);
|
||||||
|
|
||||||
|
D3D11_MAPPED_SUBRESOURCE map;
|
||||||
|
context_->Map(postConstants_, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
||||||
|
memcpy(map.pData, &uniforms, sizeof(uniforms));
|
||||||
|
context_->Unmap(postConstants_, 0);
|
||||||
|
context_->VSSetConstantBuffers(0, 1, &postConstants_); // Probably not necessary
|
||||||
|
context_->PSSetConstantBuffers(0, 1, &postConstants_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramebufferManagerD3D11::RebindFramebuffer() {
|
void FramebufferManagerD3D11::RebindFramebuffer() {
|
||||||
|
@ -877,7 +886,7 @@ void FramebufferManagerD3D11::EndFrame() {
|
||||||
zoom = (PSP_CoreParameter().pixelHeight + 479) / 480;
|
zoom = (PSP_CoreParameter().pixelHeight + 479) / 480;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (zoom <= 1)
|
if (zoom <= 1 || postShaderIsUpscalingFilter_)
|
||||||
zoom = 1;
|
zoom = 1;
|
||||||
|
|
||||||
if (g_Config.IsPortrait()) {
|
if (g_Config.IsPortrait()) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue