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
return mRendererString;
}
void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask)
bool Context::clipBlitFramebufferCoordinates(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
gl::Rectangle *outSourceRect, gl::Rectangle *outDestRect,
bool *outPartialCopy)
{
Framebuffer *readFramebuffer = getReadFramebuffer();
Framebuffer *drawFramebuffer = getDrawFramebuffer();
if (!readFramebuffer || readFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE ||
!drawFramebuffer || drawFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
{
return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION);
}
if (drawFramebuffer->getSamples() != 0)
{
return gl::error(GL_INVALID_OPERATION);
return false;
}
Renderbuffer *readColorBuffer = readFramebuffer->getReadColorbuffer();
Renderbuffer *drawColorBuffer = drawFramebuffer->getFirstColorbuffer();
if (drawColorBuffer == NULL)
if (!readColorBuffer || !drawColorBuffer)
{
ERR("Draw buffers formats don't match, which is not supported in this implementation of BlitFramebufferANGLE");
return gl::error(GL_INVALID_OPERATION);
return false;
}
int readBufferWidth = readColorBuffer->getWidth();
......@@ -3073,8 +3066,8 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
int drawBufferWidth = drawColorBuffer->getWidth();
int drawBufferHeight = drawColorBuffer->getHeight();
Rectangle sourceRect;
Rectangle destRect;
gl::Rectangle sourceRect;
gl::Rectangle destRect;
if (srcX0 < srcX1)
{
......@@ -3101,7 +3094,7 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
else
{
sourceRect.height = srcY0 - srcY1;
destRect.height = dstY0 - srcY1;
destRect.height = dstY0 - dstY1;
sourceRect.y = srcY1;
destRect.y = dstY1;
}
......@@ -3119,7 +3112,6 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
destScissoredRect.width -= xDiff;
sourceScissoredRect.x += xDiff;
sourceScissoredRect.width -= xDiff;
}
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
}
}
bool blitRenderTarget = false;
bool blitDepthStencil = false;
Rectangle sourceTrimmedRect = sourceScissoredRect;
Rectangle destTrimmedRect = destScissoredRect;
......@@ -3218,111 +3207,52 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
sourceTrimmedRect.height -= yDiff;
}
bool partialBufferCopy = false;
if (sourceTrimmedRect.height < readBufferHeight ||
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;
*outSourceRect = sourceTrimmedRect;
*outDestRect = destTrimmedRect;
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;
}
*outPartialCopy = sourceTrimmedRect.height < readBufferHeight ||
sourceTrimmedRect.width < readBufferWidth ||
destTrimmedRect.height < drawBufferHeight ||
destTrimmedRect.width < drawBufferWidth ||
sourceTrimmedRect.x != 0 || destTrimmedRect.x != 0 ||
sourceTrimmedRect.y != 0 || destTrimmedRect.y != 0;
if (drawFramebuffer->getColorbuffer(colorAttachment)->getActualFormat() != readColorBuffer->getActualFormat())
{
validDrawFormat = false;
}
}
}
return true;
}
if (!validReadType || !validDrawType || !validDrawFormat)
{
ERR("Color buffer format conversion in BlitFramebufferANGLE not supported by this implementation");
return gl::error(GL_INVALID_OPERATION);
}
if (partialBufferCopy && readFramebuffer->getSamples() != 0)
{
return gl::error(GL_INVALID_OPERATION);
}
void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter)
{
Framebuffer *readFramebuffer = getReadFramebuffer();
Framebuffer *drawFramebuffer = getDrawFramebuffer();
bool blitRenderTarget = false;
bool blitDepthStencil = false;
if ((mask & GL_COLOR_BUFFER_BIT) && readFramebuffer->getReadColorbuffer() && drawFramebuffer->getFirstColorbuffer())
{
blitRenderTarget = true;
}
if (mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
if ((mask & GL_STENCIL_BUFFER_BIT) && readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
{
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;
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
}
blitDepthStencil = true;
}
if ((mask & GL_DEPTH_BUFFER_BIT) && readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
{
blitDepthStencil = true;
}
if ((drawDSBuffer && drawDSBuffer->getSamples() != 0) ||
(readDSBuffer && readDSBuffer->getSamples() != 0))
{
return gl::error(GL_INVALID_OPERATION);
}
gl::Rectangle sourceClippedRect, destClippedRect;
bool partialCopy;
if (!clipBlitFramebufferCoordinates(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
&sourceClippedRect, &destClippedRect, &partialCopy))
{
return;
}
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
float getTextureMaxAnisotropy() const;
void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask);
bool clipBlitFramebufferCoordinates(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
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,
GLint x, GLint y, GLsizei width, GLsizei height);
......
......@@ -1680,6 +1680,238 @@ bool validateInvalidateFramebufferParameters(gl::Context *context, GLenum target
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"
{
......@@ -8796,7 +9028,15 @@ void __stdcall glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint sr
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&)
......@@ -11300,36 +11540,19 @@ void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLi
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();
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 gl::error(GL_INVALID_OPERATION);
return;
}
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&)
......
......@@ -221,7 +221,7 @@ class Renderer
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,
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,
GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels) = 0;
......
......@@ -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 blitRenderTarget, bool blitDepthStencil)
bool blitRenderTarget, bool blitDepthStencil, GLenum filter)
{
if (blitRenderTarget)
{
......@@ -3032,7 +3032,7 @@ bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &read
RenderTarget *drawRenderTarget = drawBuffer->getRenderTarget();
if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, false))
if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter))
{
return false;
}
......@@ -3060,7 +3060,7 @@ bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &read
RenderTarget *readRenderTarget = readBuffer->getDepthStencil();
RenderTarget *drawRenderTarget = drawBuffer->getDepthStencil();
if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, true))
if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter))
{
return false;
}
......@@ -3290,8 +3290,8 @@ void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResou
stagingTex = NULL;
}
bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget,
RenderTarget *drawRenderTarget, bool wholeBufferCopy)
bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget,
RenderTarget *drawRenderTarget, GLenum filter)
{
ASSERT(readRect.width == drawRect.width && readRect.height == drawRect.height);
......@@ -3349,6 +3349,10 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R
readBox.front = 0;
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
// We also require complete framebuffer copies for depth-stencil blit.
D3D11_BOX *pSrcBox = wholeBufferCopy ? NULL : &readBox;
......
......@@ -165,7 +165,7 @@ class Renderer11 : public Renderer
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,
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,
GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels);
......@@ -222,7 +222,7 @@ class Renderer11 : public Renderer
rx::Range getViewportBounds() const;
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);
HMODULE mD3d11Module;
......
......@@ -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 blitRenderTarget, bool blitDepthStencil)
bool blitRenderTarget, bool blitDepthStencil, GLenum filter)
{
ASSERT(filter == GL_NEAREST);
endScene();
if (blitRenderTarget)
......
......@@ -183,7 +183,7 @@ class Renderer9 : public Renderer
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,
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,
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