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 @@ ...@@ -254,6 +254,7 @@
'libGLESv2/constants.h', 'libGLESv2/constants.h',
'libGLESv2/Context.cpp', 'libGLESv2/Context.cpp',
'libGLESv2/Context.h', 'libGLESv2/Context.h',
'libGLESv2/angletypes.cpp',
'libGLESv2/angletypes.h', 'libGLESv2/angletypes.h',
'libGLESv2/Fence.cpp', 'libGLESv2/Fence.cpp',
'libGLESv2/Fence.h', 'libGLESv2/Fence.h',
......
...@@ -3613,185 +3613,6 @@ const char *Context::getRendererString() const ...@@ -3613,185 +3613,6 @@ const char *Context::getRendererString() const
return mRendererString; 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, void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter) GLbitfield mask, GLenum filter)
{ {
...@@ -3814,17 +3635,12 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 ...@@ -3814,17 +3635,12 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
blitDepth = true; blitDepth = true;
} }
gl::Rectangle sourceClippedRect, destClippedRect; gl::Rectangle srcRect(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
bool partialCopy; gl::Rectangle dstRect(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
if (!clipBlitFramebufferCoordinates(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
&sourceClippedRect, &destClippedRect, &partialCopy))
{
return;
}
if (blitRenderTarget || blitDepth || blitStencil) 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); blitRenderTarget, blitDepth, blitStencil, filter);
} }
} }
......
...@@ -432,11 +432,6 @@ class Context ...@@ -432,11 +432,6 @@ class Context
float getTextureMaxAnisotropy() const; 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, void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter); 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 ...@@ -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) { } 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 struct Box
{ {
int x; int x;
......
...@@ -241,6 +241,7 @@ copy "$(OutDir)libGLESv2.lib" "$(ProjectDir)..\..\lib\$(Configuration)\" ...@@ -241,6 +241,7 @@ copy "$(OutDir)libGLESv2.lib" "$(ProjectDir)..\..\lib\$(Configuration)\"
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
</ClCompile> </ClCompile>
<ClCompile Include="angletypes.cpp" />
<ClCompile Include="Buffer.cpp" /> <ClCompile Include="Buffer.cpp" />
<ClCompile Include="Context.cpp" /> <ClCompile Include="Context.cpp" />
<ClCompile Include="..\common\debug.cpp"> <ClCompile Include="..\common\debug.cpp">
......
...@@ -263,6 +263,9 @@ ...@@ -263,6 +263,9 @@
<ClCompile Include="renderer\Clear11.cpp"> <ClCompile Include="renderer\Clear11.cpp">
<Filter>Source Files\Renderer11</Filter> <Filter>Source Files\Renderer11</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="angletypes.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="BinaryStream.h"> <ClInclude Include="BinaryStream.h">
...@@ -704,4 +707,4 @@ ...@@ -704,4 +707,4 @@
<ItemGroup> <ItemGroup>
<ResourceCompile Include="libGLESv2.rc" /> <ResourceCompile Include="libGLESv2.rc" />
</ItemGroup> </ItemGroup>
</Project> </Project>
\ No newline at end of file
...@@ -30,16 +30,19 @@ class Blit11 ...@@ -30,16 +30,19 @@ class Blit11
bool copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize, bool copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize,
ID3D11RenderTargetView *dest, const gl::Box &destArea, const gl::Extents &destSize, 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, 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, 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, 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: private:
rx::Renderer11 *mRenderer; rx::Renderer11 *mRenderer;
...@@ -53,7 +56,7 @@ class Blit11 ...@@ -53,7 +56,7 @@ class Blit11
bool copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, 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,
bool stencilOnly); const gl::Rectangle *scissor, bool stencilOnly);
static bool compareBlitParameters(const BlitParameters &a, const BlitParameters &b); static bool compareBlitParameters(const BlitParameters &a, const BlitParameters &b);
...@@ -84,7 +87,8 @@ class Blit11 ...@@ -84,7 +87,8 @@ class Blit11
ID3D11Buffer *mVertexBuffer; ID3D11Buffer *mVertexBuffer;
ID3D11SamplerState *mPointSampler; ID3D11SamplerState *mPointSampler;
ID3D11SamplerState *mLinearSampler; ID3D11SamplerState *mLinearSampler;
ID3D11RasterizerState *mRasterizerState; ID3D11RasterizerState *mScissorEnabledRasterizerState;
ID3D11RasterizerState *mScissorDisabledRasterizerState;
ID3D11DepthStencilState *mDepthStencilState; ID3D11DepthStencilState *mDepthStencilState;
ID3D11InputLayout *mQuad2DIL; ID3D11InputLayout *mQuad2DIL;
......
...@@ -225,7 +225,7 @@ class Renderer ...@@ -225,7 +225,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 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, 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;
......
...@@ -169,7 +169,7 @@ class Renderer11 : public Renderer ...@@ -169,7 +169,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 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, 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);
...@@ -225,7 +225,8 @@ class Renderer11 : public Renderer ...@@ -225,7 +225,8 @@ 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, 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); ID3D11Texture2D *resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource);
HMODULE mD3d11Module; HMODULE mD3d11Module;
......
...@@ -2715,7 +2715,7 @@ bool Renderer9::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sou ...@@ -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 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); ASSERT(filter == GL_NEAREST);
...@@ -2754,6 +2754,9 @@ bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle & ...@@ -2754,6 +2754,9 @@ bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle &
return gl::error(GL_OUT_OF_MEMORY, false); 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; RECT srcRect;
srcRect.left = readRect.x; srcRect.left = readRect.x;
srcRect.right = readRect.x + readRect.width; srcRect.right = readRect.x + readRect.width;
...@@ -2766,6 +2769,75 @@ bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle & ...@@ -2766,6 +2769,75 @@ bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle &
dstRect.top = drawRect.y; dstRect.top = drawRect.y;
dstRect.bottom = drawRect.y + drawRect.height; 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); HRESULT result = mDevice->StretchRect(readSurface, &srcRect, drawSurface, &dstRect, D3DTEXF_NONE);
SafeRelease(readSurface); SafeRelease(readSurface);
......
...@@ -186,7 +186,7 @@ class Renderer9 : public Renderer ...@@ -186,7 +186,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 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, 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);
......
...@@ -140,7 +140,8 @@ bool TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, unsign ...@@ -140,7 +140,8 @@ bool TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, unsign
Blit11 *blitter = mRenderer->getBlitter(); Blit11 *blitter = mRenderer->getBlitter();
return blitter->copyDepthStencil(srcTexture, sourceSubresource, copyArea, texSize, return blitter->copyDepthStencil(srcTexture, sourceSubresource, copyArea, texSize,
dstTexture, dstSubresource, copyArea, texSize); dstTexture, dstSubresource, copyArea, texSize,
NULL);
} }
else else
{ {
...@@ -180,7 +181,7 @@ void TextureStorage11::generateMipmapLayer(RenderTarget11 *source, RenderTarget1 ...@@ -180,7 +181,7 @@ void TextureStorage11::generateMipmapLayer(RenderTarget11 *source, RenderTarget1
Blit11 *blitter = mRenderer->getBlitter(); 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::GetFormat(source->getInternalFormat(), mRenderer->getCurrentClientVersion()),
GL_LINEAR); GL_LINEAR);
} }
......
...@@ -98,6 +98,31 @@ bool ValidateRenderbufferStorageParameters(const gl::Context *context, GLenum ta ...@@ -98,6 +98,31 @@ bool ValidateRenderbufferStorageParameters(const gl::Context *context, GLenum ta
return true; 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, bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask,
GLenum filter, bool fromAngleExtension) GLenum filter, bool fromAngleExtension)
...@@ -164,14 +189,6 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint ...@@ -164,14 +189,6 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
return gl::error(GL_INVALID_OPERATION, false); 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; bool sameBounds = srcX0 == dstX0 && srcY0 == dstY0 && srcX1 == dstX1 && srcY1 == dstY1;
GLuint clientVersion = context->getClientVersion(); GLuint clientVersion = context->getClientVersion();
...@@ -249,8 +266,9 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint ...@@ -249,8 +266,9 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
} }
} }
} }
if (readFramebuffer->getSamples() != 0 && IsPartialBlit(context, readColorBuffer, drawColorBuffer,
if (partialCopy && readFramebuffer->getSamples() != 0) srcX0, srcY0, srcX1, srcY1,
dstX0, dstY0, dstX1, dstY1))
{ {
return gl::error(GL_INVALID_OPERATION, false); return gl::error(GL_INVALID_OPERATION, false);
} }
...@@ -277,7 +295,8 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint ...@@ -277,7 +295,8 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
if (fromAngleExtension) 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."); 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 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 ...@@ -296,12 +315,6 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
gl::Renderbuffer *readStencilBuffer = readFramebuffer->getStencilbuffer(); gl::Renderbuffer *readStencilBuffer = readFramebuffer->getStencilbuffer();
gl::Renderbuffer *drawStencilBuffer = drawFramebuffer->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 && drawStencilBuffer)
{ {
if (readStencilBuffer->getActualFormat() != drawStencilBuffer->getActualFormat()) if (readStencilBuffer->getActualFormat() != drawStencilBuffer->getActualFormat())
...@@ -316,7 +329,8 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint ...@@ -316,7 +329,8 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
if (fromAngleExtension) 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."); 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 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