Commit 2da819e1 by Jamie Madill

D3D11: Fix blit from out-of-bounds.

Do not copy pixels in a negative read region. Also make sure we clamp the boundaries so the dEQP tests are mostly pixel-perfect. We can't yet fix some default framebuffer tests because of issues with blitting RGBA8 (default FBO) to floating point framebuffers. BUG=angleproject:1241 TEST=dEQP-GLES3.functional.fbo.blit.* Change-Id: I16ee264b0b1a7e6b9121dde5ae4f96cfd27ea53e Reviewed-on: https://chromium-review.googlesource.com/315670Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 063d9e78
...@@ -68,13 +68,21 @@ typedef Color<unsigned int> ColorUI; ...@@ -68,13 +68,21 @@ typedef Color<unsigned int> ColorUI;
struct Rectangle struct Rectangle
{ {
Rectangle() : x(0), y(0), width(0), height(0) {}
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)
{
}
int x0() const { return x; }
int y0() const { return y; }
int x1() const { return x + width; }
int y1() const { return y + height; }
int x; int x;
int y; int y;
int width; int width;
int height; int height;
Rectangle() : x(0), y(0), width(0), height(0) { }
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 operator==(const Rectangle &a, const Rectangle &b); bool operator==(const Rectangle &a, const Rectangle &b);
......
...@@ -3782,9 +3782,15 @@ gl::Error Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsP ...@@ -3782,9 +3782,15 @@ gl::Error Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsP
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTargetD3D *readRenderTarget, gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn,
RenderTargetD3D *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor, const gl::Rectangle &drawRectIn,
bool colorBlit, bool depthBlit, bool stencilBlit) RenderTargetD3D *readRenderTarget,
RenderTargetD3D *drawRenderTarget,
GLenum filter,
const gl::Rectangle *scissor,
bool colorBlit,
bool depthBlit,
bool stencilBlit)
{ {
// Since blitRenderbufferRect is called for each render buffer that needs to be blitted, // Since blitRenderbufferRect is called for each render buffer that needs to be blitted,
// it should never be the case that both color and depth/stencil need to be blitted at // it should never be the case that both color and depth/stencil need to be blitted at
...@@ -3850,6 +3856,66 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const ...@@ -3850,6 +3856,66 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const
gl::Extents readSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1); gl::Extents readSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1);
gl::Extents drawSize(drawRenderTarget->getWidth(), drawRenderTarget->getHeight(), 1); gl::Extents drawSize(drawRenderTarget->getWidth(), drawRenderTarget->getHeight(), 1);
// From the spec:
// "The actual region taken from the read framebuffer is limited to the intersection of the
// source buffers being transferred, which may include the color buffer selected by the read
// buffer, the depth buffer, and / or the stencil buffer depending on mask."
// This means negative x and y are out of bounds, and not to be read from. We handle this here
// by internally scaling the read and draw rectangles.
gl::Rectangle readRect = readRectIn;
gl::Rectangle drawRect = drawRectIn;
auto readToDrawX = [&drawRectIn, &readRectIn](int readOffset)
{
double readToDrawScale =
static_cast<double>(drawRectIn.width) / static_cast<double>(readRectIn.width);
return static_cast<int>(round(static_cast<double>(readOffset) * readToDrawScale));
};
if (readRect.x < 0)
{
int readOffset = -readRect.x;
readRect.x += readOffset;
readRect.width -= readOffset;
int drawOffset = readToDrawX(readOffset);
drawRect.x += drawOffset;
drawRect.width -= drawOffset;
}
auto readToDrawY = [&drawRectIn, &readRectIn](int readOffset)
{
double readToDrawScale =
static_cast<double>(drawRectIn.height) / static_cast<double>(readRectIn.height);
return static_cast<int>(round(static_cast<double>(readOffset) * readToDrawScale));
};
if (readRect.y < 0)
{
int readOffset = -readRect.y;
readRect.y += readOffset;
readRect.height -= readOffset;
int drawOffset = readToDrawY(readOffset);
drawRect.y += drawOffset;
drawRect.height -= drawOffset;
}
if (readRect.x1() < 0)
{
int readOffset = -readRect.x1();
readRect.width += readOffset;
int drawOffset = readToDrawX(readOffset);
drawRect.width += drawOffset;
}
if (readRect.y1() < 0)
{
int readOffset = -readRect.y1();
readRect.height += readOffset;
int drawOffset = readToDrawY(readOffset);
drawRect.height += drawOffset;
}
bool scissorNeeded = scissor && gl::ClipRectangle(drawRect, *scissor, NULL); bool scissorNeeded = scissor && gl::ClipRectangle(drawRect, *scissor, NULL);
bool wholeBufferCopy = !scissorNeeded && bool wholeBufferCopy = !scissorNeeded &&
......
...@@ -286,9 +286,8 @@ gl::Error FramebufferGL::blit(const gl::State &state, const gl::Rectangle &sourc ...@@ -286,9 +286,8 @@ gl::Error FramebufferGL::blit(const gl::State &state, const gl::Rectangle &sourc
mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, sourceFramebufferGL->getFramebufferID()); mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, sourceFramebufferGL->getFramebufferID());
mStateManager->bindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebufferID); mStateManager->bindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebufferID);
mFunctions->blitFramebuffer(sourceArea.x, sourceArea.y, sourceArea.x + sourceArea.width, sourceArea.y + sourceArea.height, mFunctions->blitFramebuffer(sourceArea.x, sourceArea.y, sourceArea.x1(), sourceArea.y1(),
destArea.x, destArea.y, destArea.x + destArea.width, destArea.y + destArea.height, destArea.x, destArea.y, destArea.x1(), destArea.y1(), mask, filter);
mask, filter);
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
......
...@@ -414,13 +414,6 @@ ...@@ -414,13 +414,6 @@
1097 WIN : dEQP-GLES3.functional.fbo.color.repeated_clear.sample.tex2d.rg16f = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.color.repeated_clear.sample.tex2d.rg16f = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.color.repeated_clear.sample.tex2d.r32f = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.color.repeated_clear.sample.tex2d.r32f = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.color.repeated_clear.sample.tex2d.r16f = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.color.repeated_clear.sample.tex2d.r16f = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.rect.out_of_bounds_nearest = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.rect.out_of_bounds_reverse_src_x_nearest = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.rect.out_of_bounds_reverse_src_y_nearest = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.rect.out_of_bounds_reverse_dst_x_nearest = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.rect.out_of_bounds_reverse_dst_y_nearest = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.rect.out_of_bounds_reverse_src_dst_x_nearest = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.rect.out_of_bounds_reverse_src_dst_y_nearest = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.conversion.rgba8_to_rgb8 = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.conversion.rgba8_to_rgb8 = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.conversion.rgba8_to_rgba32f = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.conversion.rgba8_to_rgba32f = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.conversion.rgba8_to_rgba16f = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.conversion.rgba8_to_rgba16f = FAIL
...@@ -486,57 +479,32 @@ ...@@ -486,57 +479,32 @@
1097 WIN : dEQP-GLES3.functional.fbo.blit.conversion.r8_to_rg16f = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.conversion.r8_to_rg16f = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.conversion.r8_to_r32f = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.conversion.r8_to_r32f = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.conversion.r8_to_r16f = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.conversion.r8_to_r16f = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgba8_linear_out_of_bounds_blit_from_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgba8_linear_out_of_bounds_blit_to_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.srgb8_alpha8_linear_out_of_bounds_blit_from_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.srgb8_alpha8_linear_out_of_bounds_blit_to_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgb10_a2_linear_out_of_bounds_blit_from_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgb10_a2_linear_out_of_bounds_blit_to_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgba4_linear_out_of_bounds_blit_from_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgba4_linear_out_of_bounds_blit_to_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgb5_a1_linear_out_of_bounds_blit_from_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgb5_a1_linear_out_of_bounds_blit_to_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgb8 = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgb8 = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgb8_linear_out_of_bounds_blit_from_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgb8_linear_out_of_bounds_blit_to_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgb565_linear_out_of_bounds_blit_from_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgb565_linear_out_of_bounds_blit_to_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rg8_linear_out_of_bounds_blit_from_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rg8_linear_out_of_bounds_blit_to_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.r8_linear_out_of_bounds_blit_from_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.r8_linear_out_of_bounds_blit_to_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgba32f = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgba32f = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgba32f_nearest_scale_blit_from_default = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgba32f_nearest_scale_blit_from_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgba32f_nearest_out_of_bounds_blit_from_default = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgba32f_nearest_out_of_bounds_blit_from_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgba32f_nearest_out_of_bounds_blit_to_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgba16f = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgba16f = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgba16f_nearest_scale_blit_from_default = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgba16f_nearest_scale_blit_from_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgba16f_linear_scale_blit_from_default = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgba16f_linear_scale_blit_from_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgba16f_linear_out_of_bounds_blit_from_default = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgba16f_linear_out_of_bounds_blit_from_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgba16f_linear_out_of_bounds_blit_to_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.r11f_g11f_b10f = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.r11f_g11f_b10f = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.r11f_g11f_b10f_nearest_scale_blit_from_default = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.r11f_g11f_b10f_nearest_scale_blit_from_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.r11f_g11f_b10f_linear_scale_blit_from_default = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.r11f_g11f_b10f_linear_scale_blit_from_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.r11f_g11f_b10f_linear_out_of_bounds_blit_from_default = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.r11f_g11f_b10f_linear_out_of_bounds_blit_from_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.r11f_g11f_b10f_linear_out_of_bounds_blit_to_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rg32f = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rg32f = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rg32f_nearest_scale_blit_from_default = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rg32f_nearest_scale_blit_from_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rg32f_nearest_out_of_bounds_blit_from_default = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rg32f_nearest_out_of_bounds_blit_from_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rg32f_nearest_out_of_bounds_blit_to_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rg16f = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rg16f = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rg16f_nearest_scale_blit_from_default = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rg16f_nearest_scale_blit_from_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rg16f_linear_scale_blit_from_default = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rg16f_linear_scale_blit_from_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rg16f_linear_out_of_bounds_blit_from_default = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rg16f_linear_out_of_bounds_blit_from_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rg16f_linear_out_of_bounds_blit_to_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.r32f = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.r32f = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.r32f_nearest_scale_blit_from_default = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.r32f_nearest_scale_blit_from_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.r32f_nearest_out_of_bounds_blit_from_default = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.r32f_nearest_out_of_bounds_blit_from_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.r32f_nearest_out_of_bounds_blit_to_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.r16f = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.r16f = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.r16f_nearest_scale_blit_from_default = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.r16f_nearest_scale_blit_from_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.r16f_linear_scale_blit_from_default = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.r16f_linear_scale_blit_from_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.r16f_linear_out_of_bounds_blit_from_default = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.r16f_linear_out_of_bounds_blit_from_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.r16f_linear_out_of_bounds_blit_to_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.msaa.2_samples.depth_component32f = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.msaa.2_samples.depth_component32f = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.msaa.2_samples.depth_component24 = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.msaa.2_samples.depth_component24 = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.msaa.2_samples.depth_component16 = FAIL 1097 WIN : dEQP-GLES3.functional.fbo.msaa.2_samples.depth_component16 = FAIL
......
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