From 2d63a74aeb67b97c4381a4574c738b3f1471be45 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 17 Jun 2014 23:10:38 -0700 Subject: [PATCH 1/6] Allow DrawPixels (uploads) to handle alpha. Doesn't update stencil, but at least it updates alpha. This was fixed to 1.0 before because we had blending enabled by accident during DrawPixels(). --- GPU/GLES/Framebuffer.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/GPU/GLES/Framebuffer.cpp b/GPU/GLES/Framebuffer.cpp index 9add9d621afc..22b29520eea5 100644 --- a/GPU/GLES/Framebuffer.cpp +++ b/GPU/GLES/Framebuffer.cpp @@ -70,8 +70,7 @@ static const char tex_fs[] = "uniform sampler2D sampler0;\n" "varying vec2 v_texcoord0;\n" "void main() {\n" - " gl_FragColor.rgb = texture2D(sampler0, v_texcoord0).rgb;\n" - " gl_FragColor.a = 1.0;\n" + " gl_FragColor = texture2D(sampler0, v_texcoord0);\n" "}\n"; static const char basic_vs[] = From d4c416a437c1a8bf037014c0ae413694d66c43fe Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 17 Jun 2014 23:27:19 -0700 Subject: [PATCH 2/6] Use the pre-world normal in software proj mapping. Fixes #6081. --- GPU/GLES/SoftwareTransform.cpp | 48 +++++++++++++++++----------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/GPU/GLES/SoftwareTransform.cpp b/GPU/GLES/SoftwareTransform.cpp index de368bf4aa82..a66747122e14 100644 --- a/GPU/GLES/SoftwareTransform.cpp +++ b/GPU/GLES/SoftwareTransform.cpp @@ -203,34 +203,37 @@ void TransformDrawEngine::SoftwareTransformAndDraw( // Scale UV? } else { // We do software T&L for now - float out[3], norm[3]; - float pos[3], nrm[3]; + float out[3]; + float pos[3]; Vec3f normal(0, 0, 1); + Vec3f worldnormal(0, 0, 1); reader.ReadPos(pos); - if (reader.hasNormal()) - reader.ReadNrm(nrm); if (!skinningEnabled) { Vec3ByMatrix43(out, pos, gstate.worldMatrix); if (reader.hasNormal()) { - Norm3ByMatrix43(norm, nrm, gstate.worldMatrix); - normal = Vec3f(norm).Normalized(); + reader.ReadNrm(normal.AsArray()); + Norm3ByMatrix43(worldnormal.AsArray(), normal.AsArray(), gstate.worldMatrix); + worldnormal = worldnormal.Normalized(); } } else { float weights[8]; reader.ReadWeights(weights); + if (reader.hasNormal()) + reader.ReadNrm(normal.AsArray()); + // Skinning - Vec3f psum(0,0,0); - Vec3f nsum(0,0,0); + Vec3f psum(0, 0, 0); + Vec3f nsum(0, 0, 0); for (int i = 0; i < vertTypeGetNumBoneWeights(vertType); i++) { if (weights[i] != 0.0f) { Vec3ByMatrix43(out, pos, gstate.boneMatrix+i*12); Vec3f tpos(out); psum += tpos * weights[i]; if (reader.hasNormal()) { - Norm3ByMatrix43(norm, nrm, gstate.boneMatrix+i*12); - Vec3f tnorm(norm); - nsum += tnorm * weights[i]; + Vec3f norm; + Norm3ByMatrix43(norm.AsArray(), normal.AsArray(), gstate.boneMatrix+i*12); + nsum += norm * weights[i]; } } } @@ -238,8 +241,9 @@ void TransformDrawEngine::SoftwareTransformAndDraw( // Yes, we really must multiply by the world matrix too. Vec3ByMatrix43(out, psum.AsArray(), gstate.worldMatrix); if (reader.hasNormal()) { - Norm3ByMatrix43(norm, nsum.AsArray(), gstate.worldMatrix); - normal = Vec3f(norm).Normalized(); + normal = nsum; + Norm3ByMatrix43(worldnormal.AsArray(), nsum.AsArray(), gstate.worldMatrix); + worldnormal = worldnormal.Normalized(); } } @@ -254,7 +258,7 @@ void TransformDrawEngine::SoftwareTransformAndDraw( if (gstate.isLightingEnabled()) { float litColor0[4]; float litColor1[4]; - lighter.Light(litColor0, litColor1, unlitColor.AsArray(), out, normal); + lighter.Light(litColor0, litColor1, unlitColor.AsArray(), out, worldnormal); // Don't ignore gstate.lmode - we should send two colors in that case for (int j = 0; j < 4; j++) { @@ -317,20 +321,16 @@ void TransformDrawEngine::SoftwareTransformAndDraw( break; case GE_PROJMAP_NORMALIZED_NORMAL: // Use normalized normal as source - if (reader.hasNormal()) { - source = Vec3f(norm).Normalized(); - } else { + source = normal.Normalized(); + if (!reader.hasNormal()) { ERROR_LOG_REPORT(G3D, "Normal projection mapping without normal?"); - source = Vec3f(0.0f, 0.0f, 1.0f); } break; case GE_PROJMAP_NORMAL: // Use non-normalized normal as source! - if (reader.hasNormal()) { - source = Vec3f(norm); - } else { + source = normal; + if (!reader.hasNormal()) { ERROR_LOG_REPORT(G3D, "Normal projection mapping without normal?"); - source = Vec3f(0.0f, 0.0f, 1.0f); } break; } @@ -349,8 +349,8 @@ void TransformDrawEngine::SoftwareTransformAndDraw( Vec3f lightpos0 = Vec3f(&lighter.lpos[gstate.getUVLS0() * 3]).Normalized(); Vec3f lightpos1 = Vec3f(&lighter.lpos[gstate.getUVLS1() * 3]).Normalized(); - uv[0] = (1.0f + Dot(lightpos0, normal))/2.0f; - uv[1] = (1.0f + Dot(lightpos1, normal))/2.0f; + uv[0] = (1.0f + Dot(lightpos0, worldnormal))/2.0f; + uv[1] = (1.0f + Dot(lightpos1, worldnormal))/2.0f; uv[2] = 1.0f; } break; From 171a865b37a90cf77a6c2fa5be3c40cea0d965c6 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 17 Jun 2014 23:29:33 -0700 Subject: [PATCH 3/6] Support reversing normals in software transform. --- GPU/GLES/SoftwareTransform.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/GPU/GLES/SoftwareTransform.cpp b/GPU/GLES/SoftwareTransform.cpp index a66747122e14..de0df57f3275 100644 --- a/GPU/GLES/SoftwareTransform.cpp +++ b/GPU/GLES/SoftwareTransform.cpp @@ -213,6 +213,9 @@ void TransformDrawEngine::SoftwareTransformAndDraw( Vec3ByMatrix43(out, pos, gstate.worldMatrix); if (reader.hasNormal()) { reader.ReadNrm(normal.AsArray()); + if (gstate.areNormalsReversed()) { + normal = -normal; + } Norm3ByMatrix43(worldnormal.AsArray(), normal.AsArray(), gstate.worldMatrix); worldnormal = worldnormal.Normalized(); } @@ -242,7 +245,10 @@ void TransformDrawEngine::SoftwareTransformAndDraw( Vec3ByMatrix43(out, psum.AsArray(), gstate.worldMatrix); if (reader.hasNormal()) { normal = nsum; - Norm3ByMatrix43(worldnormal.AsArray(), nsum.AsArray(), gstate.worldMatrix); + if (gstate.areNormalsReversed()) { + normal = -normal; + } + Norm3ByMatrix43(worldnormal.AsArray(), normal.AsArray(), gstate.worldMatrix); worldnormal = worldnormal.Normalized(); } } From a9da3618ba0653b1c239d1c7cca27e5fbcf97929 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 17 Jun 2014 23:55:09 -0700 Subject: [PATCH 4/6] Upload the color/stencil buffers on FBO creation. Fixes pausing or loading a savestate in Star Ocean (previously your character became invisible until the screen panned.) --- GPU/GLES/Framebuffer.cpp | 21 ++++++++++++++++++++- GPU/GLES/Framebuffer.h | 1 + GPU/GLES/StencilBuffer.cpp | 1 + 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/GPU/GLES/Framebuffer.cpp b/GPU/GLES/Framebuffer.cpp index 22b29520eea5..cfd6224731f5 100644 --- a/GPU/GLES/Framebuffer.cpp +++ b/GPU/GLES/Framebuffer.cpp @@ -186,6 +186,17 @@ void FramebufferManager::ClearBuffer() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); } +void FramebufferManager::ClearDepthBuffer() { + glstate.scissorTest.disable(); + glstate.depthWrite.set(GL_TRUE); +#ifdef USING_GLES2 + glClearDepthf(1.0f); +#else + glClearDepth(1.0); +#endif + glClear(GL_DEPTH_BUFFER_BIT); +} + void FramebufferManager::DisableState() { glstate.blend.disable(); glstate.cullFace.disable(); @@ -960,7 +971,6 @@ void FramebufferManager::DoSetRenderFrameBuffer() { } INFO_LOG(SCEGE, "Creating FBO for %08x : %i x %i x %i", vfb->fb_address, vfb->width, vfb->height, vfb->format); - ClearBuffer(); textureCache_->NotifyFramebuffer(vfb->fb_address, vfb, NOTIFY_FB_CREATED); @@ -976,6 +986,15 @@ void FramebufferManager::DoSetRenderFrameBuffer() { framebufRangeEnd_ = fb_address_mem + byteSize; } + if (useBufferedRendering_ && !updateVRAM_) { + gpu->PerformMemoryUpload(fb_address_mem, byteSize); + gpu->PerformStencilUpload(fb_address_mem, byteSize); + // TODO: Is it worth trying to upload the depth buffer? + ClearDepthBuffer(); + } else { + ClearBuffer(); + } + // Let's check for depth buffer overlap. Might be interesting. bool sharingReported = false; for (size_t i = 0, end = vfbs_.size(); i < end; ++i) { diff --git a/GPU/GLES/Framebuffer.h b/GPU/GLES/Framebuffer.h index dc159f17d9e7..c77fcade2a44 100644 --- a/GPU/GLES/Framebuffer.h +++ b/GPU/GLES/Framebuffer.h @@ -251,6 +251,7 @@ class FramebufferManager { void EstimateDrawingSize(int &drawing_width, int &drawing_height); static void DisableState(); static void ClearBuffer(); + static void ClearDepthBuffer(); static bool MaskedEqual(u32 addr1, u32 addr2); void SetColorUpdated(VirtualFramebuffer *dstBuffer) { diff --git a/GPU/GLES/StencilBuffer.cpp b/GPU/GLES/StencilBuffer.cpp index 71fa4f6f33d2..0429f4b2a3a0 100644 --- a/GPU/GLES/StencilBuffer.cpp +++ b/GPU/GLES/StencilBuffer.cpp @@ -88,6 +88,7 @@ bool FramebufferManager::NotifyStencilUpload(u32 addr, int size) { shaderManager_->DirtyLastShader(); + // TODO: Check if it's all the same value, commonly 0? MakePixelTexture(Memory::GetPointer(addr), dstBuffer->format, dstBuffer->fb_stride, dstBuffer->bufferWidth, dstBuffer->bufferHeight); DisableState(); glstate.colorMask.set(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); From b5eb072e6486861de6c9a96a1b5455b9309872e1 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 17 Jun 2014 23:56:33 -0700 Subject: [PATCH 5/6] Clear depth buffers to zero, not 1.0f. Memory is generally initially zeros. --- GPU/GLES/Framebuffer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/GPU/GLES/Framebuffer.cpp b/GPU/GLES/Framebuffer.cpp index cfd6224731f5..b2ad3be9005d 100644 --- a/GPU/GLES/Framebuffer.cpp +++ b/GPU/GLES/Framebuffer.cpp @@ -179,9 +179,9 @@ void FramebufferManager::ClearBuffer() { glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClearStencil(0xFF); #ifdef USING_GLES2 - glClearDepthf(1.0f); + glClearDepthf(0.0f); #else - glClearDepth(1.0); + glClearDepth(0.0); #endif glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); } @@ -190,9 +190,9 @@ void FramebufferManager::ClearDepthBuffer() { glstate.scissorTest.disable(); glstate.depthWrite.set(GL_TRUE); #ifdef USING_GLES2 - glClearDepthf(1.0f); + glClearDepthf(0.0f); #else - glClearDepth(1.0); + glClearDepth(0.0); #endif glClear(GL_DEPTH_BUFFER_BIT); } From 19f35bbac182f1326563d995875dc4a80ebf8e84 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 17 Jun 2014 23:57:20 -0700 Subject: [PATCH 6/6] Clear stencil to 0, not 1. Memory is generally initially zeros, after all. Fixes #5205 (or at least improves it?) and fixes #6226. --- GPU/GLES/Framebuffer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/GPU/GLES/Framebuffer.cpp b/GPU/GLES/Framebuffer.cpp index b2ad3be9005d..043d202ec93d 100644 --- a/GPU/GLES/Framebuffer.cpp +++ b/GPU/GLES/Framebuffer.cpp @@ -175,9 +175,9 @@ void FramebufferManager::ClearBuffer() { glstate.scissorTest.disable(); glstate.depthWrite.set(GL_TRUE); glstate.colorMask.set(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glstate.stencilFunc.set(GL_ALWAYS, 0xFF, 0xFF); - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glClearStencil(0xFF); + glstate.stencilFunc.set(GL_ALWAYS, 0, 0); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClearStencil(0); #ifdef USING_GLES2 glClearDepthf(0.0f); #else