diff --git a/GPU/Common/DrawEngineCommon.h b/GPU/Common/DrawEngineCommon.h
index e5b7f952da..65391be14f 100644
--- a/GPU/Common/DrawEngineCommon.h
+++ b/GPU/Common/DrawEngineCommon.h
@@ -35,6 +35,16 @@ enum {
DECODED_INDEX_BUFFER_SIZE = VERTEX_BUFFER_MAX * 16,
};
+enum {
+ TEX_SLOT_PSP_TEXTURE = 0,
+ TEX_SLOT_SHADERBLEND_SRC = 1,
+ TEX_SLOT_ALPHATEST = 2,
+ TEX_SLOT_CLUT = 3,
+ TEX_SLOT_SPLINE_POINTS = 4,
+ TEX_SLOT_SPLINE_WEIGHTS_U = 5,
+ TEX_SLOT_SPLINE_WEIGHTS_V = 6,
+};
+
inline uint32_t GetVertTypeID(uint32_t vertType, int uvGenMode) {
// As the decoder depends on the UVGenMode when we use UV prescale, we simply mash it
// into the top of the verttype where there are unused bits.
diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp
index 6d7f0446ee..9478bf34fd 100644
--- a/GPU/Common/FramebufferManagerCommon.cpp
+++ b/GPU/Common/FramebufferManagerCommon.cpp
@@ -469,7 +469,7 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame
if (useBufferedRendering_ && !g_Config.bDisableSlowFramebufEffects) {
gpu->PerformMemoryUpload(params.fb_address, byteSize);
- NotifyStencilUpload(params.fb_address, byteSize, StencilUpload::STENCIL_IS_ZERO);
+ PerformStencilUpload(params.fb_address, byteSize, StencilUpload::STENCIL_IS_ZERO);
// TODO: Is it worth trying to upload the depth buffer (only if it wasn't copied above..?)
}
diff --git a/GPU/Common/FramebufferManagerCommon.h b/GPU/Common/FramebufferManagerCommon.h
index 18e99fd559..894d7266e8 100644
--- a/GPU/Common/FramebufferManagerCommon.h
+++ b/GPU/Common/FramebufferManagerCommon.h
@@ -19,7 +19,6 @@
// Here's a list of functionality to unify into FramebufferManagerCommon:
// * DrawActiveTexture
// * BlitFramebuffer
-// * StencilBuffer*.cpp
//
// Also, in TextureCache we should be able to unify texture-based depal.
@@ -253,7 +252,7 @@ public:
void NotifyVideoUpload(u32 addr, int size, int width, GEBufferFormat fmt);
void UpdateFromMemory(u32 addr, int size, bool safe);
void ApplyClearToMemory(int x1, int y1, int x2, int y2, u32 clearColor);
- bool NotifyStencilUpload(u32 addr, int size, StencilUpload flags = StencilUpload::NEEDS_CLEAR);
+ bool PerformStencilUpload(u32 addr, int size, StencilUpload flags = StencilUpload::NEEDS_CLEAR);
// Returns true if it's sure this is a direct FBO->FBO transfer and it has already handle it.
// In that case we hardly need to actually copy the bytes in VRAM, they will be wrong anyway (unless
// read framebuffers is on, in which case this should always return false).
diff --git a/GPU/Common/StencilCommon.cpp b/GPU/Common/StencilCommon.cpp
index 8fa1fc0493..fb0a6172a2 100644
--- a/GPU/Common/StencilCommon.cpp
+++ b/GPU/Common/StencilCommon.cpp
@@ -17,15 +17,13 @@
#include "Common/GPU/Shader.h"
#include "Common/GPU/ShaderWriter.h"
-#include "Common/GPU/OpenGL/GLSLProgram.h"
#include "Core/Config.h"
#include "Core/ConfigValues.h"
#include "Core/Reporting.h"
#include "GPU/Common/StencilCommon.h"
-#include "GPU/GLES/DrawEngineGLES.h"
-#include "GPU/GLES/FramebufferManagerGLES.h"
-#include "GPU/GLES/ShaderManagerGLES.h"
-#include "GPU/GLES/TextureCacheGLES.h"
+#include "GPU/Common/DrawEngineCommon.h"
+#include "GPU/Common/FramebufferManagerCommon.h"
+#include "GPU/Common/TextureCacheCommon.h"
static u8 StencilBits5551(const u8 *ptr8, u32 numPixels) {
const u32 *ptr = (const u32 *)ptr8;
@@ -128,7 +126,7 @@ void GenerateStencilVs(char *buffer, const ShaderLanguageDesc &lang) {
writer.EndVSMain(varyings);
}
-bool FramebufferManagerCommon::NotifyStencilUpload(u32 addr, int size, StencilUpload flags) {
+bool FramebufferManagerCommon::PerformStencilUpload(u32 addr, int size, StencilUpload flags) {
using namespace Draw;
addr &= 0x3FFFFFFF;
@@ -179,9 +177,11 @@ bool FramebufferManagerCommon::NotifyStencilUpload(u32 addr, int size, StencilUp
if (usedBits == 0) {
if (flags == StencilUpload::STENCIL_IS_ZERO) {
- // Common when creating buffers, it's already 0. We're done.
+ // Common when creating buffers, it's already 0.
+ // We're done.
return false;
}
+
shaderManager_->DirtyLastShader();
// Let's not bother with the shader if it's just zero.
@@ -189,8 +189,8 @@ bool FramebufferManagerCommon::NotifyStencilUpload(u32 addr, int size, StencilUp
draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::CLEAR }, "NotifyStencilUpload_Clear");
}
- // Clear destination alpha.
- // render_->Clear(0, 0, 0, GL_COLOR_BUFFER_BIT, 0x8, 0, 0, 0, 0);
+ // Here we might want to clear destination alpha by using a draw, but we haven't found a need for this yet.
+ // Will implement when needed...
gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_DEPTHSTENCIL_STATE);
return true;
}
@@ -324,6 +324,6 @@ bool FramebufferManagerCommon::NotifyStencilUpload(u32 addr, int size, StencilUp
}
tex->Release();
- gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS);
+ gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS | DIRTY_VERTEXSHADER_STATE | DIRTY_FRAGMENTSHADER_STATE);
return true;
}
diff --git a/GPU/D3D11/FramebufferManagerD3D11.cpp b/GPU/D3D11/FramebufferManagerD3D11.cpp
index 6900e115d6..6d58e5caac 100644
--- a/GPU/D3D11/FramebufferManagerD3D11.cpp
+++ b/GPU/D3D11/FramebufferManagerD3D11.cpp
@@ -207,7 +207,7 @@ void FramebufferManagerD3D11::DrawActiveTexture(float x, float y, float w, float
coord[i].pos.y = -(coord[i].pos.y * invDestH - 1.0f);
}
- if (g_display_rotation != DisplayRotation::ROTATE_0) {
+ if ((flags & DRAWTEX_TO_BACKBUFFER) && g_display_rotation != DisplayRotation::ROTATE_0) {
for (int i = 0; i < 4; i++) {
// backwards notation, should fix that...
coord[i].pos = coord[i].pos * g_display_rot_matrix;
diff --git a/GPU/GLES/DrawEngineGLES.h b/GPU/GLES/DrawEngineGLES.h
index 5554fe21e8..c016771e64 100644
--- a/GPU/GLES/DrawEngineGLES.h
+++ b/GPU/GLES/DrawEngineGLES.h
@@ -40,16 +40,6 @@ struct TransformedVertex;
struct DecVtxFormat;
-enum {
- TEX_SLOT_PSP_TEXTURE = 0,
- TEX_SLOT_SHADERBLEND_SRC = 1,
- TEX_SLOT_ALPHATEST = 2,
- TEX_SLOT_CLUT = 3,
- TEX_SLOT_SPLINE_POINTS = 4,
- TEX_SLOT_SPLINE_WEIGHTS_U = 5,
- TEX_SLOT_SPLINE_WEIGHTS_V = 6,
-};
-
class TessellationDataTransferGLES : public TessellationDataTransfer {
private:
GLRTexture *data_tex[3]{};
diff --git a/GPU/GLES/FramebufferManagerGLES.h b/GPU/GLES/FramebufferManagerGLES.h
index 8347f059a2..94b06155e0 100644
--- a/GPU/GLES/FramebufferManagerGLES.h
+++ b/GPU/GLES/FramebufferManagerGLES.h
@@ -50,8 +50,6 @@ public:
void DeviceLost() override;
void DeviceRestore(Draw::DrawContext *draw) override;
- bool NotifyStencilUpload(u32 addr, int size, StencilUpload flags = StencilUpload::NEEDS_CLEAR);
-
bool GetOutputFramebuffer(GPUDebugBuffer &buffer) override;
protected:
diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp
index 9fc627fc75..03ab2629e8 100644
--- a/GPU/GPUCommon.cpp
+++ b/GPU/GPUCommon.cpp
@@ -2933,7 +2933,7 @@ void GPUCommon::NotifyVideoUpload(u32 addr, int size, int width, int format) {
bool GPUCommon::PerformStencilUpload(u32 dest, int size) {
if (framebufferManager_->MayIntersectFramebuffer(dest)) {
- framebufferManager_->NotifyStencilUpload(dest, size);
+ framebufferManager_->PerformStencilUpload(dest, size);
return true;
}
return false;
diff --git a/UWP/GPU_UWP/GPU_UWP.vcxproj b/UWP/GPU_UWP/GPU_UWP.vcxproj
index 0d09bebc50..81ab4c82a0 100644
--- a/UWP/GPU_UWP/GPU_UWP.vcxproj
+++ b/UWP/GPU_UWP/GPU_UWP.vcxproj
@@ -470,7 +470,6 @@
-
diff --git a/UWP/GPU_UWP/GPU_UWP.vcxproj.filters b/UWP/GPU_UWP/GPU_UWP.vcxproj.filters
index 84ab7ec547..f1f1de951b 100644
--- a/UWP/GPU_UWP/GPU_UWP.vcxproj.filters
+++ b/UWP/GPU_UWP/GPU_UWP.vcxproj.filters
@@ -30,7 +30,6 @@
-
diff --git a/android/jni/Android.mk b/android/jni/Android.mk
index 246278cf05..b2e4e6fe37 100644
--- a/android/jni/Android.mk
+++ b/android/jni/Android.mk
@@ -133,7 +133,6 @@ VULKAN_FILES := \
$(SRC)/GPU/Vulkan/PipelineManagerVulkan.cpp \
$(SRC)/GPU/Vulkan/ShaderManagerVulkan.cpp \
$(SRC)/GPU/Vulkan/StateMappingVulkan.cpp \
- $(SRC)/GPU/Vulkan/StencilBufferVulkan.cpp \
$(SRC)/GPU/Vulkan/TextureCacheVulkan.cpp \
$(SRC)/GPU/Vulkan/DepalettizeShaderVulkan.cpp \
$(SRC)/GPU/Vulkan/VulkanUtil.cpp \
diff --git a/unittest/TestShaderGenerators.cpp b/unittest/TestShaderGenerators.cpp
index 1c33bccca3..8583a18c60 100644
--- a/unittest/TestShaderGenerators.cpp
+++ b/unittest/TestShaderGenerators.cpp
@@ -90,18 +90,18 @@ bool GenerateVShader(VShaderID id, char *buffer, ShaderLanguage lang, Draw::Bugs
}
}
-bool TestCompileShader(const char *buffer, ShaderLanguage lang, bool vertex, std::string *errorMessage) {
+bool TestCompileShader(const char *buffer, ShaderLanguage lang, ShaderStage stage, std::string *errorMessage) {
std::vector spirv;
switch (lang) {
#if PPSSPP_PLATFORM(WINDOWS)
case ShaderLanguage::HLSL_D3D11:
{
- auto output = CompileShaderToBytecodeD3D11(buffer, strlen(buffer), vertex ? "vs_4_0" : "ps_4_0", 0);
+ auto output = CompileShaderToBytecodeD3D11(buffer, strlen(buffer), stage == ShaderStage::Vertex ? "vs_4_0" : "ps_4_0", 0);
return !output.empty();
}
case ShaderLanguage::HLSL_D3D9:
{
- LPD3DBLOB blob = CompileShaderToByteCodeD3D9(buffer, vertex ? "vs_2_0" : "ps_2_0", errorMessage);
+ LPD3DBLOB blob = CompileShaderToByteCodeD3D9(buffer, stage == ShaderStage::Vertex ? "vs_2_0" : "ps_2_0", errorMessage);
if (blob) {
blob->Release();
return true;
@@ -112,11 +112,11 @@ bool TestCompileShader(const char *buffer, ShaderLanguage lang, bool vertex, std
#endif
case ShaderLanguage::GLSL_VULKAN:
- return GLSLtoSPV(vertex ? VK_SHADER_STAGE_VERTEX_BIT : VK_SHADER_STAGE_FRAGMENT_BIT, buffer, GLSLVariant::VULKAN, spirv, errorMessage);
+ return GLSLtoSPV(stage == ShaderStage::Vertex ? VK_SHADER_STAGE_VERTEX_BIT : VK_SHADER_STAGE_FRAGMENT_BIT, buffer, GLSLVariant::VULKAN, spirv, errorMessage);
case ShaderLanguage::GLSL_1xx:
- return GLSLtoSPV(vertex ? VK_SHADER_STAGE_VERTEX_BIT : VK_SHADER_STAGE_FRAGMENT_BIT, buffer, GLSLVariant::GL140, spirv, errorMessage);
+ return GLSLtoSPV(stage == ShaderStage::Vertex ? VK_SHADER_STAGE_VERTEX_BIT : VK_SHADER_STAGE_FRAGMENT_BIT, buffer, GLSLVariant::GL140, spirv, errorMessage);
case ShaderLanguage::GLSL_3xx:
- return GLSLtoSPV(vertex ? VK_SHADER_STAGE_VERTEX_BIT : VK_SHADER_STAGE_FRAGMENT_BIT, buffer, GLSLVariant::GLES300, spirv, errorMessage);
+ return GLSLtoSPV(stage == ShaderStage::Vertex ? VK_SHADER_STAGE_VERTEX_BIT : VK_SHADER_STAGE_FRAGMENT_BIT, buffer, GLSLVariant::GLES300, spirv, errorMessage);
default:
return false;
}
@@ -186,7 +186,7 @@ bool TestReinterpretShaders() {
failed = true;
} else {
std::string errorMessage;
- if (!TestCompileShader(buffer, languages[k], true, &errorMessage)) {
+ if (!TestCompileShader(buffer, languages[k], ShaderStage::Vertex, &errorMessage)) {
printf("Error compiling fragment shader:\n\n%s\n\n%s\n", LineNumberString(buffer).c_str(), errorMessage.c_str());
failed = true;
return false;
@@ -210,7 +210,7 @@ bool TestReinterpretShaders() {
printf("Failed!\n%s\n", buffer);
failed = true;
} else {
- if (!TestCompileShader(buffer, languages[k], false, &errorMessage)) {
+ if (!TestCompileShader(buffer, languages[k], ShaderStage::Fragment, &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;
@@ -220,9 +220,37 @@ bool TestReinterpretShaders() {
}
}
}
+ }
+ delete[] buffer;
+ return !failed;
+}
+
+bool TestStencilShaders() {
+ Draw::Bugs bugs;
+
+ ShaderLanguage languages[] = {
+#if PPSSPP_PLATFORM(WINDOWS)
+ ShaderLanguage::HLSL_D3D9,
+ ShaderLanguage::HLSL_D3D11,
+#endif
+ ShaderLanguage::GLSL_VULKAN,
+ ShaderLanguage::GLSL_3xx,
+ };
+
+ char *buffer = new char[65536];
+
+ bool failed = false;
+
+ for (int k = 0; k < ARRAY_SIZE(languages); k++) {
+ printf("=== %s ===\n\n", ShaderLanguageToString(languages[k]));
+
+ ShaderLanguageDesc desc(languages[k]);
+ std::string errorMessage;
+
+ // Generate all despite failures - it's only 6.
GenerateStencilFs(buffer, desc, bugs);
- if (!TestCompileShader(buffer, languages[k], false, &errorMessage)) {
+ if (!TestCompileShader(buffer, languages[k], ShaderStage::Fragment, &errorMessage)) {
printf("Error compiling stencil shader:\n\n%s\n\n%s\n", LineNumberString(buffer).c_str(), errorMessage.c_str());
failed = true;
return false;
@@ -231,7 +259,7 @@ bool TestReinterpretShaders() {
}
GenerateStencilVs(buffer, desc);
- if (!TestCompileShader(buffer, languages[k], false, &errorMessage)) {
+ if (!TestCompileShader(buffer, languages[k], ShaderStage::Vertex, &errorMessage)) {
printf("Error compiling stencil shader:\n\n%s\n\n%s\n", LineNumberString(buffer).c_str(), errorMessage.c_str());
failed = true;
return false;
@@ -239,6 +267,8 @@ bool TestReinterpretShaders() {
printf("===\n%s\n===\n", buffer);
}
}
+
+ delete[] buffer;
return !failed;
}
@@ -301,7 +331,7 @@ bool TestVertexShaders() {
for (int j = 0; j < numLanguages; j++) {
if (generateSuccess[j]) {
std::string errorMessage;
- if (!TestCompileShader(buffer[j], languages[j], true, &errorMessage)) {
+ if (!TestCompileShader(buffer[j], languages[j], ShaderStage::Vertex, &errorMessage)) {
printf("Error compiling vertex shader %d:\n\n%s\n\n%s\n", (int)j, LineNumberString(buffer[j]).c_str(), errorMessage.c_str());
return false;
}
@@ -363,7 +393,7 @@ bool TestFragmentShaders() {
for (int j = 0; j < numLanguages; j++) {
if (generateSuccess[j]) {
std::string errorMessage;
- if (!TestCompileShader(buffer[j], languages[j], false, &errorMessage)) {
+ if (!TestCompileShader(buffer[j], languages[j], ShaderStage::Fragment, &errorMessage)) {
printf("Error compiling fragment shader:\n\n%s\n\n%s\n", LineNumberString(buffer[j]).c_str(), errorMessage.c_str());
return false;
}
@@ -389,7 +419,7 @@ bool TestShaderGenerators() {
init_glslang();
#endif
- if (!TestFragmentShaders()) {
+ if (!TestStencilShaders()) {
return false;
}
@@ -397,6 +427,10 @@ bool TestShaderGenerators() {
return false;
}
+ if (!TestFragmentShaders()) {
+ return false;
+ }
+
if (!TestVertexShaders()) {
return false;
}