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;
*outPartialCopy = sourceTrimmedRect.height < readBufferHeight ||
sourceTrimmedRect.width < readBufferWidth || sourceTrimmedRect.width < readBufferWidth ||
destTrimmedRect.height < drawBufferHeight || destTrimmedRect.height < drawBufferHeight ||
destTrimmedRect.width < drawBufferWidth || destTrimmedRect.width < drawBufferWidth ||
sourceTrimmedRect.y != 0 || destTrimmedRect.y != 0 || sourceTrimmedRect.x != 0 || destTrimmedRect.x != 0) sourceTrimmedRect.x != 0 || destTrimmedRect.x != 0 ||
{ sourceTrimmedRect.y != 0 || destTrimmedRect.y != 0;
partialBufferCopy = true;
}
if (mask & GL_COLOR_BUFFER_BIT) return true;
{ }
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++)
{
if (drawFramebuffer->isEnabledColorAttachment(colorAttachment))
{
if (drawFramebuffer->getColorbufferType(colorAttachment) != GL_TEXTURE_2D &&
drawFramebuffer->getColorbufferType(colorAttachment) != GL_RENDERBUFFER)
{
validDrawType = false;
}
if (drawFramebuffer->getColorbuffer(colorAttachment)->getActualFormat() != readColorBuffer->getActualFormat())
{
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) bool blitRenderTarget = false;
bool blitDepthStencil = false;
if ((mask & GL_COLOR_BUFFER_BIT) && readFramebuffer->getReadColorbuffer() && drawFramebuffer->getFirstColorbuffer())
{ {
return gl::error(GL_INVALID_OPERATION);
}
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;
Renderbuffer *drawDSBuffer = NULL;
// 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.
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; blitDepthStencil = true;
readDSBuffer = readFramebuffer->getDepthbuffer();
drawDSBuffer = drawFramebuffer->getDepthbuffer();
}
} }
if ((mask & GL_DEPTH_BUFFER_BIT) && readFramebuffer->getDepthbuffer() && 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; 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,
&sourceClippedRect, &destClippedRect, &partialCopy))
{ {
return gl::error(GL_INVALID_OPERATION); 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);
......
...@@ -1680,6 +1680,238 @@ bool validateInvalidateFramebufferParameters(gl::Context *context, GLenum target ...@@ -1680,6 +1680,238 @@ bool validateInvalidateFramebufferParameters(gl::Context *context, GLenum target
return true; return true;
} }
bool validateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask,
GLenum filter, bool fromAngleExtension)
{
switch (filter)
{
case GL_NEAREST:
break;
case GL_LINEAR:
if (fromAngleExtension)
{
return gl::error(GL_INVALID_ENUM, false);
}
break;
default:
return gl::error(GL_INVALID_ENUM, false);
}
if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
{
return gl::error(GL_INVALID_VALUE, false);
}
if (mask == 0)
{
// ES3.0 spec, section 4.3.2 specifies that a mask of zero is valid and no
// buffers are copied.
return false;
}
if (fromAngleExtension && (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0))
{
ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation.");
return gl::error(GL_INVALID_OPERATION, false);
}
// ES3.0 spec, section 4.3.2 states that linear filtering is only available for the
// color buffer, leaving only nearest being unfiltered from above
if ((mask & ~GL_COLOR_BUFFER_BIT) != 0 && filter != GL_NEAREST)
{
return gl::error(GL_INVALID_OPERATION, false);
}
if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
{
if (fromAngleExtension)
{
ERR("Blits with the same source and destination framebuffer are not supported by this "
"implementation.");
}
return gl::error(GL_INVALID_OPERATION, false);
}
gl::Framebuffer *readFramebuffer = context->getReadFramebuffer();
gl::Framebuffer *drawFramebuffer = context->getDrawFramebuffer();
if (!readFramebuffer || readFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE ||
!drawFramebuffer || drawFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
{
return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
}
if (drawFramebuffer->getSamples() != 0)
{
return gl::error(GL_INVALID_OPERATION, false);
}
gl::Rectangle sourceClippedRect, destClippedRect;
bool partialCopy;
if (!context->clipBlitFramebufferCoordinates(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
&sourceClippedRect, &destClippedRect, &partialCopy))
{
return gl::error(GL_INVALID_OPERATION, false);
}
bool sameBounds = srcX0 == dstX0 && srcY0 == dstY0 && srcX1 == dstX1 && srcY1 == dstY1;
GLuint clientVersion = context->getClientVersion();
if (mask & GL_COLOR_BUFFER_BIT)
{
gl::Renderbuffer *readColorBuffer = readFramebuffer->getReadColorbuffer();
gl::Renderbuffer *drawColorBuffer = drawFramebuffer->getFirstColorbuffer();
if (readColorBuffer && drawColorBuffer)
{
GLint readInternalFormat = readColorBuffer->getActualFormat();
GLint drawInternalFormat = drawColorBuffer->getActualFormat();
for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; i++)
{
if (drawFramebuffer->isEnabledColorAttachment(i))
{
GLint drawbufferAttachmentFormat = drawFramebuffer->getColorbuffer(i)->getActualFormat();
if (gl::IsNormalizedFixedPointFormat(readInternalFormat, clientVersion) &&
!gl::IsNormalizedFixedPointFormat(drawbufferAttachmentFormat, clientVersion))
{
return gl::error(GL_INVALID_OPERATION, false);
}
if (gl::IsUnsignedIntegerFormat(readInternalFormat, clientVersion) &&
!gl::IsUnsignedIntegerFormat(drawbufferAttachmentFormat, clientVersion))
{
return gl::error(GL_INVALID_OPERATION, false);
}
if (gl::IsSignedIntegerFormat(readInternalFormat, clientVersion) &&
!gl::IsSignedIntegerFormat(drawbufferAttachmentFormat, clientVersion))
{
return gl::error(GL_INVALID_OPERATION, false);
}
if (readColorBuffer->getSamples() > 0 && (readInternalFormat != drawbufferAttachmentFormat || !sameBounds))
{
return gl::error(GL_INVALID_OPERATION, false);
}
}
}
if (gl::IsIntegerFormat(readInternalFormat, clientVersion) && filter == GL_LINEAR)
{
return gl::error(GL_INVALID_OPERATION, false);
}
if (fromAngleExtension)
{
const GLenum readColorbufferType = readFramebuffer->getReadColorbufferType();
if (readColorbufferType != GL_TEXTURE_2D && readColorbufferType != GL_RENDERBUFFER)
{
return gl::error(GL_INVALID_OPERATION, false);
}
for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
{
if (drawFramebuffer->isEnabledColorAttachment(colorAttachment))
{
if (drawFramebuffer->getColorbufferType(colorAttachment) != GL_TEXTURE_2D &&
drawFramebuffer->getColorbufferType(colorAttachment) != GL_RENDERBUFFER)
{
return gl::error(GL_INVALID_OPERATION, false);
}
if (drawFramebuffer->getColorbuffer(colorAttachment)->getActualFormat() != readColorBuffer->getActualFormat())
{
return gl::error(GL_INVALID_OPERATION, false);
}
}
}
if (partialCopy && readFramebuffer->getSamples() != 0)
{
return gl::error(GL_INVALID_OPERATION, false);
}
}
}
}
if (mask & GL_DEPTH_BUFFER_BIT)
{
gl::Renderbuffer *readDepthBuffer = readFramebuffer->getDepthbuffer();
gl::Renderbuffer *drawDepthBuffer = drawFramebuffer->getDepthbuffer();
if (readDepthBuffer && drawDepthBuffer)
{
if (readDepthBuffer->getActualFormat() != drawDepthBuffer->getActualFormat())
{
return gl::error(GL_INVALID_OPERATION, false);
}
if (readDepthBuffer->getSamples() > 0 && !sameBounds)
{
return gl::error(GL_INVALID_OPERATION, false);
}
if (fromAngleExtension)
{
if (partialCopy)
{
ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
return gl::error(GL_INVALID_OPERATION, false); // only whole-buffer copies are permitted
}
if (readDepthBuffer->getSamples() != 0 || drawDepthBuffer->getSamples() != 0)
{
return gl::error(GL_INVALID_OPERATION, false);
}
}
}
}
if (mask & GL_STENCIL_BUFFER_BIT)
{
gl::Renderbuffer *readStencilBuffer = readFramebuffer->getStencilbuffer();
gl::Renderbuffer *drawStencilBuffer = drawFramebuffer->getStencilbuffer();
if (fromAngleExtension && partialCopy)
{
ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
return gl::error(GL_INVALID_OPERATION, false); // only whole-buffer copies are permitted
}
if (readStencilBuffer && drawStencilBuffer)
{
if (readStencilBuffer->getActualFormat() != drawStencilBuffer->getActualFormat())
{
return gl::error(GL_INVALID_OPERATION, false);
}
if (readStencilBuffer->getSamples() > 0 && !sameBounds)
{
return gl::error(GL_INVALID_OPERATION, false);
}
if (fromAngleExtension)
{
if (partialCopy)
{
ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
return gl::error(GL_INVALID_OPERATION, false); // only whole-buffer copies are permitted
}
if (readStencilBuffer->getSamples() != 0 || drawStencilBuffer->getSamples() != 0)
{
return gl::error(GL_INVALID_OPERATION, false);
}
}
}
}
return true;
}
extern "C" extern "C"
{ {
...@@ -8796,7 +9028,15 @@ void __stdcall glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint sr ...@@ -8796,7 +9028,15 @@ void __stdcall glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint sr
return gl::error(GL_INVALID_OPERATION); return gl::error(GL_INVALID_OPERATION);
} }
glBlitFramebufferANGLE(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); if (!validateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1,
dstX0, dstY0, dstX1, dstY1, mask, filter,
false))
{
return;
}
context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
mask, filter);
} }
} }
catch(std::bad_alloc&) catch(std::bad_alloc&)
...@@ -11300,36 +11540,19 @@ void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLi ...@@ -11300,36 +11540,19 @@ void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLi
try try
{ {
switch (filter)
{
case GL_NEAREST:
break;
default:
return gl::error(GL_INVALID_ENUM);
}
if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
{
return gl::error(GL_INVALID_VALUE);
}
if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
{
ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
return gl::error(GL_INVALID_OPERATION);
}
gl::Context *context = gl::getNonLostContext(); gl::Context *context = gl::getNonLostContext();
if (context) if (context)
{ {
if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle()) if (!validateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1,
dstX0, dstY0, dstX1, dstY1, mask, filter,
true))
{ {
ERR("Blits with the same source and destination framebuffer are not supported by this implementation."); return;
return gl::error(GL_INVALID_OPERATION);
} }
context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask); context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
mask, filter);
} }
} }
catch(std::bad_alloc&) catch(std::bad_alloc&)
......
...@@ -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;
} }
...@@ -3291,7 +3291,7 @@ void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResou ...@@ -3291,7 +3291,7 @@ void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResou
} }
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