Commit b04dc82e by Geoff Lang

Move Framebuffer clearing from Renderer to the Framebuffer object.

BUG=angle:841 Change-Id: I95c9cbdc2d1c99731e19c48e18117358d22b9e94 Reviewed-on: https://chromium-review.googlesource.com/232690Reviewed-by: 's avatarKenneth Russell <kbr@chromium.org> Reviewed-by: 's avatarBrandon Jones <bajones@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent c9878cb1
......@@ -1231,56 +1231,6 @@ bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned
return false;
}
Error Context::clear(GLbitfield mask)
{
if (mState.isRasterizerDiscardEnabled())
{
return Error(GL_NO_ERROR);
}
return mRenderer->clear(getData(), mask);
}
Error Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
{
if (mState.isRasterizerDiscardEnabled())
{
return Error(GL_NO_ERROR);
}
return mRenderer->clearBufferfv(getData(), buffer, drawbuffer, values);
}
Error Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
{
if (mState.isRasterizerDiscardEnabled())
{
return Error(GL_NO_ERROR);
}
return mRenderer->clearBufferuiv(getData(), buffer, drawbuffer, values);
}
Error Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
{
if (mState.isRasterizerDiscardEnabled())
{
return Error(GL_NO_ERROR);
}
return mRenderer->clearBufferiv(getData(), buffer, drawbuffer, values);
}
Error Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
{
if (mState.isRasterizerDiscardEnabled())
{
return Error(GL_NO_ERROR);
}
return mRenderer->clearBufferfi(getData(), buffer, drawbuffer, depth, stencil);
}
Error Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
{
......
......@@ -175,12 +175,6 @@ class Context
bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams);
bool getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams);
Error clear(GLbitfield mask);
Error clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values);
Error clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values);
Error clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values);
Error clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
Error readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels);
Error drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances);
Error drawElements(GLenum mode, GLsizei count, GLenum type,
......
......@@ -463,6 +463,31 @@ Error Framebuffer::invalidateSub(size_t count, const GLenum *attachments, const
return mImpl->invalidateSub(count, attachments, area);
}
Error Framebuffer::clear(const State &state, GLbitfield mask)
{
return mImpl->clear(state, mask);
}
Error Framebuffer::clearBufferfv(const State &state, GLenum buffer, GLint drawbuffer, const GLfloat *values)
{
return mImpl->clearBufferfv(state, buffer, drawbuffer, values);
}
Error Framebuffer::clearBufferuiv(const State &state, GLenum buffer, GLint drawbuffer, const GLuint *values)
{
return mImpl->clearBufferuiv(state, buffer, drawbuffer, values);
}
Error Framebuffer::clearBufferiv(const State &state, GLenum buffer, GLint drawbuffer, const GLint *values)
{
return mImpl->clearBufferiv(state, buffer, drawbuffer, values);
}
Error Framebuffer::clearBufferfi(const State &state, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
{
return mImpl->clearBufferfi(state, buffer, drawbuffer, depth, stencil);
}
int Framebuffer::getSamples(const gl::Data &data) const
{
if (checkStatus(data) == GL_FRAMEBUFFER_COMPLETE)
......
......@@ -36,6 +36,7 @@ struct Caps;
struct Extensions;
class TextureCapsMap;
struct Data;
class State;
struct Rectangle;
typedef std::vector<FramebufferAttachment *> ColorbufferInfo;
......@@ -87,6 +88,12 @@ class Framebuffer
Error invalidate(size_t count, const GLenum *attachments);
Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area);
Error clear(const State &state, GLbitfield mask);
Error clearBufferfv(const State &state, GLenum buffer, GLint drawbuffer, const GLfloat *values);
Error clearBufferuiv(const State &state, GLenum buffer, GLint drawbuffer, const GLuint *values);
Error clearBufferiv(const State &state, GLenum buffer, GLint drawbuffer, const GLint *values);
Error clearBufferfi(const State &state, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
// Use this method to retrieve the color buffer map when doing rendering.
// It will apply a workaround for poor shader performance on some systems
// by compacting the list to skip NULL values.
......
......@@ -15,6 +15,7 @@
namespace gl
{
class State;
class FramebufferAttachment;
struct Rectangle;
}
......@@ -50,6 +51,12 @@ class FramebufferImpl
virtual gl::Error invalidate(size_t count, const GLenum *attachments) = 0;
virtual gl::Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area) = 0;
virtual gl::Error clear(const gl::State &state, GLbitfield mask) = 0;
virtual gl::Error clearBufferfv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLfloat *values) = 0;
virtual gl::Error clearBufferuiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLuint *values) = 0;
virtual gl::Error clearBufferiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLint *values) = 0;
virtual gl::Error clearBufferfi(const gl::State &state, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) = 0;
virtual GLenum checkStatus() const = 0;
};
......
......@@ -84,12 +84,6 @@ class Renderer
const GLvoid *indices, GLsizei instances,
const RangeUI &indexRange) = 0;
virtual gl::Error clear(const gl::Data &data, GLbitfield mask) = 0;
virtual gl::Error clearBufferfv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLfloat *values) = 0;
virtual gl::Error clearBufferuiv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLuint *values) = 0;
virtual gl::Error clearBufferiv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLint *values) = 0;
virtual gl::Error clearBufferfi(const gl::Data &data, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) = 0;
virtual gl::Error readPixels(const gl::Data &data, GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, GLsizei *bufSize, void* pixels) = 0;
......
......@@ -66,11 +66,18 @@ RenderTarget *DefaultAttachmentD3D::getRenderTarget() const
FramebufferD3D::FramebufferD3D(RendererD3D *renderer)
: mRenderer(renderer),
mColorBuffers(renderer->getRendererCaps().maxColorAttachments)
mColorBuffers(renderer->getRendererCaps().maxColorAttachments),
mDepthbuffer(nullptr),
mStencilbuffer(nullptr),
mDrawBuffers(renderer->getRendererCaps().maxDrawBuffers)
{
ASSERT(mRenderer != nullptr);
std::fill(mColorBuffers.begin(), mColorBuffers.end(), nullptr);
ASSERT(mDrawBuffers.size() > 0);
mDrawBuffers[0] = GL_COLOR_ATTACHMENT0;
std::fill(mDrawBuffers.begin() + 1, mDrawBuffers.end(), GL_NONE);
}
FramebufferD3D::~FramebufferD3D()
......@@ -85,18 +92,24 @@ void FramebufferD3D::setColorAttachment(size_t index, const gl::FramebufferAttac
void FramebufferD3D::setDepthttachment(const gl::FramebufferAttachment *attachment)
{
mDepthbuffer = attachment;
}
void FramebufferD3D::setStencilAttachment(const gl::FramebufferAttachment *attachment)
{
mStencilbuffer = attachment;
}
void FramebufferD3D::setDepthStencilAttachment(const gl::FramebufferAttachment *attachment)
{
mDepthbuffer = attachment;
mStencilbuffer = attachment;
}
void FramebufferD3D::setDrawBuffers(size_t count, const GLenum *buffers)
{
std::copy_n(buffers, count, mDrawBuffers.begin());
std::fill(mDrawBuffers.begin() + count, mDrawBuffers.end(), GL_NONE);
}
void FramebufferD3D::setReadBuffer(GLenum buffer)
......@@ -115,6 +128,86 @@ gl::Error FramebufferD3D::invalidateSub(size_t, const GLenum *, const gl::Rectan
return gl::Error(GL_NO_ERROR);
}
gl::Error FramebufferD3D::clear(const gl::State &state, GLbitfield mask)
{
gl::ClearParameters clearParams = state.getClearParameters(mask);
return clear(state, clearParams);
}
gl::Error FramebufferD3D::clearBufferfv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLfloat *values)
{
// glClearBufferfv can be called to clear the color buffer or depth buffer
gl::ClearParameters clearParams = state.getClearParameters(0);
if (buffer == GL_COLOR)
{
for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
{
clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
}
clearParams.colorFClearValue = gl::ColorF(values[0], values[1], values[2], values[3]);
clearParams.colorClearType = GL_FLOAT;
}
if (buffer == GL_DEPTH)
{
clearParams.clearDepth = true;
clearParams.depthClearValue = values[0];
}
return clear(state, clearParams);
}
gl::Error FramebufferD3D::clearBufferuiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLuint *values)
{
// glClearBufferuiv can only be called to clear a color buffer
gl::ClearParameters clearParams = state.getClearParameters(0);
for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
{
clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
}
clearParams.colorUIClearValue = gl::ColorUI(values[0], values[1], values[2], values[3]);
clearParams.colorClearType = GL_UNSIGNED_INT;
return clear(state, clearParams);
}
gl::Error FramebufferD3D::clearBufferiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLint *values)
{
// glClearBufferiv can be called to clear the color buffer or stencil buffer
gl::ClearParameters clearParams = state.getClearParameters(0);
if (buffer == GL_COLOR)
{
for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
{
clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
}
clearParams.colorIClearValue = gl::ColorI(values[0], values[1], values[2], values[3]);
clearParams.colorClearType = GL_INT;
}
if (buffer == GL_STENCIL)
{
clearParams.clearStencil = true;
clearParams.stencilClearValue = values[1];
}
return clear(state, clearParams);
}
gl::Error FramebufferD3D::clearBufferfi(const gl::State &state, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
{
// glClearBufferfi can only be called to clear a depth stencil buffer
gl::ClearParameters clearParams = state.getClearParameters(0);
clearParams.clearDepth = true;
clearParams.depthClearValue = depth;
clearParams.clearStencil = true;
clearParams.stencilClearValue = stencil;
return clear(state, clearParams);
}
GLenum FramebufferD3D::checkStatus() const
{
// D3D11 does not allow for overlapping RenderTargetViews, so ensure uniqueness
......
......@@ -15,6 +15,7 @@
namespace gl
{
struct ClearParameters;
class FramebufferAttachment;
}
......@@ -60,13 +61,26 @@ class FramebufferD3D : public FramebufferImpl
gl::Error invalidate(size_t count, const GLenum *attachments) override;
gl::Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area) override;
gl::Error clear(const gl::State &state, GLbitfield mask) override;
gl::Error clearBufferfv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLfloat *values) override;
gl::Error clearBufferuiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLuint *values) override;
gl::Error clearBufferiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLint *values) override;
gl::Error clearBufferfi(const gl::State &state, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) override;
GLenum checkStatus() const override;
protected:
std::vector<const gl::FramebufferAttachment*> mColorBuffers;
const gl::FramebufferAttachment *mDepthbuffer;
const gl::FramebufferAttachment *mStencilbuffer;
std::vector<GLenum> mDrawBuffers;
private:
RendererD3D *const mRenderer;
virtual gl::Error clear(const gl::State &state, const gl::ClearParameters &clearParams) = 0;
};
gl::Error GetAttachmentRenderTarget(const gl::FramebufferAttachment *attachment, RenderTarget **outRT);
......
......@@ -636,128 +636,6 @@ gl::Texture *RendererD3D::getIncompleteTexture(GLenum type)
return mIncompleteTextures[type].get();
}
gl::Error RendererD3D::clear(const gl::Data &data, GLbitfield mask)
{
gl::ClearParameters clearParams = data.state->getClearParameters(mask);
// Clips the clear to the scissor rectangle but not the viewport
gl::Error error = applyRenderTarget(data, GL_TRIANGLES, true);
if (error.isError())
{
return error;
}
return clear(clearParams, data.state->getDrawFramebuffer());
}
gl::Error RendererD3D::clearBufferfv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLfloat *values)
{
// glClearBufferfv can be called to clear the color buffer or depth buffer
gl::ClearParameters clearParams = data.state->getClearParameters(0);
if (buffer == GL_COLOR)
{
for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
{
clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
}
clearParams.colorFClearValue = gl::ColorF(values[0], values[1], values[2], values[3]);
clearParams.colorClearType = GL_FLOAT;
}
if (buffer == GL_DEPTH)
{
clearParams.clearDepth = true;
clearParams.depthClearValue = values[0];
}
// Clips the clear to the scissor rectangle but not the viewport
gl::Error error = applyRenderTarget(data, GL_TRIANGLES, true);
if (error.isError())
{
return error;
}
return clear(clearParams, data.state->getDrawFramebuffer());
}
gl::Error RendererD3D::clearBufferuiv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLuint *values)
{
// glClearBufferuiv can only be called to clear a color buffer
gl::ClearParameters clearParams = data.state->getClearParameters(0);
for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
{
clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
}
clearParams.colorUIClearValue = gl::ColorUI(values[0], values[1], values[2], values[3]);
clearParams.colorClearType = GL_UNSIGNED_INT;
// Clips the clear to the scissor rectangle but not the viewport
gl::Error error = applyRenderTarget(data, GL_TRIANGLES, true);
if (error.isError())
{
return error;
}
return clear(clearParams, data.state->getDrawFramebuffer());
}
gl::Error RendererD3D::clearBufferiv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLint *values)
{
// glClearBufferiv can be called to clear the color buffer or stencil buffer
gl::ClearParameters clearParams = data.state->getClearParameters(0);
if (buffer == GL_COLOR)
{
for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
{
clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
}
clearParams.colorIClearValue = gl::ColorI(values[0], values[1], values[2], values[3]);
clearParams.colorClearType = GL_INT;
}
if (buffer == GL_STENCIL)
{
clearParams.clearStencil = true;
clearParams.stencilClearValue = values[1];
}
// Clips the clear to the scissor rectangle but not the viewport
gl::Error error = applyRenderTarget(data, GL_TRIANGLES, true);
if (error.isError())
{
return error;
}
return clear(clearParams, data.state->getDrawFramebuffer());
}
gl::Error RendererD3D::clearBufferfi(const gl::Data &data, GLenum buffer, GLint drawbuffer,
GLfloat depth, GLint stencil)
{
if (data.state->isRasterizerDiscardEnabled())
{
return gl::Error(GL_NO_ERROR);
}
// glClearBufferfi can only be called to clear a depth stencil buffer
gl::ClearParameters clearParams = data.state->getClearParameters(0);
clearParams.clearDepth = true;
clearParams.depthClearValue = depth;
clearParams.clearStencil = true;
clearParams.stencilClearValue = stencil;
// Clips the clear to the scissor rectangle but not the viewport
gl::Error error = applyRenderTarget(data, GL_TRIANGLES, true);
if (error.isError())
{
return error;
}
return clear(clearParams, data.state->getDrawFramebuffer());
}
gl::Error RendererD3D::blitFramebuffer(const gl::Data &data,
GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
......
......@@ -59,12 +59,6 @@ class RendererD3D : public Renderer
const GLvoid *indices, GLsizei instances,
const RangeUI &indexRange) override;
gl::Error clear(const gl::Data &data, GLbitfield mask) override;
gl::Error clearBufferfv(const gl::Data &data, GLenum buffer, int drawbuffer, const GLfloat *values) override;
gl::Error clearBufferuiv(const gl::Data &data, GLenum buffer, int drawbuffer, const GLuint *values) override;
gl::Error clearBufferiv(const gl::Data &data, GLenum buffer, int drawbuffer, const GLint *values) override;
gl::Error clearBufferfi(const gl::Data &data, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) override;
gl::Error readPixels(const gl::Data &data, GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, GLsizei *bufSize, void* pixels) override;
......@@ -176,7 +170,6 @@ class RendererD3D : public Renderer
virtual gl::Error drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive) = 0;
virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) = 0;
virtual gl::Error clear(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer) = 0;
virtual gl::Error blitRect(const gl::Framebuffer *readTarget, const gl::Rectangle &readRect,
const gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
const gl::Rectangle *scissor, bool blitRenderTarget,
......
......@@ -17,7 +17,7 @@
namespace gl
{
class Framebuffer;
class FramebufferAttachment;
}
namespace rx
......@@ -32,7 +32,9 @@ class Clear11
~Clear11();
// Clears the framebuffer with the supplied clear parameters, assumes that the framebuffer is currently applied.
gl::Error clearFramebuffer(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer);
gl::Error clearFramebuffer(const gl::ClearParameters &clearParams, const std::vector<const gl::FramebufferAttachment*> &colorAttachments,
const std::vector<GLenum> &drawBufferStates, const gl::FramebufferAttachment *depthAttachment,
const gl::FramebufferAttachment *stencilAttachment);
private:
Renderer11 *mRenderer;
......
......@@ -7,7 +7,13 @@
// Framebuffer11.cpp: Implements the Framebuffer11 class.
#include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h"
#include "libANGLE/renderer/d3d/d3d11/Clear11.h"
#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h"
#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
#include "libANGLE/renderer/d3d/TextureD3D.h"
#include "libANGLE/Framebuffer.h"
#include "libANGLE/FramebufferAttachment.h"
#include "libANGLE/Texture.h"
namespace rx
{
......@@ -23,4 +29,48 @@ Framebuffer11::~Framebuffer11()
{
}
static void InvalidateAttachmentSwizzles(const gl::FramebufferAttachment *attachment)
{
if (attachment && attachment->type() == GL_TEXTURE)
{
gl::Texture *texture = attachment->getTexture();
TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
TextureStorage *texStorage = textureD3D->getNativeTexture();
if (texStorage)
{
TextureStorage11 *texStorage11 = TextureStorage11::makeTextureStorage11(texStorage);
if (!texStorage11)
{
ERR("texture storage pointer unexpectedly null.");
return;
}
texStorage11->invalidateSwizzleCacheLevel(attachment->mipLevel());
}
}
}
void Framebuffer11::invalidateSwizzles()
{
std::for_each(mColorBuffers.begin(), mColorBuffers.end(), InvalidateAttachmentSwizzles);
InvalidateAttachmentSwizzles(mDepthbuffer);
InvalidateAttachmentSwizzles(mStencilbuffer);
}
gl::Error Framebuffer11::clear(const gl::State &state, const gl::ClearParameters &clearParams)
{
Clear11 *clearer = mRenderer->getClearer();
gl::Error error = clearer->clearFramebuffer(clearParams, mColorBuffers, mDrawBuffers,
mDepthbuffer, mStencilbuffer);
if (error.isError())
{
return error;
}
invalidateSwizzles();
return gl::Error(GL_NO_ERROR);
}
}
......@@ -21,7 +21,12 @@ class Framebuffer11 : public FramebufferD3D
Framebuffer11(Renderer11 *renderer);
virtual ~Framebuffer11();
// Invalidate the cached swizzles of all bound texture attachments.
void invalidateSwizzles();
private:
gl::Error clear(const gl::State &state, const gl::ClearParameters &clearParams) override;
Renderer11 *const mRenderer;
};
......
......@@ -1753,19 +1753,6 @@ gl::Error Renderer11::applyUniforms(const ProgramImpl &program, const std::vecto
return gl::Error(GL_NO_ERROR);
}
gl::Error Renderer11::clear(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer)
{
gl::Error error = mClear->clearFramebuffer(clearParams, frameBuffer);
if (error.isError())
{
return error;
}
invalidateFramebufferSwizzles(frameBuffer);
return gl::Error(GL_NO_ERROR);
}
void Renderer11::markAllStateDirty()
{
for (unsigned int rtIndex = 0; rtIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++)
......
......@@ -94,8 +94,6 @@ class Renderer11 : public RendererD3D
virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances);
gl::Error clear(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer) override;
virtual void markAllStateDirty();
// lost device
......@@ -195,6 +193,7 @@ class Renderer11 : public RendererD3D
DXGIFactory *getDxgiFactory() { return mDxgiFactory; };
Blit11 *getBlitter() { return mBlit; }
Clear11 *getClearer() { return mClear; }
// Buffer-to-texture and Texture-to-buffer copies
virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const;
......
......@@ -7,7 +7,15 @@
// Framebuffer9.cpp: Implements the Framebuffer9 class.
#include "libANGLE/renderer/d3d/d3d9/Framebuffer9.h"
#include "libANGLE/renderer/d3d/d3d9/formatutils9.h"
#include "libANGLE/renderer/d3d/d3d9/TextureStorage9.h"
#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h"
#include "libANGLE/renderer/d3d/TextureD3D.h"
#include "libANGLE/Framebuffer.h"
#include "libANGLE/FramebufferAttachment.h"
#include "libANGLE/Texture.h"
namespace rx
{
......@@ -23,4 +31,25 @@ Framebuffer9::~Framebuffer9()
{
}
gl::Error Framebuffer9::clear(const gl::State &state, const gl::ClearParameters &clearParams)
{
const gl::FramebufferAttachment *colorBuffer = mColorBuffers[0];
const gl::FramebufferAttachment *depthStencilBuffer = (mDepthbuffer != nullptr) ? mDepthbuffer
: mStencilbuffer;
gl::Error error = mRenderer->applyRenderTarget(colorBuffer, depthStencilBuffer);
if (error.isError())
{
return error;
}
float nearZ, farZ;
state.getDepthRange(&nearZ, &farZ);
mRenderer->setViewport(state.getViewport(), nearZ, farZ, GL_TRIANGLES, state.getRasterizerState().frontFace, true);
mRenderer->setScissorRectangle(state.getScissor(), state.isScissorTestEnabled());
return mRenderer->clear(clearParams, mColorBuffers[0], depthStencilBuffer);
}
}
......@@ -22,6 +22,8 @@ class Framebuffer9 : public FramebufferD3D
virtual ~Framebuffer9();
private:
gl::Error clear(const gl::State &state, const gl::ClearParameters &clearParams) override;
Renderer9 *const mRenderer;
};
......
......@@ -1155,7 +1155,7 @@ bool Renderer9::applyPrimitiveType(GLenum mode, GLsizei count)
}
gl::Error Renderer9::getNullColorbuffer(gl::FramebufferAttachment *depthbuffer, gl::FramebufferAttachment **outColorBuffer)
gl::Error Renderer9::getNullColorbuffer(const gl::FramebufferAttachment *depthbuffer, const gl::FramebufferAttachment **outColorBuffer)
{
ASSERT(depthbuffer);
......@@ -1205,28 +1205,27 @@ gl::Error Renderer9::getNullColorbuffer(gl::FramebufferAttachment *depthbuffer,
return gl::Error(GL_NO_ERROR);
}
gl::Error Renderer9::applyRenderTarget(const gl::Framebuffer *framebuffer)
gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorBuffer, const gl::FramebufferAttachment *depthStencilBuffer)
{
// if there is no color attachment we must synthesize a NULL colorattachment
// to keep the D3D runtime happy. This should only be possible if depth texturing.
gl::FramebufferAttachment *attachment = framebuffer->getColorbuffer(0);
if (!attachment)
if (!colorBuffer)
{
gl::Error error = getNullColorbuffer(framebuffer->getDepthbuffer(), &attachment);
gl::Error error = getNullColorbuffer(depthStencilBuffer, &colorBuffer);
if (error.isError())
{
return error;
}
}
ASSERT(attachment);
ASSERT(colorBuffer);
bool renderTargetChanged = false;
unsigned int renderTargetSerial = GetAttachmentSerial(attachment);
unsigned int renderTargetSerial = GetAttachmentSerial(colorBuffer);
if (renderTargetSerial != mAppliedRenderTargetSerial)
{
// Apply the render target on the device
RenderTarget9 *renderTarget = NULL;
gl::Error error = d3d9::GetAttachmentRenderTarget(attachment, &renderTarget);
gl::Error error = d3d9::GetAttachmentRenderTarget(colorBuffer, &renderTarget);
if (error.isError())
{
return error;
......@@ -1243,31 +1242,17 @@ gl::Error Renderer9::applyRenderTarget(const gl::Framebuffer *framebuffer)
renderTargetChanged = true;
}
gl::FramebufferAttachment *depthStencil = framebuffer->getDepthbuffer();
unsigned int depthbufferSerial = 0;
unsigned int stencilbufferSerial = 0;
if (depthStencil)
{
depthbufferSerial = GetAttachmentSerial(depthStencil);
}
else if (framebuffer->getStencilbuffer())
{
depthStencil = framebuffer->getStencilbuffer();
stencilbufferSerial = GetAttachmentSerial(depthStencil);
}
if (depthbufferSerial != mAppliedDepthbufferSerial ||
stencilbufferSerial != mAppliedStencilbufferSerial ||
!mDepthStencilInitialized)
unsigned int depthStencilSerial = (depthStencilBuffer != nullptr) ? GetAttachmentSerial(depthStencilBuffer) : 0;
if (depthStencilSerial != mAppliedDepthStencilSerial || !mDepthStencilInitialized)
{
unsigned int depthSize = 0;
unsigned int stencilSize = 0;
// Apply the depth stencil on the device
if (depthStencil)
if (depthStencilBuffer)
{
RenderTarget9 *depthStencilRenderTarget = NULL;
gl::Error error = d3d9::GetAttachmentRenderTarget(depthStencil, &depthStencilRenderTarget);
gl::Error error = d3d9::GetAttachmentRenderTarget(depthStencilBuffer, &depthStencilRenderTarget);
if (error.isError())
{
return error;
......@@ -1280,8 +1265,8 @@ gl::Error Renderer9::applyRenderTarget(const gl::Framebuffer *framebuffer)
mDevice->SetDepthStencilSurface(depthStencilSurface);
SafeRelease(depthStencilSurface);
depthSize = depthStencil->getDepthSize();
stencilSize = depthStencil->getStencilSize();
depthSize = depthStencilBuffer->getDepthSize();
stencilSize = depthStencilBuffer->getStencilSize();
}
else
{
......@@ -1300,8 +1285,7 @@ gl::Error Renderer9::applyRenderTarget(const gl::Framebuffer *framebuffer)
mForceSetDepthStencilState = true;
}
mAppliedDepthbufferSerial = depthbufferSerial;
mAppliedStencilbufferSerial = stencilbufferSerial;
mAppliedDepthStencilSerial = depthStencilSerial;
mDepthStencilInitialized = true;
}
......@@ -1311,15 +1295,20 @@ gl::Error Renderer9::applyRenderTarget(const gl::Framebuffer *framebuffer)
mForceSetViewport = true;
mForceSetBlendState = true;
mRenderTargetDesc.width = attachment->getWidth();
mRenderTargetDesc.height = attachment->getHeight();
mRenderTargetDesc.format = attachment->getActualFormat();
mRenderTargetDesc.width = colorBuffer->getWidth();
mRenderTargetDesc.height = colorBuffer->getHeight();
mRenderTargetDesc.format = colorBuffer->getActualFormat();
mRenderTargetDescInitialized = true;
}
return gl::Error(GL_NO_ERROR);
}
gl::Error Renderer9::applyRenderTarget(const gl::Framebuffer *framebuffer)
{
return applyRenderTarget(framebuffer->getColorbuffer(0), framebuffer->getDepthOrStencilbuffer());
}
gl::Error Renderer9::applyVertexBuffer(const gl::State &state, GLint first, GLsizei count, GLsizei instances)
{
TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS];
......@@ -1880,7 +1869,8 @@ void Renderer9::applyUniformnbv(gl::LinkedUniform *targetUniform, const GLint *v
applyUniformnfv(targetUniform, (GLfloat*)vector);
}
gl::Error Renderer9::clear(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer)
gl::Error Renderer9::clear(const gl::ClearParameters &clearParams, const gl::FramebufferAttachment *colorBuffer,
const gl::FramebufferAttachment *depthStencilBuffer)
{
if (clearParams.colorClearType != GL_FLOAT)
{
......@@ -1904,9 +1894,9 @@ gl::Error Renderer9::clear(const gl::ClearParameters &clearParams, const gl::Fra
DWORD stencil = clearParams.stencilClearValue & 0x000000FF;
unsigned int stencilUnmasked = 0x0;
if (clearParams.clearStencil && frameBuffer->hasStencil())
if (clearParams.clearStencil && depthStencilBuffer->getStencilSize() > 0)
{
unsigned int stencilSize = gl::GetInternalFormatInfo((frameBuffer->getStencilbuffer()->getActualFormat())).stencilBits;
unsigned int stencilSize = gl::GetInternalFormatInfo((depthStencilBuffer->getActualFormat())).stencilBits;
stencilUnmasked = (0x1 << stencilSize) - 1;
}
......@@ -1917,9 +1907,8 @@ gl::Error Renderer9::clear(const gl::ClearParameters &clearParams, const gl::Fra
D3DCOLOR color = D3DCOLOR_ARGB(255, 0, 0, 0);
if (clearColor)
{
const gl::FramebufferAttachment *attachment = frameBuffer->getFirstColorbuffer();
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(attachment->getInternalFormat());
const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(attachment->getActualFormat());
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(colorBuffer->getInternalFormat());
const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(colorBuffer->getActualFormat());
color = D3DCOLOR_ARGB(gl::unorm<8>((formatInfo.alphaBits == 0 && actualFormatInfo.alphaBits > 0) ? 1.0f : clearParams.colorFClearValue.alpha),
gl::unorm<8>((formatInfo.redBits == 0 && actualFormatInfo.redBits > 0) ? 0.0f : clearParams.colorFClearValue.red),
......@@ -2100,8 +2089,7 @@ gl::Error Renderer9::clear(const gl::ClearParameters &clearParams, const gl::Fra
void Renderer9::markAllStateDirty()
{
mAppliedRenderTargetSerial = 0;
mAppliedDepthbufferSerial = 0;
mAppliedStencilbufferSerial = 0;
mAppliedDepthStencilSerial = 0;
mDepthStencilInitialized = false;
mRenderTargetDescInitialized = false;
......
......@@ -82,6 +82,7 @@ class Renderer9 : public RendererD3D
bool ignoreViewport);
gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) override;
gl::Error applyRenderTarget(const gl::FramebufferAttachment *colorBuffer, const gl::FramebufferAttachment *depthStencilBuffer);
virtual gl::Error applyShaders(gl::Program *program, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
bool rasterizerDiscard, bool transformFeedbackActive);
virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray);
......@@ -95,7 +96,8 @@ class Renderer9 : public RendererD3D
virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances);
gl::Error clear(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer) override;
gl::Error clear(const gl::ClearParameters &clearParams, const gl::FramebufferAttachment *colorBuffer,
const gl::FramebufferAttachment *depthStencilBuffer);
virtual void markAllStateDirty();
......@@ -228,7 +230,7 @@ class Renderer9 : public RendererD3D
gl::Error getCountingIB(size_t count, StaticIndexBufferInterface **outIB);
gl::Error getNullColorbuffer(gl::FramebufferAttachment *depthbuffer, gl::FramebufferAttachment **outColorBuffer);
gl::Error getNullColorbuffer(const gl::FramebufferAttachment *depthbuffer, const gl::FramebufferAttachment **outColorBuffer);
D3DPOOL getBufferPool(DWORD usage) const;
......@@ -272,8 +274,7 @@ class Renderer9 : public RendererD3D
// current render target states
unsigned int mAppliedRenderTargetSerial;
unsigned int mAppliedDepthbufferSerial;
unsigned int mAppliedStencilbufferSerial;
unsigned int mAppliedDepthStencilSerial;
bool mDepthStencilInitialized;
bool mRenderTargetDescInitialized;
RenderTarget::Desc mRenderTargetDesc;
......
......@@ -628,7 +628,7 @@ void GL_APIENTRY Clear(GLbitfield mask)
return;
}
Error error = context->clear(mask);
Error error = framebufferObject->clear(context->getState(), mask);
if (error.isError())
{
context->recordError(error);
......
......@@ -1797,7 +1797,10 @@ void GL_APIENTRY ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* val
return;
}
Error error = context->clearBufferiv(buffer, drawbuffer, value);
Framebuffer *framebufferObject = context->getState().getDrawFramebuffer();
ASSERT(framebufferObject);
Error error = framebufferObject->clearBufferiv(context->getState(), buffer, drawbuffer, value);
if (error.isError())
{
context->recordError(error);
......@@ -1834,7 +1837,10 @@ void GL_APIENTRY ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* v
return;
}
Error error = context->clearBufferuiv(buffer, drawbuffer, value);
Framebuffer *framebufferObject = context->getState().getDrawFramebuffer();
ASSERT(framebufferObject);
Error error = framebufferObject->clearBufferuiv(context->getState(), buffer, drawbuffer, value);
if (error.isError())
{
context->recordError(error);
......@@ -1879,7 +1885,10 @@ void GL_APIENTRY ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* v
return;
}
Error error = context->clearBufferfv(buffer, drawbuffer, value);
Framebuffer *framebufferObject = context->getState().getDrawFramebuffer();
ASSERT(framebufferObject);
Error error = framebufferObject->clearBufferfv(context->getState(), buffer, drawbuffer, value);
if (error.isError())
{
context->recordError(error);
......@@ -1916,7 +1925,10 @@ void GL_APIENTRY ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, G
return;
}
Error error = context->clearBufferfi(buffer, drawbuffer, depth, stencil);
Framebuffer *framebufferObject = context->getState().getDrawFramebuffer();
ASSERT(framebufferObject);
Error error = framebufferObject->clearBufferfi(context->getState(), buffer, drawbuffer, depth, stencil);
if (error.isError())
{
context->recordError(error);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment