Commit 758d5b21 by Geoff Lang Committed by Shannon Woods

Refactored validation to glBlitFramebufferANGLE and implemented glBlitFramebuffer.

TRAC #23211 Signed-off-by: Jamie Madill Signed-off-by: Shannon Woods Author: Geoff Lang
parent a2d97f13
...@@ -3041,31 +3041,24 @@ const char *Context::getRendererString() const ...@@ -3041,31 +3041,24 @@ const char *Context::getRendererString() const
return mRendererString; return mRendererString;
} }
void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, bool Context::clipBlitFramebufferCoordinates(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask) gl::Rectangle *outSourceRect, gl::Rectangle *outDestRect,
bool *outPartialCopy)
{ {
Framebuffer *readFramebuffer = getReadFramebuffer(); Framebuffer *readFramebuffer = getReadFramebuffer();
Framebuffer *drawFramebuffer = getDrawFramebuffer(); Framebuffer *drawFramebuffer = getDrawFramebuffer();
if (!readFramebuffer || readFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE || if (!readFramebuffer || readFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE ||
!drawFramebuffer || drawFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE) !drawFramebuffer || drawFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
{ {
return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION); return false;
}
if (drawFramebuffer->getSamples() != 0)
{
return gl::error(GL_INVALID_OPERATION);
} }
Renderbuffer *readColorBuffer = readFramebuffer->getReadColorbuffer(); Renderbuffer *readColorBuffer = readFramebuffer->getReadColorbuffer();
Renderbuffer *drawColorBuffer = drawFramebuffer->getFirstColorbuffer(); Renderbuffer *drawColorBuffer = drawFramebuffer->getFirstColorbuffer();
if (!readColorBuffer || !drawColorBuffer)
if (drawColorBuffer == NULL)
{ {
ERR("Draw buffers formats don't match, which is not supported in this implementation of BlitFramebufferANGLE"); return false;
return gl::error(GL_INVALID_OPERATION);
} }
int readBufferWidth = readColorBuffer->getWidth(); int readBufferWidth = readColorBuffer->getWidth();
...@@ -3073,8 +3066,8 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 ...@@ -3073,8 +3066,8 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
int drawBufferWidth = drawColorBuffer->getWidth(); int drawBufferWidth = drawColorBuffer->getWidth();
int drawBufferHeight = drawColorBuffer->getHeight(); int drawBufferHeight = drawColorBuffer->getHeight();
Rectangle sourceRect; gl::Rectangle sourceRect;
Rectangle destRect; gl::Rectangle destRect;
if (srcX0 < srcX1) if (srcX0 < srcX1)
{ {
...@@ -3101,7 +3094,7 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 ...@@ -3101,7 +3094,7 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
else else
{ {
sourceRect.height = srcY0 - srcY1; sourceRect.height = srcY0 - srcY1;
destRect.height = dstY0 - srcY1; destRect.height = dstY0 - dstY1;
sourceRect.y = srcY1; sourceRect.y = srcY1;
destRect.y = dstY1; destRect.y = dstY1;
} }
...@@ -3119,7 +3112,6 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 ...@@ -3119,7 +3112,6 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
destScissoredRect.width -= xDiff; destScissoredRect.width -= xDiff;
sourceScissoredRect.x += xDiff; sourceScissoredRect.x += xDiff;
sourceScissoredRect.width -= xDiff; sourceScissoredRect.width -= xDiff;
} }
if (destRect.x + destRect.width > mState.scissor.x + mState.scissor.width) if (destRect.x + destRect.width > mState.scissor.x + mState.scissor.width)
...@@ -3146,9 +3138,6 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 ...@@ -3146,9 +3138,6 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
} }
} }
bool blitRenderTarget = false;
bool blitDepthStencil = false;
Rectangle sourceTrimmedRect = sourceScissoredRect; Rectangle sourceTrimmedRect = sourceScissoredRect;
Rectangle destTrimmedRect = destScissoredRect; Rectangle destTrimmedRect = destScissoredRect;
...@@ -3218,111 +3207,52 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 ...@@ -3218,111 +3207,52 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
sourceTrimmedRect.height -= yDiff; sourceTrimmedRect.height -= yDiff;
} }
bool partialBufferCopy = false; *outSourceRect = sourceTrimmedRect;
if (sourceTrimmedRect.height < readBufferHeight || *outDestRect = destTrimmedRect;
sourceTrimmedRect.width < readBufferWidth ||
destTrimmedRect.height < drawBufferHeight ||
destTrimmedRect.width < drawBufferWidth ||
sourceTrimmedRect.y != 0 || destTrimmedRect.y != 0 || sourceTrimmedRect.x != 0 || destTrimmedRect.x != 0)
{
partialBufferCopy = true;
}
if (mask & GL_COLOR_BUFFER_BIT)
{
const GLenum readColorbufferType = readFramebuffer->getReadColorbufferType();
const bool validReadType = (readColorbufferType == GL_TEXTURE_2D) || (readColorbufferType == GL_RENDERBUFFER);
bool validDrawType = true;
bool validDrawFormat = true;
for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) *outPartialCopy = sourceTrimmedRect.height < readBufferHeight ||
{ sourceTrimmedRect.width < readBufferWidth ||
if (drawFramebuffer->isEnabledColorAttachment(colorAttachment)) destTrimmedRect.height < drawBufferHeight ||
{ destTrimmedRect.width < drawBufferWidth ||
if (drawFramebuffer->getColorbufferType(colorAttachment) != GL_TEXTURE_2D && sourceTrimmedRect.x != 0 || destTrimmedRect.x != 0 ||
drawFramebuffer->getColorbufferType(colorAttachment) != GL_RENDERBUFFER) sourceTrimmedRect.y != 0 || destTrimmedRect.y != 0;
{
validDrawType = false;
}
if (drawFramebuffer->getColorbuffer(colorAttachment)->getActualFormat() != readColorBuffer->getActualFormat()) return true;
{ }
validDrawFormat = false;
}
}
}
if (!validReadType || !validDrawType || !validDrawFormat) void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
{ GLbitfield mask, GLenum filter)
ERR("Color buffer format conversion in BlitFramebufferANGLE not supported by this implementation"); {
return gl::error(GL_INVALID_OPERATION); Framebuffer *readFramebuffer = getReadFramebuffer();
} Framebuffer *drawFramebuffer = getDrawFramebuffer();
if (partialBufferCopy && readFramebuffer->getSamples() != 0)
{
return gl::error(GL_INVALID_OPERATION);
}
bool blitRenderTarget = false;
bool blitDepthStencil = false;
if ((mask & GL_COLOR_BUFFER_BIT) && readFramebuffer->getReadColorbuffer() && drawFramebuffer->getFirstColorbuffer())
{
blitRenderTarget = true; blitRenderTarget = true;
} }
if ((mask & GL_STENCIL_BUFFER_BIT) && readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
if (mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
{ {
Renderbuffer *readDSBuffer = NULL; blitDepthStencil = true;
Renderbuffer *drawDSBuffer = NULL; }
if ((mask & GL_DEPTH_BUFFER_BIT) && readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
// We support OES_packed_depth_stencil, and do not support a separately attached depth and stencil buffer, so if we have {
// both a depth and stencil buffer, it will be the same buffer. blitDepthStencil = true;
}
if (mask & GL_DEPTH_BUFFER_BIT)
{
if (readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
{
if (readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType() ||
readFramebuffer->getDepthbuffer()->getActualFormat() != drawFramebuffer->getDepthbuffer()->getActualFormat())
{
return gl::error(GL_INVALID_OPERATION);
}
blitDepthStencil = true;
readDSBuffer = readFramebuffer->getDepthbuffer();
drawDSBuffer = drawFramebuffer->getDepthbuffer();
}
}
if (mask & GL_STENCIL_BUFFER_BIT)
{
if (readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
{
if (readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType() ||
readFramebuffer->getStencilbuffer()->getActualFormat() != drawFramebuffer->getStencilbuffer()->getActualFormat())
{
return gl::error(GL_INVALID_OPERATION);
}
blitDepthStencil = true;
readDSBuffer = readFramebuffer->getStencilbuffer();
drawDSBuffer = drawFramebuffer->getStencilbuffer();
}
}
if (partialBufferCopy)
{
ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
return gl::error(GL_INVALID_OPERATION); // only whole-buffer copies are permitted
}
if ((drawDSBuffer && drawDSBuffer->getSamples() != 0) || gl::Rectangle sourceClippedRect, destClippedRect;
(readDSBuffer && readDSBuffer->getSamples() != 0)) bool partialCopy;
{ if (!clipBlitFramebufferCoordinates(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
return gl::error(GL_INVALID_OPERATION); &sourceClippedRect, &destClippedRect, &partialCopy))
} {
return;
} }
if (blitRenderTarget || blitDepthStencil) if (blitRenderTarget || blitDepthStencil)
{ {
mRenderer->blitRect(readFramebuffer, sourceTrimmedRect, drawFramebuffer, destTrimmedRect, blitRenderTarget, blitDepthStencil); mRenderer->blitRect(readFramebuffer, sourceClippedRect, drawFramebuffer, destClippedRect,
blitRenderTarget, blitDepthStencil, filter);
} }
} }
......
...@@ -462,9 +462,13 @@ class Context ...@@ -462,9 +462,13 @@ class Context
float getTextureMaxAnisotropy() const; float getTextureMaxAnisotropy() const;
void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, bool clipBlitFramebufferCoordinates(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask); gl::Rectangle *outSourceRect, gl::Rectangle *outDestRect,
bool *outPartialCopy);
void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter);
void invalidateFrameBuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, void invalidateFrameBuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments,
GLint x, GLint y, GLsizei width, GLsizei height); GLint x, GLint y, GLsizei width, GLsizei height);
......
...@@ -221,7 +221,7 @@ class Renderer ...@@ -221,7 +221,7 @@ class Renderer
GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface2DArray *storage, GLint level) = 0; GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface2DArray *storage, GLint level) = 0;
virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
bool blitRenderTarget, bool blitDepthStencil) = 0; bool blitRenderTarget, bool blitDepthStencil, GLenum filter) = 0;
virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels) = 0; GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels) = 0;
......
...@@ -3004,7 +3004,7 @@ bool Renderer11::getRenderTargetResource(gl::Renderbuffer *colorbuffer, unsigned ...@@ -3004,7 +3004,7 @@ bool Renderer11::getRenderTargetResource(gl::Renderbuffer *colorbuffer, unsigned
} }
bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
bool blitRenderTarget, bool blitDepthStencil) bool blitRenderTarget, bool blitDepthStencil, GLenum filter)
{ {
if (blitRenderTarget) if (blitRenderTarget)
{ {
...@@ -3032,7 +3032,7 @@ bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &read ...@@ -3032,7 +3032,7 @@ bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &read
RenderTarget *drawRenderTarget = drawBuffer->getRenderTarget(); RenderTarget *drawRenderTarget = drawBuffer->getRenderTarget();
if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, false)) if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter))
{ {
return false; return false;
} }
...@@ -3060,7 +3060,7 @@ bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &read ...@@ -3060,7 +3060,7 @@ bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &read
RenderTarget *readRenderTarget = readBuffer->getDepthStencil(); RenderTarget *readRenderTarget = readBuffer->getDepthStencil();
RenderTarget *drawRenderTarget = drawBuffer->getDepthStencil(); RenderTarget *drawRenderTarget = drawBuffer->getDepthStencil();
if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, true)) if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter))
{ {
return false; return false;
} }
...@@ -3290,8 +3290,8 @@ void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResou ...@@ -3290,8 +3290,8 @@ void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResou
stagingTex = NULL; stagingTex = NULL;
} }
bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget, bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget,
RenderTarget *drawRenderTarget, bool wholeBufferCopy) RenderTarget *drawRenderTarget, GLenum filter)
{ {
ASSERT(readRect.width == drawRect.width && readRect.height == drawRect.height); ASSERT(readRect.width == drawRect.width && readRect.height == drawRect.height);
...@@ -3349,6 +3349,10 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R ...@@ -3349,6 +3349,10 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R
readBox.front = 0; readBox.front = 0;
readBox.back = 1; readBox.back = 1;
bool wholeBufferCopy = readRect.x == 0 && readRect.y == 0 &&
readRect.width == readRenderTarget->getWidth() &&
readRect.height == readRenderTarget->getHeight();
// D3D11 needs depth-stencil CopySubresourceRegions to have a NULL pSrcBox // D3D11 needs depth-stencil CopySubresourceRegions to have a NULL pSrcBox
// We also require complete framebuffer copies for depth-stencil blit. // We also require complete framebuffer copies for depth-stencil blit.
D3D11_BOX *pSrcBox = wholeBufferCopy ? NULL : &readBox; D3D11_BOX *pSrcBox = wholeBufferCopy ? NULL : &readBox;
......
...@@ -165,7 +165,7 @@ class Renderer11 : public Renderer ...@@ -165,7 +165,7 @@ class Renderer11 : public Renderer
GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface2DArray *storage, GLint level); GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface2DArray *storage, GLint level);
virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
bool blitRenderTarget, bool blitDepthStencil); bool blitRenderTarget, bool blitDepthStencil, GLenum filter);
virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels); GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels);
...@@ -222,7 +222,7 @@ class Renderer11 : public Renderer ...@@ -222,7 +222,7 @@ class Renderer11 : public Renderer
rx::Range getViewportBounds() const; rx::Range getViewportBounds() const;
bool blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget, bool blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget,
RenderTarget *drawRenderTarget, bool wholeBufferCopy); RenderTarget *drawRenderTarget, GLenum filter);
ID3D11Texture2D *resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource); ID3D11Texture2D *resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource);
HMODULE mD3d11Module; HMODULE mD3d11Module;
......
...@@ -2663,8 +2663,10 @@ bool Renderer9::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sou ...@@ -2663,8 +2663,10 @@ bool Renderer9::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sou
} }
bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle &readRect, gl::Framebuffer *drawFramebuffer, const gl::Rectangle &drawRect, bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle &readRect, gl::Framebuffer *drawFramebuffer, const gl::Rectangle &drawRect,
bool blitRenderTarget, bool blitDepthStencil) bool blitRenderTarget, bool blitDepthStencil, GLenum filter)
{ {
ASSERT(filter == GL_NEAREST);
endScene(); endScene();
if (blitRenderTarget) if (blitRenderTarget)
......
...@@ -183,7 +183,7 @@ class Renderer9 : public Renderer ...@@ -183,7 +183,7 @@ class Renderer9 : public Renderer
GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface2DArray *storage, GLint level); GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface2DArray *storage, GLint level);
virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
bool blitRenderTarget, bool blitDepthStencil); bool blitRenderTarget, bool blitDepthStencil, GLenum filter);
virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels); GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels);
......
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