mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-22 10:49:05 +02:00
Merge pull request #11192 from unknownbrackets/stencil
Correct stencil upload bugs
This commit is contained in:
3 files changed
+19
-8
No files matched your search
@@ -86,10 +86,13 @@ struct VirtualFramebuffer {
|
||||
// width/height: The detected size of the current framebuffer.
|
||||
u16 width;
|
||||
u16 height;
|
||||
// renderWidth/renderHeight: The actual size we render at. May be scaled to render at higher resolutions.
|
||||
// renderWidth/renderHeight: The scaled size we render at. May be scaled to render at higher resolutions.
|
||||
// The physical buffer may be larger than renderWidth/renderHeight.
|
||||
u16 renderWidth;
|
||||
u16 renderHeight;
|
||||
// bufferWidth/bufferHeight: The actual (but non scaled) size of the buffer we render to. May only be bigger than width/height.
|
||||
// bufferWidth/bufferHeight: The pre-scaling size of the buffer itself. May only be bigger than width/height.
|
||||
// Actual physical buffer is this size times the render resolution multiplier.
|
||||
// The buffer may be used to render a width or height from 0 to these values without being recreated.
|
||||
u16 bufferWidth;
|
||||
u16 bufferHeight;
|
||||
|
||||
|
||||
@@ -126,12 +126,15 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, bool skipZe
|
||||
std::vector<GLRShader *> shaders;
|
||||
shaders.push_back(render_->CreateShader(GL_VERTEX_SHADER, vs_code, "stencil"));
|
||||
shaders.push_back(render_->CreateShader(GL_FRAGMENT_SHADER, fs_code, "stencil"));
|
||||
std::vector<GLRProgram::Semantic> semantics;
|
||||
semantics.push_back({ 0, "a_position" });
|
||||
semantics.push_back({ 1, "a_texcoord0" });
|
||||
std::vector<GLRProgram::UniformLocQuery> queries;
|
||||
queries.push_back({ &u_stencilUploadTex, "tex" });
|
||||
queries.push_back({ &u_stencilValue, "u_stencilValue" });
|
||||
std::vector<GLRProgram::Initializer> inits;
|
||||
inits.push_back({ &u_stencilUploadTex, 0, 0 });
|
||||
stencilUploadProgram_ = render_->CreateProgram(shaders, {}, queries, inits, false);
|
||||
stencilUploadProgram_ = render_->CreateProgram(shaders, semantics, queries, inits, false);
|
||||
for (auto iter : shaders) {
|
||||
render_->DeleteShader(iter);
|
||||
}
|
||||
@@ -146,27 +149,28 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, bool skipZe
|
||||
|
||||
// Our fragment shader (and discard) is slow. Since the source is 1x, we can stencil to 1x.
|
||||
// Then after we're done, we'll just blit it across and stretch it there.
|
||||
if (dstBuffer->bufferWidth == dstBuffer->renderWidth || !dstBuffer->fbo) {
|
||||
if (dstBuffer->width == dstBuffer->renderWidth || !dstBuffer->fbo) {
|
||||
useBlit = false;
|
||||
}
|
||||
u16 w = useBlit ? dstBuffer->bufferWidth : dstBuffer->renderWidth;
|
||||
u16 h = useBlit ? dstBuffer->bufferHeight : dstBuffer->renderHeight;
|
||||
u16 w = useBlit ? dstBuffer->width : dstBuffer->renderWidth;
|
||||
u16 h = useBlit ? dstBuffer->height : dstBuffer->renderHeight;
|
||||
|
||||
Draw::Framebuffer *blitFBO = nullptr;
|
||||
if (useBlit) {
|
||||
blitFBO = GetTempFBO(TempFBO::COPY, w, h, Draw::FBO_8888);
|
||||
draw_->BindFramebufferAsRenderTarget(blitFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE });
|
||||
} else if (dstBuffer->fbo) {
|
||||
draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::CLEAR });
|
||||
draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::DONT_CARE });
|
||||
}
|
||||
render_->SetViewport({ 0, 0, (float)w, (float)h, 0.0f, 1.0f });
|
||||
|
||||
float u1 = 1.0f;
|
||||
float v1 = 1.0f;
|
||||
MakePixelTexture(src, dstBuffer->format, dstBuffer->fb_stride, dstBuffer->bufferWidth, dstBuffer->bufferHeight, u1, v1);
|
||||
MakePixelTexture(src, dstBuffer->format, dstBuffer->fb_stride, dstBuffer->width, dstBuffer->height, u1, v1);
|
||||
textureCacheGL_->ForgetLastTexture();
|
||||
|
||||
// We must bind the program after starting the render pass, and set the color mask after clearing.
|
||||
render_->SetScissor({ 0, 0, w, h });
|
||||
render_->SetDepth(false, false, GL_ALWAYS);
|
||||
render_->Clear(0, 0, 0, GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, 0x8, 0, 0, 0, 0);
|
||||
render_->SetStencilFunc(GL_TRUE, GL_ALWAYS, 0xFF, 0xFF);
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include "GPU/Vulkan/TextureCacheVulkan.h"
|
||||
#include "GPU/Vulkan/VulkanUtil.h"
|
||||
|
||||
// This shader references gl_FragDepth to prevent early fragment tests.
|
||||
// They shouldn't happen since it uses discard, but Adreno detects that incorrectly - see #10634.
|
||||
static const char *stencil_fs = R"(#version 450
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
#extension GL_ARB_shading_language_420pack : enable
|
||||
@@ -38,6 +40,8 @@ layout (location = 0) in vec2 v_texcoord0;
|
||||
layout (location = 0) out vec4 fragColor0;
|
||||
|
||||
void main() {
|
||||
gl_FragDepth = 0.0;
|
||||
|
||||
if (u_stencilValue == 0) {
|
||||
fragColor0 = vec4(0.0);
|
||||
} else {
|
||||
|
||||
Reference in new issue
Block a user