Commit 125deab6 by Geoff Lang

Moved the clipping of blit rectangles to bounds or scissors into the Renderers…

Moved the clipping of blit rectangles to bounds or scissors into the Renderers since rounding to integers can cause errors when stretching in ES3. TRAC #23650 Author: Geoff Lang Signed-off-by: Jamie Madill Signed-off-by: Shannon Woods
parent c832516a
......@@ -254,6 +254,7 @@
'libGLESv2/constants.h',
'libGLESv2/Context.cpp',
'libGLESv2/Context.h',
'libGLESv2/angletypes.cpp',
'libGLESv2/angletypes.h',
'libGLESv2/Fence.cpp',
'libGLESv2/Fence.h',
......
......@@ -3613,185 +3613,6 @@ const char *Context::getRendererString() const
return mRendererString;
}
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 false;
}
Renderbuffer *readColorBuffer = readFramebuffer->getReadColorbuffer();
Renderbuffer *drawColorBuffer = drawFramebuffer->getFirstColorbuffer();
if (!readColorBuffer || !drawColorBuffer)
{
return false;
}
int readBufferWidth = readColorBuffer->getWidth();
int readBufferHeight = readColorBuffer->getHeight();
int drawBufferWidth = drawColorBuffer->getWidth();
int drawBufferHeight = drawColorBuffer->getHeight();
gl::Rectangle sourceRect;
gl::Rectangle destRect;
if (srcX0 < srcX1)
{
sourceRect.x = srcX0;
destRect.x = dstX0;
sourceRect.width = srcX1 - srcX0;
destRect.width = dstX1 - dstX0;
}
else
{
sourceRect.x = srcX1;
destRect.x = dstX1;
sourceRect.width = srcX0 - srcX1;
destRect.width = dstX0 - dstX1;
}
if (srcY0 < srcY1)
{
sourceRect.height = srcY1 - srcY0;
destRect.height = dstY1 - dstY0;
sourceRect.y = srcY0;
destRect.y = dstY0;
}
else
{
sourceRect.height = srcY0 - srcY1;
destRect.height = dstY0 - dstY1;
sourceRect.y = srcY1;
destRect.y = dstY1;
}
Rectangle sourceScissoredRect = sourceRect;
Rectangle destScissoredRect = destRect;
if (mState.scissorTest)
{
// Only write to parts of the destination framebuffer which pass the scissor test.
if (destRect.x < mState.scissor.x)
{
int xDiff = mState.scissor.x - destRect.x;
destScissoredRect.x = mState.scissor.x;
destScissoredRect.width -= xDiff;
sourceScissoredRect.x += xDiff;
sourceScissoredRect.width -= xDiff;
}
if (destRect.x + destRect.width > mState.scissor.x + mState.scissor.width)
{
int xDiff = (destRect.x + destRect.width) - (mState.scissor.x + mState.scissor.width);
destScissoredRect.width -= xDiff;
sourceScissoredRect.width -= xDiff;
}
if (destRect.y < mState.scissor.y)
{
int yDiff = mState.scissor.y - destRect.y;
destScissoredRect.y = mState.scissor.y;
destScissoredRect.height -= yDiff;
sourceScissoredRect.y += yDiff;
sourceScissoredRect.height -= yDiff;
}
if (destRect.y + destRect.height > mState.scissor.y + mState.scissor.height)
{
int yDiff = (destRect.y + destRect.height) - (mState.scissor.y + mState.scissor.height);
destScissoredRect.height -= yDiff;
sourceScissoredRect.height -= yDiff;
}
}
Rectangle sourceTrimmedRect = sourceScissoredRect;
Rectangle destTrimmedRect = destScissoredRect;
// The source & destination rectangles also may need to be trimmed if they fall out of the bounds of
// the actual draw and read surfaces.
if (sourceTrimmedRect.x < 0)
{
int xDiff = 0 - sourceTrimmedRect.x;
sourceTrimmedRect.x = 0;
sourceTrimmedRect.width -= xDiff;
destTrimmedRect.x += xDiff;
destTrimmedRect.width -= xDiff;
}
if (sourceTrimmedRect.x + sourceTrimmedRect.width > readBufferWidth)
{
int xDiff = (sourceTrimmedRect.x + sourceTrimmedRect.width) - readBufferWidth;
sourceTrimmedRect.width -= xDiff;
destTrimmedRect.width -= xDiff;
}
if (sourceTrimmedRect.y < 0)
{
int yDiff = 0 - sourceTrimmedRect.y;
sourceTrimmedRect.y = 0;
sourceTrimmedRect.height -= yDiff;
destTrimmedRect.y += yDiff;
destTrimmedRect.height -= yDiff;
}
if (sourceTrimmedRect.y + sourceTrimmedRect.height > readBufferHeight)
{
int yDiff = (sourceTrimmedRect.y + sourceTrimmedRect.height) - readBufferHeight;
sourceTrimmedRect.height -= yDiff;
destTrimmedRect.height -= yDiff;
}
if (destTrimmedRect.x < 0)
{
int xDiff = 0 - destTrimmedRect.x;
destTrimmedRect.x = 0;
destTrimmedRect.width -= xDiff;
sourceTrimmedRect.x += xDiff;
sourceTrimmedRect.width -= xDiff;
}
if (destTrimmedRect.x + destTrimmedRect.width > drawBufferWidth)
{
int xDiff = (destTrimmedRect.x + destTrimmedRect.width) - drawBufferWidth;
destTrimmedRect.width -= xDiff;
sourceTrimmedRect.width -= xDiff;
}
if (destTrimmedRect.y < 0)
{
int yDiff = 0 - destTrimmedRect.y;
destTrimmedRect.y = 0;
destTrimmedRect.height -= yDiff;
sourceTrimmedRect.y += yDiff;
sourceTrimmedRect.height -= yDiff;
}
if (destTrimmedRect.y + destTrimmedRect.height > drawBufferHeight)
{
int yDiff = (destTrimmedRect.y + destTrimmedRect.height) - drawBufferHeight;
destTrimmedRect.height -= yDiff;
sourceTrimmedRect.height -= yDiff;
}
*outSourceRect = sourceTrimmedRect;
*outDestRect = destTrimmedRect;
*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;
return true;
}
void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter)
{
......@@ -3814,17 +3635,12 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
blitDepth = true;
}
gl::Rectangle sourceClippedRect, destClippedRect;
bool partialCopy;
if (!clipBlitFramebufferCoordinates(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
&sourceClippedRect, &destClippedRect, &partialCopy))
{
return;
}
gl::Rectangle srcRect(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
gl::Rectangle dstRect(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
if (blitRenderTarget || blitDepth || blitStencil)
{
mRenderer->blitRect(readFramebuffer, sourceClippedRect, drawFramebuffer, destClippedRect,
const gl::Rectangle *scissor = mState.scissorTest ? &mState.scissor : NULL;
mRenderer->blitRect(readFramebuffer, srcRect, drawFramebuffer, dstRect, scissor,
blitRenderTarget, blitDepth, blitStencil, filter);
}
}
......
......@@ -432,11 +432,6 @@ class Context
float getTextureMaxAnisotropy() const;
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);
......
#include "precompiled.h"
//
// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// angletypes.h : Defines a variety of structures and enum types that are used throughout libGLESv2
#include "libGLESv2/angletypes.h"
namespace gl
{
static void MinMax(int a, int b, int *minimum, int *maximum)
{
if (a < b)
{
*minimum = a;
*maximum = b;
}
else
{
*minimum = b;
*maximum = a;
}
}
bool ClipRectangle(const Rectangle &source, const Rectangle &clip, Rectangle *intersection)
{
int minSourceX, maxSourceX, minSourceY, maxSourceY;
MinMax(source.x, source.x + source.width, &minSourceX, &maxSourceX);
MinMax(source.y, source.y + source.height, &minSourceY, &maxSourceY);
int minClipX, maxClipX, minClipY, maxClipY;
MinMax(clip.x, clip.x + clip.width, &minClipX, &maxClipX);
MinMax(clip.y, clip.y + clip.height, &minClipY, &maxClipY);
if (minSourceX >= maxClipX || maxSourceX <= minClipX || minSourceY >= maxClipY || maxSourceY <= minClipY)
{
if (intersection)
{
intersection->x = minSourceX;
intersection->y = maxSourceY;
intersection->width = maxSourceX - minSourceX;
intersection->height = maxSourceY - minSourceY;
}
return false;
}
else
{
if (intersection)
{
intersection->x = std::max(minSourceX, minClipX);
intersection->y = std::max(minSourceY, minClipY);
intersection->width = std::min(maxSourceX, maxClipX) - std::max(minSourceX, minClipX);
intersection->height = std::min(maxSourceY, maxClipY) - std::max(minSourceY, minClipY);
}
return true;
}
}
}
......@@ -58,6 +58,8 @@ struct Rectangle
Rectangle(int x_in, int y_in, int width_in, int height_in) : x(x_in), y(y_in), width(width_in), height(height_in) { }
};
bool ClipRectangle(const Rectangle &source, const Rectangle &clip, Rectangle *intersection);
struct Box
{
int x;
......
......@@ -241,6 +241,7 @@ copy "$(OutDir)libGLESv2.lib" "$(ProjectDir)..\..\lib\$(Configuration)\"
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="angletypes.cpp" />
<ClCompile Include="Buffer.cpp" />
<ClCompile Include="Context.cpp" />
<ClCompile Include="..\common\debug.cpp">
......
......@@ -263,6 +263,9 @@
<ClCompile Include="renderer\Clear11.cpp">
<Filter>Source Files\Renderer11</Filter>
</ClCompile>
<ClCompile Include="angletypes.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="BinaryStream.h">
......@@ -704,4 +707,4 @@
<ItemGroup>
<ResourceCompile Include="libGLESv2.rc" />
</ItemGroup>
</Project>
\ No newline at end of file
</Project>
......@@ -30,16 +30,19 @@ class Blit11
bool copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize,
ID3D11RenderTargetView *dest, const gl::Box &destArea, const gl::Extents &destSize,
GLenum destFormat, GLenum filter);
const gl::Rectangle *scissor, GLenum destFormat, GLenum filter);
bool copyStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize);
ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
const gl::Rectangle *scissor);
bool copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize,
ID3D11DepthStencilView *dest, const gl::Box &destArea, const gl::Extents &destSize);
ID3D11DepthStencilView *dest, const gl::Box &destArea, const gl::Extents &destSize,
const gl::Rectangle *scissor);
bool copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize);
ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
const gl::Rectangle *scissor);
private:
rx::Renderer11 *mRenderer;
......@@ -53,7 +56,7 @@ class Blit11
bool copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
bool stencilOnly);
const gl::Rectangle *scissor, bool stencilOnly);
static bool compareBlitParameters(const BlitParameters &a, const BlitParameters &b);
......@@ -84,7 +87,8 @@ class Blit11
ID3D11Buffer *mVertexBuffer;
ID3D11SamplerState *mPointSampler;
ID3D11SamplerState *mLinearSampler;
ID3D11RasterizerState *mRasterizerState;
ID3D11RasterizerState *mScissorEnabledRasterizerState;
ID3D11RasterizerState *mScissorDisabledRasterizerState;
ID3D11DepthStencilState *mDepthStencilState;
ID3D11InputLayout *mQuad2DIL;
......
......@@ -225,7 +225,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 blitDepth, bool blitStencil, GLenum filter) = 0;
const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, 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;
......
......@@ -169,7 +169,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 blitDepth, bool blitStencil, GLenum filter);
const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, 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);
......@@ -225,7 +225,8 @@ class Renderer11 : public Renderer
rx::Range getViewportBounds() const;
bool blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget,
RenderTarget *drawRenderTarget, GLenum filter, bool colorBlit, bool depthBlit, bool stencilBlit);
RenderTarget *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor,
bool colorBlit, bool depthBlit, bool stencilBlit);
ID3D11Texture2D *resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource);
HMODULE mD3d11Module;
......
......@@ -2715,7 +2715,7 @@ 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 blitDepth, bool blitStencil, GLenum filter)
const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter)
{
ASSERT(filter == GL_NEAREST);
......@@ -2754,6 +2754,9 @@ bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle &
return gl::error(GL_OUT_OF_MEMORY, false);
}
gl::Extents srcSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1);
gl::Extents dstSize(drawRenderTarget->getWidth(), drawRenderTarget->getHeight(), 1);
RECT srcRect;
srcRect.left = readRect.x;
srcRect.right = readRect.x + readRect.width;
......@@ -2766,6 +2769,75 @@ bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle &
dstRect.top = drawRect.y;
dstRect.bottom = drawRect.y + drawRect.height;
// Clip the rectangles to the scissor rectangle
if (scissor)
{
if (dstRect.left < scissor->x)
{
srcRect.left += (scissor->x - dstRect.left);
dstRect.left = scissor->x;
}
if (dstRect.top < scissor->y)
{
srcRect.top += (scissor->y - dstRect.top);
dstRect.top = scissor->y;
}
if (dstRect.right > scissor->x + scissor->width)
{
srcRect.right -= (dstRect.right - (scissor->x + scissor->width));
dstRect.right = scissor->x + scissor->width;
}
if (dstRect.bottom > scissor->y + scissor->height)
{
srcRect.bottom -= (dstRect.bottom - (scissor->y + scissor->height));
dstRect.bottom = scissor->y + scissor->height;
}
}
// Clip the rectangles to the destination size
if (dstRect.left < 0)
{
srcRect.left += -dstRect.left;
dstRect.left = 0;
}
if (dstRect.right > dstSize.width)
{
srcRect.right -= (dstRect.right - dstSize.width);
dstRect.right = dstSize.width;
}
if (dstRect.top < 0)
{
srcRect.top += -dstRect.top;
dstRect.top = 0;
}
if (dstRect.bottom > dstSize.height)
{
srcRect.bottom -= (dstRect.bottom - dstSize.height);
dstRect.bottom = dstSize.height;
}
// Clip the rectangles to the source size
if (srcRect.left < 0)
{
dstRect.left += -srcRect.left;
srcRect.left = 0;
}
if (srcRect.right > srcSize.width)
{
dstRect.right -= (srcRect.right - srcSize.width);
srcRect.right = srcSize.width;
}
if (srcRect.top < 0)
{
dstRect.top += -srcRect.top;
srcRect.top = 0;
}
if (srcRect.bottom > srcSize.height)
{
dstRect.bottom -= (srcRect.bottom - srcSize.height);
srcRect.bottom = srcSize.height;
}
HRESULT result = mDevice->StretchRect(readSurface, &srcRect, drawSurface, &dstRect, D3DTEXF_NONE);
SafeRelease(readSurface);
......
......@@ -186,7 +186,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 blitDepth, bool blitStencil, GLenum filter);
const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, 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);
......
......@@ -140,7 +140,8 @@ bool TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, unsign
Blit11 *blitter = mRenderer->getBlitter();
return blitter->copyDepthStencil(srcTexture, sourceSubresource, copyArea, texSize,
dstTexture, dstSubresource, copyArea, texSize);
dstTexture, dstSubresource, copyArea, texSize,
NULL);
}
else
{
......@@ -180,7 +181,7 @@ void TextureStorage11::generateMipmapLayer(RenderTarget11 *source, RenderTarget1
Blit11 *blitter = mRenderer->getBlitter();
blitter->copyTexture(sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize,
blitter->copyTexture(sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize, NULL,
gl::GetFormat(source->getInternalFormat(), mRenderer->getCurrentClientVersion()),
GL_LINEAR);
}
......
......@@ -98,6 +98,31 @@ bool ValidateRenderbufferStorageParameters(const gl::Context *context, GLenum ta
return true;
}
static bool IsPartialBlit(gl::Context *context, gl::Renderbuffer *readBuffer, gl::Renderbuffer *writeBuffer,
GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1)
{
if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 ||
dstX1 != writeBuffer->getWidth() || dstY1 != writeBuffer->getHeight() ||
srcX1 != readBuffer->getWidth() || srcY1 != readBuffer->getHeight())
{
return true;
}
else if (context->isScissorTestEnabled())
{
int scissorX, scissorY, scissorWidth, scissorHeight;
context->getScissorParams(&scissorX, &scissorY, &scissorWidth, &scissorHeight);
return scissorX > 0 || scissorY > 0 ||
scissorWidth < writeBuffer->getWidth() ||
scissorHeight < writeBuffer->getHeight();
}
else
{
return false;
}
}
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)
......@@ -164,14 +189,6 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
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();
......@@ -249,8 +266,9 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
}
}
}
if (partialCopy && readFramebuffer->getSamples() != 0)
if (readFramebuffer->getSamples() != 0 && IsPartialBlit(context, readColorBuffer, drawColorBuffer,
srcX0, srcY0, srcX1, srcY1,
dstX0, dstY0, dstX1, dstY1))
{
return gl::error(GL_INVALID_OPERATION, false);
}
......@@ -277,7 +295,8 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
if (fromAngleExtension)
{
if (partialCopy)
if (IsPartialBlit(context, readDepthBuffer, drawDepthBuffer,
srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
{
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
......@@ -296,12 +315,6 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
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())
......@@ -316,7 +329,8 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
if (fromAngleExtension)
{
if (partialCopy)
if (IsPartialBlit(context, readStencilBuffer, drawStencilBuffer,
srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
{
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
......
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