From 7155963e9a21d7f9e97bd8c49bd8f590e2695883 Mon Sep 17 00:00:00 2001 From: Nicolas Capens Date: Mon, 21 Mar 2016 14:27:31 -0400 Subject: [PATCH] Bind depth and stencil buffers separately. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Bug 27460431 Change-Id: Ice854b6faec09dc5f2cbdc2a5c3ffba9a73bfb70 Reviewed-on: https://swiftshader-review.googlesource.com/4977 Tested-by: Nicolas Capens Reviewed-by: Alexis Hétu Reviewed-by: Nicolas Capens --- src/OpenGL/libGLES_CM/Context.cpp | 3 +- src/OpenGL/libGLES_CM/Device.cpp | 112 ++++++++++++++++++++++------------ src/OpenGL/libGLES_CM/Device.hpp | 6 +- src/OpenGL/libGLESv2/Context.cpp | 3 +- src/OpenGL/libGLESv2/Device.cpp | 122 +++++++++++++++++++++++++------------- src/OpenGL/libGLESv2/Device.hpp | 6 +- 6 files changed, 167 insertions(+), 85 deletions(-) diff --git a/src/OpenGL/libGLES_CM/Context.cpp b/src/OpenGL/libGLES_CM/Context.cpp index 226e18b48..e3f9902d7 100644 --- a/src/OpenGL/libGLES_CM/Context.cpp +++ b/src/OpenGL/libGLES_CM/Context.cpp @@ -1725,7 +1725,8 @@ bool Context::applyRenderTarget() if(renderTarget) renderTarget->release(); egl::Image *depthStencil = framebuffer->getDepthStencil(); - device->setDepthStencilSurface(depthStencil); + device->setDepthBuffer(depthStencil); + device->setStencilBuffer(depthStencil); if(depthStencil) depthStencil->release(); Viewport viewport; diff --git a/src/OpenGL/libGLES_CM/Device.cpp b/src/OpenGL/libGLES_CM/Device.cpp index 693f2b5e2..80cb86e20 100644 --- a/src/OpenGL/libGLES_CM/Device.cpp +++ b/src/OpenGL/libGLES_CM/Device.cpp @@ -31,8 +31,9 @@ namespace es1 Device::Device(Context *context) : Renderer(context, OpenGL, true), context(context) { - depthStencil = nullptr; renderTarget = nullptr; + depthBuffer = nullptr; + stencilBuffer = nullptr; setDepthBufferEnable(true); setFillMode(FILL_SOLID); @@ -121,18 +122,24 @@ namespace es1 Device::~Device() { - if(depthStencil) - { - depthStencil->release(); - depthStencil = nullptr; - } - if(renderTarget) { renderTarget->release(); renderTarget = nullptr; } + if(depthBuffer) + { + depthBuffer->release(); + depthBuffer = nullptr; + } + + if(stencilBuffer) + { + stencilBuffer->release(); + stencilBuffer = nullptr; + } + delete context; } @@ -171,7 +178,7 @@ namespace es1 void Device::clearDepth(float z) { - if(!depthStencil) + if(!depthBuffer) { return; } @@ -181,8 +188,8 @@ namespace es1 int x0 = 0; int y0 = 0; - int width = depthStencil->getWidth(); - int height = depthStencil->getHeight(); + int width = depthBuffer->getWidth(); + int height = depthBuffer->getHeight(); if(scissorEnable) // Clamp against scissor rectangle { @@ -192,20 +199,20 @@ namespace es1 if(height > scissorRect.y1 - scissorRect.y0) height = scissorRect.y1 - scissorRect.y0; } - depthStencil->clearDepthBuffer(z, x0, y0, width, height); + depthBuffer->clearDepthBuffer(z, x0, y0, width, height); } void Device::clearStencil(unsigned int stencil, unsigned int mask) { - if(!depthStencil) + if(!stencilBuffer) { return; } int x0 = 0; int y0 = 0; - int width = depthStencil->getWidth(); - int height = depthStencil->getHeight(); + int width = stencilBuffer->getWidth(); + int height = stencilBuffer->getHeight(); if(scissorEnable) // Clamp against scissor rectangle { @@ -215,7 +222,7 @@ namespace es1 if(height > scissorRect.y1 - scissorRect.y0) height = scissorRect.y1 - scissorRect.y0; } - depthStencil->clearStencilBuffer(stencil, mask, x0, y0, width, height); + stencilBuffer->clearStencilBuffer(stencil, mask, x0, y0, width, height); } egl::Image *Device::createDepthStencilSurface(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard) @@ -303,49 +310,70 @@ namespace es1 draw(type, 0, primitiveCount); } - void Device::setDepthStencilSurface(egl::Image *depthStencil) + void Device::setScissorEnable(bool enable) + { + scissorEnable = enable; + } + + void Device::setRenderTarget(int index, egl::Image *renderTarget) + { + if(renderTarget) + { + renderTarget->addRef(); + } + + if(this->renderTarget) + { + this->renderTarget->release(); + } + + this->renderTarget = renderTarget; + + Renderer::setRenderTarget(index, renderTarget); + } + + void Device::setDepthBuffer(egl::Image *depthBuffer) { - if(this->depthStencil == depthStencil) + if(this->depthBuffer == depthBuffer) { return; } - if(depthStencil) + if(depthBuffer) { - depthStencil->addRef(); + depthBuffer->addRef(); } - if(this->depthStencil) + if(this->depthBuffer) { - this->depthStencil->release(); + this->depthBuffer->release(); } - this->depthStencil = depthStencil; + this->depthBuffer = depthBuffer; - setDepthBuffer(depthStencil); - setStencilBuffer(depthStencil); + Renderer::setDepthBuffer(depthBuffer); } - void Device::setScissorEnable(bool enable) + void Device::setStencilBuffer(egl::Image *stencilBuffer) { - scissorEnable = enable; - } + if(this->stencilBuffer == stencilBuffer) + { + return; + } - void Device::setRenderTarget(int index, egl::Image *renderTarget) - { - if(renderTarget) + if(stencilBuffer) { - renderTarget->addRef(); + stencilBuffer->addRef(); } - if(this->renderTarget) + if(this->stencilBuffer) { - this->renderTarget->release(); + this->stencilBuffer->release(); } - this->renderTarget = renderTarget; + this->stencilBuffer = stencilBuffer; - Renderer::setRenderTarget(index, renderTarget); + Renderer::setStencilBuffer(stencilBuffer); } void Device::setScissorRect(const sw::Rect &rect) @@ -540,12 +568,20 @@ namespace es1 scissor.y1 = min(scissor.y1, renderTarget->getHeight()); } - if(depthStencil) + if(depthBuffer) + { + scissor.x0 = max(scissor.x0, 0); + scissor.x1 = min(scissor.x1, depthBuffer->getWidth()); + scissor.y0 = max(scissor.y0, 0); + scissor.y1 = min(scissor.y1, depthBuffer->getHeight()); + } + + if(stencilBuffer) { scissor.x0 = max(scissor.x0, 0); - scissor.x1 = min(scissor.x1, depthStencil->getWidth()); + scissor.x1 = min(scissor.x1, stencilBuffer->getWidth()); scissor.y0 = max(scissor.y0, 0); - scissor.y1 = min(scissor.y1, depthStencil->getHeight()); + scissor.y1 = min(scissor.y1, stencilBuffer->getHeight()); } setScissor(scissor); diff --git a/src/OpenGL/libGLES_CM/Device.hpp b/src/OpenGL/libGLES_CM/Device.hpp index 5626ec1cb..15872ca53 100644 --- a/src/OpenGL/libGLES_CM/Device.hpp +++ b/src/OpenGL/libGLES_CM/Device.hpp @@ -47,9 +47,10 @@ namespace es1 virtual egl::Image *createRenderTarget(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool lockable); virtual void drawIndexedPrimitive(sw::DrawType type, unsigned int indexOffset, unsigned int primitiveCount); virtual void drawPrimitive(sw::DrawType type, unsigned int primiveCount); - virtual void setDepthStencilSurface(egl::Image *newDepthStencil); virtual void setScissorEnable(bool enable); virtual void setRenderTarget(int index, egl::Image *renderTarget); + virtual void setDepthBuffer(egl::Image *depthBuffer); + virtual void setStencilBuffer(egl::Image *stencilBuffer); virtual void setScissorRect(const sw::Rect &rect); virtual void setViewport(const Viewport &viewport); @@ -69,7 +70,8 @@ namespace es1 bool scissorEnable; egl::Image *renderTarget; - egl::Image *depthStencil; + egl::Image *depthBuffer; + egl::Image *stencilBuffer; }; } diff --git a/src/OpenGL/libGLESv2/Context.cpp b/src/OpenGL/libGLESv2/Context.cpp index add3aff34..a62aa0efd 100644 --- a/src/OpenGL/libGLESv2/Context.cpp +++ b/src/OpenGL/libGLESv2/Context.cpp @@ -2785,7 +2785,8 @@ bool Context::applyRenderTarget() } egl::Image *depthStencil = framebuffer->getDepthStencil(); - device->setDepthStencilSurface(depthStencil); + device->setDepthBuffer(depthStencil); + device->setStencilBuffer(depthStencil); if(depthStencil) depthStencil->release(); Viewport viewport; diff --git a/src/OpenGL/libGLESv2/Device.cpp b/src/OpenGL/libGLESv2/Device.cpp index fb5d18317..27cb86462 100644 --- a/src/OpenGL/libGLESv2/Device.cpp +++ b/src/OpenGL/libGLESv2/Device.cpp @@ -31,8 +31,13 @@ namespace es2 Device::Device(Context *context) : Renderer(context, OpenGL, true), context(context) { - depthStencil = nullptr; - for(int i = 0; i < RENDERTARGETS; ++i) { renderTarget[i] = nullptr; } + for(int i = 0; i < RENDERTARGETS; i++) + { + renderTarget[i] = nullptr; + } + + depthBuffer = nullptr; + stencilBuffer = nullptr; setDepthBufferEnable(true); setFillMode(FILL_SOLID); @@ -144,13 +149,7 @@ namespace es2 Device::~Device() { - if(depthStencil) - { - depthStencil->release(); - depthStencil = nullptr; - } - - for(int i = 0; i < RENDERTARGETS; ++i) + for(int i = 0; i < RENDERTARGETS; i++) { if(renderTarget[i]) { @@ -159,6 +158,18 @@ namespace es2 } } + if(depthBuffer) + { + depthBuffer->release(); + depthBuffer = nullptr; + } + + if(stencilBuffer) + { + stencilBuffer->release(); + stencilBuffer = nullptr; + } + delete context; } @@ -213,7 +224,7 @@ namespace es2 void Device::clearDepth(float z) { - if(!depthStencil) + if(!depthBuffer) { return; } @@ -222,22 +233,22 @@ namespace es2 if(z < 0) z = 0; int x0(0), y0(0), width(0), height(0); - getScissoredRegion(depthStencil, x0, y0, width, height); + getScissoredRegion(depthBuffer, x0, y0, width, height); - depthStencil->clearDepthBuffer(z, x0, y0, width, height); + depthBuffer->clearDepthBuffer(z, x0, y0, width, height); } void Device::clearStencil(unsigned int stencil, unsigned int mask) { - if(!depthStencil) + if(!stencilBuffer) { return; } int x0(0), y0(0), width(0), height(0); - getScissoredRegion(depthStencil, x0, y0, width, height); + getScissoredRegion(stencilBuffer, x0, y0, width, height); - depthStencil->clearStencilBuffer(stencil, mask, x0, y0, width, height); + stencilBuffer->clearStencilBuffer(stencil, mask, x0, y0, width, height); } egl::Image *Device::createDepthStencilSurface(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard) @@ -329,29 +340,6 @@ namespace es2 draw(type, 0, primitiveCount); } - void Device::setDepthStencilSurface(egl::Image *depthStencil) - { - if(this->depthStencil == depthStencil) - { - return; - } - - if(depthStencil) - { - depthStencil->addRef(); - } - - if(this->depthStencil) - { - this->depthStencil->release(); - } - - this->depthStencil = depthStencil; - - setDepthBuffer(depthStencil); - setStencilBuffer(depthStencil); - } - void Device::setPixelShader(PixelShader *pixelShader) { this->pixelShader = pixelShader; @@ -394,6 +382,50 @@ namespace es2 Renderer::setRenderTarget(index, renderTarget); } + void Device::setDepthBuffer(egl::Image *depthBuffer) + { + if(this->depthBuffer == depthBuffer) + { + return; + } + + if(depthBuffer) + { + depthBuffer->addRef(); + } + + if(this->depthBuffer) + { + this->depthBuffer->release(); + } + + this->depthBuffer = depthBuffer; + + Renderer::setDepthBuffer(depthBuffer); + } + + void Device::setStencilBuffer(egl::Image *stencilBuffer) + { + if(this->stencilBuffer == stencilBuffer) + { + return; + } + + if(stencilBuffer) + { + stencilBuffer->addRef(); + } + + if(this->stencilBuffer) + { + this->stencilBuffer->release(); + } + + this->stencilBuffer = stencilBuffer; + + Renderer::setStencilBuffer(stencilBuffer); + } + void Device::setScissorRect(const sw::Rect &rect) { scissorRect = rect; @@ -795,12 +827,20 @@ namespace es2 } } - if(depthStencil) + if(depthBuffer) + { + scissor.x0 = max(scissor.x0, 0); + scissor.x1 = min(scissor.x1, depthBuffer->getWidth()); + scissor.y0 = max(scissor.y0, 0); + scissor.y1 = min(scissor.y1, depthBuffer->getHeight()); + } + + if(stencilBuffer) { scissor.x0 = max(scissor.x0, 0); - scissor.x1 = min(scissor.x1, depthStencil->getWidth()); + scissor.x1 = min(scissor.x1, stencilBuffer->getWidth()); scissor.y0 = max(scissor.y0, 0); - scissor.y1 = min(scissor.y1, depthStencil->getHeight()); + scissor.y1 = min(scissor.y1, stencilBuffer->getHeight()); } setScissor(scissor); diff --git a/src/OpenGL/libGLESv2/Device.hpp b/src/OpenGL/libGLESv2/Device.hpp index 3d9024984..f4034decc 100644 --- a/src/OpenGL/libGLESv2/Device.hpp +++ b/src/OpenGL/libGLESv2/Device.hpp @@ -47,11 +47,12 @@ namespace es2 virtual egl::Image *createRenderTarget(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool lockable); virtual void drawIndexedPrimitive(sw::DrawType type, unsigned int indexOffset, unsigned int primitiveCount); virtual void drawPrimitive(sw::DrawType type, unsigned int primiveCount); - virtual void setDepthStencilSurface(egl::Image *newDepthStencil); virtual void setPixelShader(sw::PixelShader *shader); virtual void setPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count); virtual void setScissorEnable(bool enable); virtual void setRenderTarget(int index, egl::Image *renderTarget); + virtual void setDepthBuffer(egl::Image *depthBuffer); + virtual void setStencilBuffer(egl::Image *stencilBuffer); virtual void setScissorRect(const sw::Rect &rect); virtual void setVertexShader(sw::VertexShader *shader); virtual void setVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count); @@ -90,7 +91,8 @@ namespace es2 float vertexShaderConstantF[VERTEX_UNIFORM_VECTORS][4]; egl::Image *renderTarget[RENDERTARGETS]; - egl::Image *depthStencil; + egl::Image *depthBuffer; + egl::Image *stencilBuffer; }; } -- 2.11.0