mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-07-11 01:25:07 +02:00
More reinterpret shader gen and test work.
More work on reinterpret Buildsystem fixes
This commit is contained in:
@@ -1354,6 +1354,8 @@ set(GPU_SOURCES
|
||||
GPU/Common/DrawEngineCommon.h
|
||||
GPU/Common/PresentationCommon.cpp
|
||||
GPU/Common/PresentationCommon.h
|
||||
GPU/Common/ReinterpretFramebuffer.cpp
|
||||
GPU/Common/ReinterpretFramebuffer.h
|
||||
GPU/Common/ShaderId.cpp
|
||||
GPU/Common/ShaderId.h
|
||||
GPU/Common/ShaderUniforms.cpp
|
||||
|
||||
@@ -386,6 +386,7 @@
|
||||
<ClInclude Include="Data\Collections\ConstMap.h" />
|
||||
<ClInclude Include="Data\Collections\FixedSizeQueue.h" />
|
||||
<ClInclude Include="Data\Collections\Hashmaps.h" />
|
||||
<ClInclude Include="Data\Collections\Slice.h" />
|
||||
<ClInclude Include="Data\Collections\ThreadSafeList.h" />
|
||||
<ClInclude Include="Data\Collections\TinySet.h" />
|
||||
<ClInclude Include="Data\Color\RGBAUtil.h" />
|
||||
|
||||
@@ -381,6 +381,9 @@
|
||||
<ClInclude Include="GPU\ShaderWriter.h">
|
||||
<Filter>GPU</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Data\Collections\Slice.h">
|
||||
<Filter>Data\Collections</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ABI.cpp" />
|
||||
@@ -850,4 +853,4 @@
|
||||
<Filter>Math\fast</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
// Like a const begin/end pair, just more convenient to use (and can only be used for linear array data).
|
||||
// Inspired by Rust's slices and Google's StringPiece.
|
||||
template <class T>
|
||||
struct Slice {
|
||||
// View some memory as a slice.
|
||||
Slice(const T *data, size_t size) : data_(data), size_(size) {}
|
||||
|
||||
// Intentionally non-explicit.
|
||||
// View a const array as a slice.
|
||||
template<size_t N>
|
||||
Slice(const T(&data)[N]) : data_(data), size_(N) {}
|
||||
|
||||
// Intentionally non-explicit.
|
||||
// View a const array as a slice.
|
||||
Slice(const std::vector<T> &data) : data_(data.data()), size_(data.size()) {}
|
||||
|
||||
const T &operator[](size_t index) const {
|
||||
return data_[index];
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return size_;
|
||||
}
|
||||
|
||||
// "Iterators"
|
||||
const T *begin() const {
|
||||
return data_;
|
||||
}
|
||||
const T *end() const {
|
||||
return data_ + size_;
|
||||
}
|
||||
|
||||
static Slice empty() {
|
||||
return Slice<T>(nullptr, 0);
|
||||
}
|
||||
|
||||
bool is_empty() const {
|
||||
return size_ == 0;
|
||||
}
|
||||
|
||||
private:
|
||||
const T *data_;
|
||||
size_t size_;
|
||||
};
|
||||
+128
-1
@@ -64,11 +64,12 @@ const char *hlsl_preamble_vs =
|
||||
"\n";
|
||||
|
||||
// Unsafe. But doesn't matter, we'll use big buffers for shader gen.
|
||||
void ShaderWriter::F(const char *format, ...) {
|
||||
ShaderWriter & ShaderWriter::F(const char *format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
p_ += vsprintf(p_, format, args);
|
||||
va_end(args);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void ShaderWriter::Preamble(const char **gl_extensions, size_t num_gl_extensions) {
|
||||
@@ -110,6 +111,9 @@ void ShaderWriter::Preamble(const char **gl_extensions, size_t num_gl_extensions
|
||||
C("#define DISCARD discard\n");
|
||||
if (lang_.gles) {
|
||||
C("precision lowp float;\n");
|
||||
if (lang_.glslES30) {
|
||||
C("precision highp int;\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ShaderStage::Vertex:
|
||||
@@ -128,3 +132,126 @@ void ShaderWriter::Preamble(const char **gl_extensions, size_t num_gl_extensions
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderWriter::BeginVSMain(Slice<InputDef> inputs, Slice<UniformDef> uniforms, Slice<VaryingDef> varyings) {
|
||||
switch (lang_.shaderLanguage) {
|
||||
case HLSL_D3D11:
|
||||
case HLSL_D3D9:
|
||||
break;
|
||||
case GLSL_VULKAN:
|
||||
default:
|
||||
C("void main() {\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderWriter::BeginFSMain(Slice<UniformDef> uniforms, Slice<VaryingDef> varyings) {
|
||||
switch (lang_.shaderLanguage) {
|
||||
case HLSL_D3D11:
|
||||
if (!uniforms.is_empty()) {
|
||||
for (auto &uniform : uniforms) {
|
||||
//F(" %s %s : %s;\n", uniform.type, uniform.name, uniform.index);
|
||||
}
|
||||
}
|
||||
// Let's do the varyings as parameters to main, no struct.
|
||||
C("vec4 main(");
|
||||
for (auto &varying : varyings) {
|
||||
F(" %s %s : %s, ", varying.type, varying.name, varying.semantic);
|
||||
}
|
||||
// Erase the last comma
|
||||
Rewind(2);
|
||||
|
||||
F(") : SV_Target0 {\n");
|
||||
break;
|
||||
case HLSL_D3D9:
|
||||
for (auto &uniform : uniforms) {
|
||||
F(" %s %s : %s;\n", uniform.type, uniform.name, uniform.index);
|
||||
}
|
||||
// Let's do the varyings as parameters to main, no struct.
|
||||
C("vec4 main(");
|
||||
for (auto &varying : varyings) {
|
||||
F(" %s %s : %s, ", varying.type, varying.name, varying.semantic);
|
||||
}
|
||||
// Erase the last comma
|
||||
Rewind(2);
|
||||
|
||||
F(") : COLOR {\n");
|
||||
break;
|
||||
case GLSL_VULKAN:
|
||||
for (auto &varying : varyings) {
|
||||
F("layout(location = %d) in %s %s; // %s\n", varying.index, varying.type, varying.name, varying.semantic);
|
||||
}
|
||||
C("layout (location = 0, index = 0) out vec4 fragColor0;\n");
|
||||
C("\nvoid main() {\n");
|
||||
break;
|
||||
default:
|
||||
for (auto &varying : varyings) {
|
||||
F("in %s %s; // %s\n", varying.type, varying.name, varying.semantic);
|
||||
}
|
||||
if (!strcmp(lang_.fragColor0, "fragColor0")) {
|
||||
C("out vec4 fragColor0;\n");
|
||||
}
|
||||
C("\nvoid main() {\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderWriter::EndVSMain() {
|
||||
C("}\n");
|
||||
}
|
||||
|
||||
void ShaderWriter::EndFSMain(const char *vec4_color_variable) {
|
||||
switch (lang_.shaderLanguage) {
|
||||
case HLSL_D3D11:
|
||||
case HLSL_D3D9:
|
||||
F(" return %s;\n", vec4_color_variable);
|
||||
break;
|
||||
case GLSL_VULKAN:
|
||||
default: // OpenGL
|
||||
F(" %s = %s;\n", lang_.fragColor0, vec4_color_variable);
|
||||
break;
|
||||
}
|
||||
C("}\n");
|
||||
}
|
||||
|
||||
void ShaderWriter::DeclareTexture2D(const char *name, int binding) {
|
||||
switch (lang_.shaderLanguage) {
|
||||
case HLSL_D3D11:
|
||||
F("Texture2D<float4> %s : register(t%d);\n", name, binding);
|
||||
break;
|
||||
case HLSL_D3D9:
|
||||
break;
|
||||
case GLSL_VULKAN:
|
||||
F("layout(set = 0, binding = %d) uniform sampler2D %s;\n", binding, name);
|
||||
break;
|
||||
default:
|
||||
F("uniform sampler2D %s;\n", name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderWriter::DeclareSampler2D(const char *name, int binding) {
|
||||
// We only use separate samplers in HLSL D3D11, where we have no choice.
|
||||
switch (lang_.shaderLanguage) {
|
||||
case HLSL_D3D11:
|
||||
F("SamplerState %s : register(s%d);\n", name, binding);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ShaderWriter &ShaderWriter::SampleTexture2D(const char *texName, const char *samplerName, const char *uv) {
|
||||
switch (lang_.shaderLanguage) {
|
||||
case HLSL_D3D11:
|
||||
F("%s.Sample(%s, %s)", texName, samplerName, uv);
|
||||
break;
|
||||
case HLSL_D3D9:
|
||||
F("tex2D(%s, %s)", texName, uv);
|
||||
break;
|
||||
default:
|
||||
// Note: we ignore the sampler. make sure you bound samplers to the textures correctly.
|
||||
F("%s(%s, %s)", lang_.texture, texName, uv);
|
||||
break;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,11 +4,35 @@
|
||||
|
||||
#include "Common/Log.h"
|
||||
#include "Common/GPU/Shader.h"
|
||||
#include "GPU/ge_constants.h"
|
||||
#include "GPU/GPUCommon.h"
|
||||
#include "Common/Data/Collections/Slice.h"
|
||||
|
||||
// Helps generate a shader compatible with all backends.
|
||||
//
|
||||
// Can use the uniform buffer support in thin3d.
|
||||
//
|
||||
// Using #defines and magic in this class, we partially define our own shader language that basically looks
|
||||
// like GLSL, but has a few little oddities like splat3.
|
||||
|
||||
struct InputDef {
|
||||
const char *type;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
struct UniformDef {
|
||||
const char *type;
|
||||
const char *name;
|
||||
int index;
|
||||
};
|
||||
|
||||
struct VaryingDef {
|
||||
const char *type;
|
||||
const char *name;
|
||||
const char *semantic;
|
||||
int index;
|
||||
};
|
||||
|
||||
class ShaderWriter {
|
||||
public:
|
||||
ShaderWriter(char *buffer, const ShaderLanguageDesc &lang, ShaderStage stage, const char **gl_extensions, size_t num_gl_extensions) : p_(buffer), lang_(lang), stage_(stage) {
|
||||
@@ -21,23 +45,42 @@ public:
|
||||
// Assumes the input is zero-terminated.
|
||||
// C : Copies a buffer directly to the stream.
|
||||
template<size_t T>
|
||||
void C(const char(&text)[T]) {
|
||||
ShaderWriter &C(const char(&text)[T]) {
|
||||
memcpy(p_, text, T);
|
||||
p_ += T - 1;
|
||||
return *this;
|
||||
}
|
||||
// W: Writes a zero-terminated string to the stream.
|
||||
void W(const char *text) {
|
||||
ShaderWriter &W(const char *text) {
|
||||
size_t len = strlen(text);
|
||||
memcpy(p_, text, len + 1);
|
||||
p_ += len;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// F: Formats into the buffer.
|
||||
void F(const char *format, ...);
|
||||
ShaderWriter &F(const char *format, ...);
|
||||
|
||||
// void BeginMain();
|
||||
// void EndMain();
|
||||
// Several of the shader languages ignore samplers, beware of that.
|
||||
void DeclareSampler2D(const char *name, int binding);
|
||||
void DeclareTexture2D(const char *name, int binding);
|
||||
|
||||
ShaderWriter &SampleTexture2D(const char *texName, const char *samplerName, const char *uv);
|
||||
|
||||
// Simple shaders with no special tricks.
|
||||
void BeginVSMain(Slice<InputDef> inputs, Slice<UniformDef> uniforms, Slice<VaryingDef> varyings);
|
||||
void BeginFSMain(Slice<UniformDef> uniforms, Slice<VaryingDef> varyings);
|
||||
|
||||
// For simple shaders that output a single color, we can deal with this generically.
|
||||
void EndVSMain();
|
||||
void EndFSMain(const char *vec4_color_variable);
|
||||
|
||||
|
||||
void Rewind(size_t offset) {
|
||||
p_ -= offset;
|
||||
}
|
||||
|
||||
// Can probably remove this
|
||||
char *GetPos() {
|
||||
return p_;
|
||||
}
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CommonTypes.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
|
||||
// Broken out of MemMap.h to avoid a bad include dependency.
|
||||
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
#include <cstdarg>
|
||||
|
||||
#include "GPU/Common/ColorReinterpret.h"
|
||||
#include "GPU/Common/ShaderWriter.h"
|
||||
|
||||
// TODO: We could have an option to preserve any extra color precision. But gonna start without it.
|
||||
// Requires full size integer math.
|
||||
bool GenerateReinterpretFragmentShader(char *buffer, GEBufferFormat from, GEBufferFormat to, const ShaderLanguageDesc &lang) {
|
||||
if (!lang.bitwiseOps) {
|
||||
return false;
|
||||
}
|
||||
ShaderWriter writer(buffer, lang, ShaderStage::Fragment);
|
||||
|
||||
switch (from) {
|
||||
case GE_FORMAT_4444:
|
||||
writer.W(" uint color = uint(in.r * 15.99) | (uint(in.g * 15.99) << 4) | (uint(in.b * 15.99) << 8) | (uint(in.a * 15.99) << 12);\n");
|
||||
break;
|
||||
case GE_FORMAT_5551:
|
||||
writer.W(" uint color = uint(in.r * 31.99) | (uint(in.g * 31.99) << 5) | (uint(in.b * 31.99) << 10);\n");
|
||||
writer.W(" if (in.a > 128.0) color |= 0x8000;\n");
|
||||
break;
|
||||
case GE_FORMAT_565:
|
||||
writer.W(" uint color = uint(in.r * 31.99) | (uint(in.g * 63.99) << 5) | (uint(in.b * 31.99) << 11);\n");
|
||||
break;
|
||||
default: _assert_(false);
|
||||
}
|
||||
|
||||
switch (to) {
|
||||
case GE_FORMAT_4444:
|
||||
writer.W(" vec4 output = vec4(float(color & 0xF), float((color >> 4) & 0xF), float((color >> 8) & 0xF), float((color >> 12) & 0xF));\n");
|
||||
writer.W(" output *= 1.0 / 15.0;\n");
|
||||
break;
|
||||
case GE_FORMAT_5551:
|
||||
writer.W(" vec4 output = vec4(float(color & 0x1F), float((color >> 5) & 0x1F), float((color >> 10) & 0x1F), 0.0);\n");
|
||||
writer.W(" output.rgb *= 1.0 / 31.0;\n");
|
||||
writer.W(" output.a = float(color >> 15);\n");
|
||||
break;
|
||||
case GE_FORMAT_565:
|
||||
writer.W(" vec4 output = vec4(float(color & 0x1F), float((color >> 5) & 0x3F), float((color >> 11) & 0x1F), 1.0);\n");
|
||||
writer.W(" output.rb *= 1.0 / 31.0;\n");
|
||||
writer.W(" output.g *= 1.0 / 63.0;\n");
|
||||
break;
|
||||
default: _assert_(false);
|
||||
}
|
||||
|
||||
writer.W("}");
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "Common/Log.h"
|
||||
#include "GPU/ge_constants.h"
|
||||
#include "GPU/GPUCommon.h"
|
||||
#include "GPU/Common/ShaderWriter.h"
|
||||
@@ -0,0 +1,64 @@
|
||||
#include <cstdarg>
|
||||
|
||||
#include "Common/GPU/ShaderWriter.h"
|
||||
#include "GPU/Common/ReinterpretFramebuffer.h"
|
||||
|
||||
// TODO: We could have an option to preserve any extra color precision. But gonna start without it.
|
||||
// Requires full size integer math.
|
||||
bool GenerateReinterpretFragmentShader(char *buffer, GEBufferFormat from, GEBufferFormat to, const ShaderLanguageDesc &lang) {
|
||||
if (!lang.bitwiseOps) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ShaderWriter writer(buffer, lang, ShaderStage::Fragment, nullptr, 0);
|
||||
|
||||
writer.DeclareSampler2D("samp", 0);
|
||||
writer.DeclareTexture2D("tex", 0);
|
||||
|
||||
static const VaryingDef varyings[1] = {
|
||||
{ "vec4", "v_texcoord", "TEXCOORD0" },
|
||||
};
|
||||
|
||||
writer.BeginFSMain(Slice<UniformDef>::empty(), varyings);
|
||||
|
||||
writer.C(" vec4 val = ").SampleTexture2D("tex", "samp", "v_texcoord.xy").C(";\n");
|
||||
|
||||
switch (from) {
|
||||
case GE_FORMAT_4444:
|
||||
writer.C(" uint color = uint(val.r * 15.99) | (uint(val.g * 15.99) << 4) | (uint(val.b * 15.99) << 8) | (uint(val.a * 15.99) << 12);\n");
|
||||
break;
|
||||
case GE_FORMAT_5551:
|
||||
writer.C(" uint color = uint(val.r * 31.99) | (uint(val.g * 31.99) << 5) | (uint(val.b * 31.99) << 10);\n");
|
||||
writer.C(" if (val.a > 128.0) color |= 0x8000U;\n");
|
||||
break;
|
||||
case GE_FORMAT_565:
|
||||
writer.C(" uint color = uint(val.r * 31.99) | (uint(val.g * 63.99) << 5) | (uint(val.b * 31.99) << 11);\n");
|
||||
break;
|
||||
default:
|
||||
_assert_(false);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (to) {
|
||||
case GE_FORMAT_4444:
|
||||
writer.C(" vec4 outColor = vec4(float(color & 0xFU), float((color >> 4) & 0xFU), float((color >> 8) & 0xFU), float((color >> 12) & 0xFU));\n");
|
||||
writer.C(" outColor *= 1.0 / 15.0;\n");
|
||||
break;
|
||||
case GE_FORMAT_5551:
|
||||
writer.C(" vec4 outColor = vec4(float(color & 0x1FU), float((color >> 5) & 0x1FU), float((color >> 10) & 0x1FU), 0.0);\n");
|
||||
writer.C(" outColor.rgb *= 1.0 / 31.0;\n");
|
||||
writer.C(" outColor.a = float(color >> 15);\n");
|
||||
break;
|
||||
case GE_FORMAT_565:
|
||||
writer.C(" vec4 outColor = vec4(float(color & 0x1FU), float((color >> 5) & 0x3FU), float((color >> 11) & 0x1FU), 1.0);\n");
|
||||
writer.C(" outColor.rb *= 1.0 / 31.0;\n");
|
||||
writer.C(" outColor.g *= 1.0 / 63.0;\n");
|
||||
break;
|
||||
default:
|
||||
_assert_(false);
|
||||
break;
|
||||
}
|
||||
|
||||
writer.EndFSMain("outColor");
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "Common/Log.h"
|
||||
#include "GPU/ge_constants.h"
|
||||
#include "GPU/GPUCommon.h"
|
||||
#include "Common/GPU/ShaderWriter.h"
|
||||
|
||||
bool GenerateReinterpretFragmentShader(char *buffer, GEBufferFormat from, GEBufferFormat to, const ShaderLanguageDesc &lang);
|
||||
@@ -338,6 +338,7 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\ext\xbrz\xbrz.h" />
|
||||
<ClInclude Include="Common\ReinterpretFramebuffer.h" />
|
||||
<ClInclude Include="Common\DepalettizeShaderCommon.h" />
|
||||
<ClInclude Include="Common\DrawEngineCommon.h" />
|
||||
<ClInclude Include="Common\FragmentShaderGenerator.h" />
|
||||
@@ -475,6 +476,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\ext\xbrz\xbrz.cpp" />
|
||||
<ClCompile Include="Common\ReinterpretFramebuffer.cpp" />
|
||||
<ClCompile Include="Common\DepalettizeShaderCommon.cpp" />
|
||||
<ClCompile Include="Common\DrawEngineCommon.cpp" />
|
||||
<ClCompile Include="Common\FragmentShaderGenerator.cpp" />
|
||||
|
||||
@@ -270,6 +270,9 @@
|
||||
<ClInclude Include="Common\VertexShaderGenerator.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\ReinterpretFramebuffer.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Math3D.cpp">
|
||||
@@ -539,5 +542,8 @@
|
||||
<ClCompile Include="Common\VertexShaderGenerator.cpp">
|
||||
<Filter>Common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Common\ReinterpretFramebuffer.cpp">
|
||||
<Filter>Common</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -388,6 +388,7 @@
|
||||
<ClInclude Include="..\..\GPU\Common\GPUStateUtils.h" />
|
||||
<ClInclude Include="..\..\GPU\Common\IndexGenerator.h" />
|
||||
<ClInclude Include="..\..\GPU\Common\PostShader.h" />
|
||||
<ClInclude Include="..\..\GPU\Common\ReinterpretFramebuffer.h" />
|
||||
<ClInclude Include="..\..\GPU\Common\ShaderCommon.h" />
|
||||
<ClInclude Include="..\..\GPU\Common\ShaderId.h" />
|
||||
<ClInclude Include="..\..\GPU\Common\ShaderTranslation.h" />
|
||||
@@ -445,6 +446,7 @@
|
||||
<ClCompile Include="..\..\GPU\Common\GPUStateUtils.cpp" />
|
||||
<ClCompile Include="..\..\GPU\Common\IndexGenerator.cpp" />
|
||||
<ClCompile Include="..\..\GPU\Common\PostShader.cpp" />
|
||||
<ClCompile Include="..\..\GPU\Common\ReinterpretFramebuffer.cpp" />
|
||||
<ClCompile Include="..\..\GPU\Common\ShaderCommon.cpp" />
|
||||
<ClCompile Include="..\..\GPU\Common\ShaderId.cpp" />
|
||||
<ClCompile Include="..\..\GPU\Common\ShaderTranslation.cpp" />
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
<ClCompile Include="..\..\GPU\Software\RasterizerRectangle.cpp" />
|
||||
<ClCompile Include="..\..\GPU\Common\FragmentShaderGenerator.cpp" />
|
||||
<ClCompile Include="..\..\GPU\Common\VertexShaderGenerator.cpp" />
|
||||
<ClCompile Include="..\..\GPU\Common\ReinterpretFramebuffer.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\GPU\Common\DepalettizeShaderCommon.h" />
|
||||
@@ -114,5 +115,6 @@
|
||||
<ClInclude Include="..\..\GPU\Software\RasterizerRectangle.h" />
|
||||
<ClInclude Include="..\..\GPU\Common\FragmentShaderGenerator.h" />
|
||||
<ClInclude Include="..\..\GPU\Common\VertexShaderGenerator.h" />
|
||||
<ClInclude Include="..\..\GPU\Common\ReinterpretFramebuffer.h" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -316,6 +316,7 @@ EXEC_AND_LIB_FILES := \
|
||||
$(SRC)/GPU/Common/ShaderId.cpp.arm \
|
||||
$(SRC)/GPU/Common/GPUStateUtils.cpp.arm \
|
||||
$(SRC)/GPU/Common/SoftwareTransformCommon.cpp.arm \
|
||||
$(SRC)/GPU/Common/ReinterpretFramebuffer.cpp \
|
||||
$(SRC)/GPU/Common/VertexDecoderCommon.cpp.arm \
|
||||
$(SRC)/GPU/Common/TextureCacheCommon.cpp.arm \
|
||||
$(SRC)/GPU/Common/TextureScalerCommon.cpp.arm \
|
||||
|
||||
@@ -234,6 +234,7 @@ SOURCES_CXX += \
|
||||
$(GPUCOMMONDIR)/SplineCommon.cpp \
|
||||
$(GPUCOMMONDIR)/FramebufferManagerCommon.cpp \
|
||||
$(GPUCOMMONDIR)/PresentationCommon.cpp \
|
||||
$(GPUCOMMONDIR)/ReinterpretFramebuffer.cpp \
|
||||
$(GPUCOMMONDIR)/ShaderId.cpp \
|
||||
$(GPUCOMMONDIR)/ShaderCommon.cpp \
|
||||
$(GPUCOMMONDIR)/ShaderUniforms.cpp \
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "GPU/Common/FragmentShaderGenerator.h"
|
||||
#include "GPU/Common/VertexShaderGenerator.h"
|
||||
#include "GPU/Common/ReinterpretFramebuffer.h"
|
||||
|
||||
#include "GPU/D3D11/D3D11Util.h"
|
||||
#include "GPU/D3D11/D3D11Loader.h"
|
||||
@@ -141,12 +142,72 @@ void PrintDiff(const char *a, const char *b) {
|
||||
}
|
||||
}
|
||||
|
||||
const char *ShaderLanguageToString(ShaderLanguage lang) {
|
||||
switch (lang) {
|
||||
case HLSL_D3D11: return "HLSL_D3D11";
|
||||
case HLSL_D3D9: return "HLSL_D3D9";
|
||||
case GLSL_VULKAN: return "GLSL_VULKAN";
|
||||
case GLSL_1xx: return "GLSL_1xx";
|
||||
case GLSL_3xx: return "GLSL_3xx";
|
||||
default: return "N/A";
|
||||
}
|
||||
}
|
||||
|
||||
bool TestReinterpretShaders() {
|
||||
ShaderLanguage languages[] = {
|
||||
ShaderLanguage::HLSL_D3D11,
|
||||
ShaderLanguage::GLSL_VULKAN,
|
||||
ShaderLanguage::GLSL_3xx,
|
||||
};
|
||||
GEBufferFormat fmts[3] = {
|
||||
GE_FORMAT_565,
|
||||
GE_FORMAT_5551,
|
||||
GE_FORMAT_4444,
|
||||
};
|
||||
char *buffer = new char[65536];
|
||||
|
||||
// Generate all despite failures - it's only 6.
|
||||
bool failed = false;
|
||||
|
||||
for (int k = 0; k < ARRAY_SIZE(languages); k++) {
|
||||
printf("=== %s ===\n\n", ShaderLanguageToString(languages[k]));
|
||||
|
||||
ShaderLanguageDesc desc(languages[k]);
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
if (i == j)
|
||||
continue; // useless shader!
|
||||
if (!GenerateReinterpretFragmentShader(buffer, fmts[i], fmts[j], desc)) {
|
||||
printf("Failed!\n%s\n", buffer);
|
||||
failed = true;
|
||||
} else {
|
||||
std::string errorMessage;
|
||||
if (!TestCompileShader(buffer, languages[k], false, &errorMessage)) {
|
||||
printf("Error compiling fragment shader %d:\n\n%s\n\n%s\n", (int)j, LineNumberString(buffer).c_str(), errorMessage.c_str());
|
||||
failed = true;
|
||||
return false;
|
||||
} else {
|
||||
printf("===\n%s\n===\n", buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return !failed;
|
||||
}
|
||||
|
||||
|
||||
bool TestShaderGenerators() {
|
||||
LoadD3D11();
|
||||
init_glslang();
|
||||
LoadD3DCompilerDynamic();
|
||||
|
||||
if (!TestReinterpretShaders()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ShaderLanguage languages[] = {
|
||||
ShaderLanguage::HLSL_D3D9,
|
||||
ShaderLanguage::HLSL_D3D11,
|
||||
|
||||
Reference in New Issue
Block a user