Commit b436aac3 by Jamie Madill Committed by Commit Bot

Vulkan: Support inverted blit for depth/stencil.

Depth/stencil formats are packed tightly when reading back Images with vkCmdCopyImageToBuffer. Same for the reverse. Thus we need to take this into account when doing our blitWithReadback implementation. This splits the depth/stencil blit into two separate steps. Fixes all the remaining blit failures in BlitFramebufferANGLETest. Bug: angleproject:2673 Change-Id: Ie9f43f782a82b5a0746d00122b24f81088d57c4c Reviewed-on: https://chromium-review.googlesource.com/1140740 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 3003f048
......@@ -6,7 +6,7 @@
"ANGLE format:src/libANGLE/renderer/angle_format_map.json":
"ea6dfe3ebbc86e04f0d4b9f568ba22ae",
"ANGLE format:src/libANGLE/renderer/gen_angle_format_table.py":
"4b311db89dc5d3ed17c6e0f0e99260aa",
"9de29b6ca59a05747623c0dc32344b14",
"ANGLE load functions table:src/libANGLE/renderer/gen_load_functions_table.py":
"8afc7eecce2a3ba9f0b4beacb1aa7fe2",
"ANGLE load functions table:src/libANGLE/renderer/load_functions_data.json":
......
......@@ -9,6 +9,8 @@
#ifndef COMMON_COLOR_H_
#define COMMON_COLOR_H_
#include <cstdint>
namespace angle
{
......@@ -46,6 +48,14 @@ typedef Color<float> ColorF;
typedef Color<int> ColorI;
typedef Color<unsigned int> ColorUI;
struct DepthStencil
{
DepthStencil() : depth(0), stencil(0) {}
// Double is needed to represent the 32-bit integer range of GL_DEPTH_COMPONENT32.
double depth;
uint32_t stencil;
};
} // namespace angle
// TODO: Move this fully into the angle namespace
......
......@@ -24,8 +24,11 @@ void ReadColor(const uint8_t *source, uint8_t *dest);
template <typename destType, typename colorDataType>
void WriteColor(const uint8_t *source, uint8_t *dest);
template <typename sourceType, typename destType, typename colorDataType>
void CopyPixel(const uint8_t *source, uint8_t *dest);
template <typename SourceType>
void ReadDepthStencil(const uint8_t *source, uint8_t *dest);
template <typename DestType>
void WriteDepthStencil(const uint8_t *source, uint8_t *dest);
void CopyBGRA8ToRGBA8(const uint8_t *source, uint8_t *dest);
......
......@@ -8,27 +8,31 @@
namespace angle
{
template <typename sourceType, typename colorDataType>
inline void ReadColor(const uint8_t *source, uint8_t *dest)
void ReadColor(const uint8_t *source, uint8_t *dest)
{
sourceType::readColor(reinterpret_cast<Color<colorDataType>*>(dest),
reinterpret_cast<const sourceType*>(source));
}
template <typename destType, typename colorDataType>
inline void WriteColor(const uint8_t *source, uint8_t *dest)
void WriteColor(const uint8_t *source, uint8_t *dest)
{
destType::writeColor(reinterpret_cast<destType*>(dest),
reinterpret_cast<const Color<colorDataType>*>(source));
}
template <typename sourceType, typename destType, typename colorDataType>
inline void CopyPixel(const uint8_t *source, uint8_t *dest)
template <typename SourceType>
void ReadDepthStencil(const uint8_t *source, uint8_t *dest)
{
colorDataType temp;
ReadColor<sourceType, colorDataType>(source, &temp);
WriteColor<destType, colorDataType>(&temp, dest);
SourceType::ReadDepthStencil(reinterpret_cast<DepthStencil *>(dest),
reinterpret_cast<const SourceType *>(source));
}
template <typename DestType>
void WriteDepthStencil(const uint8_t *source, uint8_t *dest)
{
DestType::WriteDepthStencil(reinterpret_cast<DestType *>(dest),
reinterpret_cast<const DepthStencil *>(source));
}
} // namespace angle
......@@ -1759,4 +1759,77 @@ void R11G11B10F::average(R11G11B10F *dst, const R11G11B10F *src1, const R11G11B1
dst->B = gl::averageFloat10(src1->B, src2->B);
}
void D24S8::ReadDepthStencil(DepthStencil *dst, const D24S8 *src)
{
dst->depth = gl::normalizedToFloat<24>(src->D);
dst->stencil = gl::getShiftedData<8, 24>(src->S);
}
void D24S8::WriteDepthStencil(D24S8 *dst, const DepthStencil *src)
{
dst->D = gl::floatToNormalized<24, uint32_t>(static_cast<float>(src->depth));
dst->S = src->stencil & 0xFF;
}
void S8::ReadDepthStencil(DepthStencil *dst, const S8 *src)
{
UNIMPLEMENTED();
}
void S8::WriteDepthStencil(S8 *dst, const DepthStencil *src)
{
UNIMPLEMENTED();
}
void D16::ReadDepthStencil(DepthStencil *dst, const D16 *src)
{
UNIMPLEMENTED();
}
void D16::WriteDepthStencil(D16 *dst, const DepthStencil *src)
{
UNIMPLEMENTED();
}
void D24::ReadDepthStencil(DepthStencil *dst, const D24 *src)
{
dst->depth = gl::normalizedToFloat<24>(src->D);
}
void D24::WriteDepthStencil(D24 *dst, const DepthStencil *src)
{
UNIMPLEMENTED();
}
void D32F::ReadDepthStencil(DepthStencil *dst, const D32F *src)
{
dst->depth = src->D;
}
void D32F::WriteDepthStencil(D32F *dst, const DepthStencil *src)
{
UNIMPLEMENTED();
}
void D32::ReadDepthStencil(DepthStencil *dst, const D32 *src)
{
UNIMPLEMENTED();
}
void D32::WriteDepthStencil(D32 *dst, const DepthStencil *src)
{
UNIMPLEMENTED();
}
void D32FS8::ReadDepthStencil(DepthStencil *dst, const D32FS8 *src)
{
dst->depth = src->D;
dst->stencil = gl::getShiftedData<8, 24>(static_cast<uint32_t>(src->S));
}
void D32FS8::WriteDepthStencil(D32FS8 *dst, const DepthStencil *src)
{
dst->D = static_cast<float>(src->depth);
dst->S = src->stencil & 0xFF;
}
} // namespace angle
......@@ -710,6 +710,63 @@ struct R11G11B10F
};
static_assert(sizeof(R11G11B10F) == 4, "R11G11B10F struct not 32-bits.");
struct D24S8
{
uint32_t D : 24;
uint32_t S : 8;
static void ReadDepthStencil(DepthStencil *dst, const D24S8 *src);
static void WriteDepthStencil(D24S8 *dst, const DepthStencil *src);
};
struct S8
{
uint8_t S;
static void ReadDepthStencil(DepthStencil *dst, const S8 *src);
static void WriteDepthStencil(S8 *dst, const DepthStencil *src);
};
struct D16
{
uint16_t D;
static void ReadDepthStencil(DepthStencil *dst, const D16 *src);
static void WriteDepthStencil(D16 *dst, const DepthStencil *src);
};
struct D24
{
uint32_t D;
static void ReadDepthStencil(DepthStencil *dst, const D24 *src);
static void WriteDepthStencil(D24 *dst, const DepthStencil *src);
};
struct D32F
{
float D;
static void ReadDepthStencil(DepthStencil *dst, const D32F *src);
static void WriteDepthStencil(D32F *dst, const DepthStencil *src);
};
struct D32
{
uint32_t D;
static void ReadDepthStencil(DepthStencil *dst, const D32 *src);
static void WriteDepthStencil(D32 *dst, const DepthStencil *src);
};
struct D32FS8
{
float D;
uint32_t S;
static void ReadDepthStencil(DepthStencil *dst, const D32FS8 *src);
static void WriteDepthStencil(D32FS8 *dst, const DepthStencil *src);
};
} // namespace angle
#endif // IMAGEUTIL_IMAGEFORMATS_H_
......@@ -73,12 +73,12 @@ constexpr Format g_formatInfoTable[] = {
{ FormatID::BC2_RGBA_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
{ FormatID::BC3_RGBA_UNORM_BLOCK, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
{ FormatID::BC3_RGBA_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, true },
{ FormatID::D16_UNORM, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT16, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 16, 0, 2, false },
{ FormatID::D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 24, 8, 4, false },
{ FormatID::D24_UNORM_X8_UINT, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT24, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 24, 0, 4, false },
{ FormatID::D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, nullptr, NoCopyFunctions, nullptr, nullptr, GL_FLOAT, 0, 0, 0, 0, 32, 0, 4, false },
{ FormatID::D32_FLOAT_S8X24_UINT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, nullptr, NoCopyFunctions, nullptr, nullptr, GL_FLOAT, 0, 0, 0, 0, 32, 8, 8, false },
{ FormatID::D32_UNORM, GL_DEPTH_COMPONENT32_OES, GL_DEPTH_COMPONENT32_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 32, 0, 4, false },
{ FormatID::D16_UNORM, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT16, nullptr, NoCopyFunctions, ReadDepthStencil<D16>, WriteDepthStencil<D16>, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 16, 0, 2, false },
{ FormatID::D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, nullptr, NoCopyFunctions, ReadDepthStencil<D24S8>, WriteDepthStencil<D24S8>, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 24, 8, 4, false },
{ FormatID::D24_UNORM_X8_UINT, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT24, nullptr, NoCopyFunctions, ReadDepthStencil<D24>, WriteDepthStencil<D24>, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 24, 0, 4, false },
{ FormatID::D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, nullptr, NoCopyFunctions, ReadDepthStencil<D32F>, WriteDepthStencil<D32F>, GL_FLOAT, 0, 0, 0, 0, 32, 0, 4, false },
{ FormatID::D32_FLOAT_S8X24_UINT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, nullptr, NoCopyFunctions, ReadDepthStencil<D32FS8>, WriteDepthStencil<D32FS8>, GL_FLOAT, 0, 0, 0, 0, 32, 8, 8, false },
{ FormatID::D32_UNORM, GL_DEPTH_COMPONENT32_OES, GL_DEPTH_COMPONENT32_OES, nullptr, NoCopyFunctions, ReadDepthStencil<D32>, WriteDepthStencil<D32>, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 32, 0, 4, false },
{ FormatID::EAC_R11G11_SNORM_BLOCK, GL_COMPRESSED_SIGNED_RG11_EAC, GL_COMPRESSED_SIGNED_RG11_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_SIGNED_NORMALIZED, 11, 11, 0, 0, 0, 0, 2, true },
{ FormatID::EAC_R11G11_UNORM_BLOCK, GL_COMPRESSED_RG11_EAC, GL_COMPRESSED_RG11_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 11, 11, 0, 0, 0, 0, 2, true },
{ FormatID::EAC_R11_SNORM_BLOCK, GL_COMPRESSED_SIGNED_R11_EAC, GL_COMPRESSED_SIGNED_R11_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_SIGNED_NORMALIZED, 11, 0, 0, 0, 0, 0, 1, true },
......@@ -196,7 +196,7 @@ constexpr Format g_formatInfoTable[] = {
{ FormatID::R8_UNORM, GL_R8, GL_R8, GenerateMip<R8>, NoCopyFunctions, ReadColor<R8, GLfloat>, WriteColor<R8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 0, 0, 0, 0, 0, 1, false },
{ FormatID::R8_USCALED, GL_R8_USCALED_ANGLEX, GL_R8_USCALED_ANGLEX, GenerateMip<R8>, NoCopyFunctions, ReadColor<R8, GLuint>, WriteColor<R8, GLuint>, GL_UNSIGNED_INT, 8, 0, 0, 0, 0, 0, 1, false },
{ FormatID::R9G9B9E5_SHAREDEXP, GL_RGB9_E5, GL_RGB9_E5, GenerateMip<R9G9B9E5>, NoCopyFunctions, ReadColor<R9G9B9E5, GLfloat>, WriteColor<R9G9B9E5, GLfloat>, GL_FLOAT, 9, 9, 9, 0, 0, 0, 3, false },
{ FormatID::S8_UINT, GL_STENCIL_INDEX8, GL_STENCIL_INDEX8, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_INT, 0, 0, 0, 0, 0, 8, 1, false },
{ FormatID::S8_UINT, GL_STENCIL_INDEX8, GL_STENCIL_INDEX8, nullptr, NoCopyFunctions, ReadDepthStencil<S8>, WriteDepthStencil<S8>, GL_UNSIGNED_INT, 0, 0, 0, 0, 0, 8, 1, false },
// clang-format on
};
......
......@@ -85,19 +85,31 @@ const Format &Format::Get(FormatID id)
}} // namespace angle
"""
def is_depth_stencil(angle_format):
if not 'channels' in angle_format or not angle_format['channels']:
return False
return 'd' in angle_format['channels'] or 's' in angle_format['channels']
def get_component_suffix(angle_format):
if angle_format['componentType'] == 'float':
return 'F'
if angle_format['componentType'] == 'int' or angle_format['componentType'] == 'snorm':
return 'S'
return ""
def get_channel_struct(angle_format):
if 'bits' not in angle_format or angle_format['bits'] is None:
return None
if 'BLOCK' in angle_format['id']:
return None
bits = angle_format['bits']
if 'D' in bits or 'S' in bits:
return None
if 'channelStruct' in angle_format:
return angle_format['channelStruct']
struct_name = ''
component_suffix = get_component_suffix(angle_format)
for channel in angle_format['channels']:
if channel == 'r':
struct_name += 'R{}'.format(bits['R'])
......@@ -109,15 +121,19 @@ def get_channel_struct(angle_format):
struct_name += 'A{}'.format(bits['A'])
if channel == 'l':
struct_name += 'L{}'.format(bits['L'])
if angle_format['componentType'] == 'float':
struct_name += 'F'
if angle_format['componentType'] == 'int' or angle_format['componentType'] == 'snorm':
struct_name += 'S'
if channel == 'd':
struct_name += 'D{}'.format(bits['D']) + component_suffix
if channel == 's':
struct_name += 'S{}'.format(bits['S'])
if not is_depth_stencil(angle_format):
struct_name += component_suffix
return struct_name
def get_mip_generation_function(angle_format):
channel_struct = get_channel_struct(angle_format)
if channel_struct == None or "BLOCK" in angle_format["id"]:
if is_depth_stencil(angle_format) or channel_struct == None or "BLOCK" in angle_format["id"]:
return 'nullptr'
return 'GenerateMip<' + channel_struct + '>'
......@@ -135,6 +151,10 @@ def get_color_read_function(angle_format):
channel_struct = get_channel_struct(angle_format)
if channel_struct == None:
return 'nullptr'
if is_depth_stencil(angle_format):
return 'ReadDepthStencil<' + channel_struct + '>'
read_component_type = get_color_read_write_component_type(angle_format)
return 'ReadColor<' + channel_struct + ', '+ read_component_type + '>'
......@@ -142,6 +162,10 @@ def get_color_write_function(angle_format):
channel_struct = get_channel_struct(angle_format)
if channel_struct == None:
return 'nullptr'
if is_depth_stencil(angle_format):
return 'WriteDepthStencil<' + channel_struct + '>'
write_component_type = get_color_read_write_component_type(angle_format)
return 'WriteColor<' + channel_struct + ', '+ write_component_type + '>'
......
......@@ -236,8 +236,9 @@ void PackPixels(const PackPixelsParams &params,
// Maximum size of any Color<T> type used.
uint8_t temp[16];
static_assert(sizeof(temp) >= sizeof(gl::ColorF) && sizeof(temp) >= sizeof(gl::ColorUI) &&
sizeof(temp) >= sizeof(gl::ColorI),
"Unexpected size of gl::Color struct.");
sizeof(temp) >= sizeof(gl::ColorI) &&
sizeof(temp) >= sizeof(angle::DepthStencil),
"Unexpected size of pixel struct.");
ColorReadFunction colorReadFunction = sourceFormat.colorReadFunction;
ASSERT(colorReadFunction != nullptr);
......
......@@ -67,6 +67,40 @@ bool HasSrcAndDstBlitProperties(const VkPhysicalDevice &physicalDevice,
IsMaskFlagSet<VkFormatFeatureFlags>(readImageProperties.optimalTilingFeatures,
VK_FORMAT_FEATURE_BLIT_SRC_BIT));
}
// Special rules apply to VkBufferImageCopy with depth/stencil. The components are tightly packed
// into a depth or stencil section of the destination buffer. See the spec:
// https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VkBufferImageCopy.html
const angle::Format &GetDepthStencilImageToBufferFormat(const angle::Format &imageFormat,
VkImageAspectFlagBits copyAspect)
{
if (copyAspect == VK_IMAGE_ASPECT_STENCIL_BIT)
{
ASSERT(imageFormat.id == angle::FormatID::D24_UNORM_S8_UINT ||
imageFormat.id == angle::FormatID::D32_FLOAT_S8X24_UINT ||
imageFormat.id == angle::FormatID::S8_UINT);
return angle::Format::Get(angle::FormatID::S8_UINT);
}
ASSERT(copyAspect == VK_IMAGE_ASPECT_DEPTH_BIT);
switch (imageFormat.id)
{
case angle::FormatID::D16_UNORM:
return imageFormat;
case angle::FormatID::D24_UNORM_X8_UINT:
return imageFormat;
case angle::FormatID::D24_UNORM_S8_UINT:
return angle::Format::Get(angle::FormatID::D24_UNORM_X8_UINT);
case angle::FormatID::D32_FLOAT:
return imageFormat;
case angle::FormatID::D32_FLOAT_S8X24_UINT:
return angle::Format::Get(angle::FormatID::D32_FLOAT);
default:
UNREACHABLE();
return imageFormat;
}
}
} // anonymous namespace
// static
......@@ -395,56 +429,56 @@ RenderTargetVk *FramebufferVk::getColorReadRenderTarget() const
angle::Result FramebufferVk::blitWithReadback(ContextVk *contextVk,
const gl::Rectangle &copyArea,
bool blitDepthBuffer,
bool blitStencilBuffer,
VkImageAspectFlagBits aspect,
vk::CommandBuffer *commandBuffer,
RenderTargetVk *readRenderTarget,
RenderTargetVk *drawRenderTarget)
{
RendererVk *renderer = contextVk->getRenderer();
vk::ImageHelper *imageForRead = readRenderTarget->getImageForRead(
this, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, commandBuffer);
const angle::Format &drawFormat = drawRenderTarget->getImageFormat().angleFormat();
RendererVk *renderer = contextVk->getRenderer();
const angle::Format &readFormat = readRenderTarget->getImageFormat().textureFormat();
GLuint outputPitch = 0;
if (blitStencilBuffer)
{
// If we're copying the stencil bits, we need to adjust the outputPitch
// because in Vulkan, if we copy the stencil out of a any texture, the stencil
// will be tightly packed in an S8 buffer (as specified in the spec here
// https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VkBufferImageCopy.html)
outputPitch = copyArea.width * (drawFormat.stencilBits / 8);
}
else
{
outputPitch = copyArea.width * drawFormat.pixelBytes;
}
ASSERT(aspect == VK_IMAGE_ASPECT_DEPTH_BIT || aspect == VK_IMAGE_ASPECT_STENCIL_BIT);
// This path is only currently used for y-flipping depth/stencil blits.
PackPixelsParams packPixelsParams;
packPixelsParams.pack.alignment = 1;
packPixelsParams.pack.reverseRowOrder = true;
packPixelsParams.destFormat = &drawFormat;
packPixelsParams.area.height = copyArea.height;
packPixelsParams.area.width = copyArea.width;
packPixelsParams.area.height = copyArea.height;
packPixelsParams.area.x = copyArea.x;
packPixelsParams.area.y = copyArea.y;
packPixelsParams.outputPitch = outputPitch;
GLuint pixelBytes = imageForRead->getFormat().angleFormat().pixelBytes;
GLuint sizeToRequest = copyArea.width * copyArea.height * pixelBytes;
uint8_t *copyPtr = nullptr;
VkBuffer handleOut = VK_NULL_HANDLE;
uint32_t offsetOut = 0;
// Read back depth values into the destination buffer.
const angle::Format &copyFormat = GetDepthStencilImageToBufferFormat(readFormat, aspect);
packPixelsParams.destFormat = &copyFormat;
packPixelsParams.outputPitch = copyFormat.pixelBytes * copyArea.width;
// Allocate a space in the destination buffer to write to.
size_t blitAllocationSize = copyFormat.pixelBytes * copyArea.width * copyArea.height;
uint8_t *destPtr = nullptr;
VkBuffer destBufferHandle = VK_NULL_HANDLE;
uint32_t destOffset = 0;
ANGLE_TRY(mBlitPixelBuffer.allocate(contextVk, blitAllocationSize, &destPtr, &destBufferHandle,
&destOffset, nullptr));
ANGLE_TRY(
readPixelsImpl(contextVk, copyArea, packPixelsParams, aspect, readRenderTarget, destPtr));
VkBufferImageCopy copyRegion;
copyRegion.bufferOffset = destOffset;
copyRegion.bufferImageHeight = copyArea.height;
copyRegion.bufferRowLength = copyArea.width;
copyRegion.imageExtent.width = copyArea.width;
copyRegion.imageExtent.height = copyArea.height;
copyRegion.imageExtent.depth = 1;
copyRegion.imageSubresource.mipLevel = 0;
copyRegion.imageSubresource.aspectMask = aspect;
copyRegion.imageSubresource.baseArrayLayer = 0;
copyRegion.imageSubresource.layerCount = 1;
copyRegion.imageOffset.x = copyArea.x;
copyRegion.imageOffset.y = copyArea.y;
copyRegion.imageOffset.z = 0;
VkImageAspectFlags copyFlags =
vk::GetDepthStencilAspectFlagsForCopy(blitDepthBuffer, blitStencilBuffer);
ANGLE_TRY(mBlitPixelBuffer.allocate(contextVk, sizeToRequest, &copyPtr, &handleOut, &offsetOut,
nullptr));
ANGLE_TRY(readPixelsImpl(contextVk, copyArea, packPixelsParams, copyFlags, readRenderTarget,
copyPtr));
ANGLE_TRY(mBlitPixelBuffer.flush(contextVk));
// Reinitialize the commandBuffer after a read pixels because it calls
......@@ -459,25 +493,11 @@ angle::Result FramebufferVk::blitWithReadback(ContextVk *contextVk,
imageForWrite->getAspectFlags(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, commandBuffer);
VkBufferImageCopy region;
region.bufferOffset = offsetOut;
region.bufferImageHeight = copyArea.height;
region.bufferRowLength = copyArea.width;
region.imageExtent.width = copyArea.width;
region.imageExtent.height = copyArea.height;
region.imageExtent.depth = 1;
region.imageSubresource.mipLevel = 0;
region.imageSubresource.aspectMask = copyFlags;
region.imageSubresource.baseArrayLayer = 0;
region.imageSubresource.layerCount = 1;
region.imageOffset.x = copyArea.x;
region.imageOffset.y = copyArea.y;
region.imageOffset.z = 0;
commandBuffer->copyBufferToImage(handleOut, imageForWrite->getImage(),
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
commandBuffer->copyBufferToImage(destBufferHandle, imageForWrite->getImage(),
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &copyRegion);
mBlitPixelBuffer.releaseRetainedBuffers(renderer);
return angle::Result::Continue();
}
......@@ -584,9 +604,18 @@ gl::Error FramebufferVk::blit(const gl::Context *context,
{
if (flipSource || flipDest)
{
ANGLE_TRY(blitWithReadback(contextVk, readRenderTargetRect, blitDepthBuffer,
blitStencilBuffer, commandBuffer, readRenderTarget,
drawRenderTarget));
if (blitDepthBuffer)
{
ANGLE_TRY(blitWithReadback(contextVk, readRenderTargetRect,
VK_IMAGE_ASPECT_DEPTH_BIT, commandBuffer,
readRenderTarget, drawRenderTarget));
}
if (blitStencilBuffer)
{
ANGLE_TRY(blitWithReadback(contextVk, readRenderTargetRect,
VK_IMAGE_ASPECT_STENCIL_BIT, commandBuffer,
readRenderTarget, drawRenderTarget));
}
}
else
{
......@@ -1115,7 +1144,7 @@ gl::DrawBufferMask FramebufferVk::getEmulatedAlphaAttachmentMask()
angle::Result FramebufferVk::readPixelsImpl(ContextVk *contextVk,
const gl::Rectangle &area,
const PackPixelsParams &packPixelsParams,
const VkImageAspectFlags &copyAspectFlags,
VkImageAspectFlagBits copyAspectFlags,
RenderTargetVk *renderTarget,
void *pixels)
{
......@@ -1129,24 +1158,18 @@ angle::Result FramebufferVk::readPixelsImpl(ContextVk *contextVk,
vk::ImageHelper *srcImage =
renderTarget->getImageForRead(this, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, commandBuffer);
const angle::Format &angleFormat = srcImage->getFormat().textureFormat();
GLuint pixelBytes = angleFormat.pixelBytes;
const angle::Format *readFormat = &srcImage->getFormat().textureFormat();
// If we're copying only the stencil bits, we need to adjust the allocation size and the source
// pitch because in Vulkan, if we copy the stencil out of a D24S8 texture, the stencil will be
// tightly packed in an S8 buffer (as specified in the spec here
// https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VkBufferImageCopy.html)
if (copyAspectFlags == VK_IMAGE_ASPECT_STENCIL_BIT)
if (copyAspectFlags != VK_IMAGE_ASPECT_COLOR_BIT)
{
pixelBytes = angleFormat.stencilBits / 8;
readFormat = &GetDepthStencilImageToBufferFormat(*readFormat, copyAspectFlags);
}
VkBuffer bufferHandle = VK_NULL_HANDLE;
uint8_t *readPixelBuffer = nullptr;
bool newBufferAllocated = false;
uint32_t stagingOffset = 0;
size_t allocationSize = area.width * pixelBytes * area.height;
size_t allocationSize = readFormat->pixelBytes * area.width * area.height;
ANGLE_TRY(mReadPixelBuffer.allocate(contextVk, allocationSize, &readPixelBuffer, &bufferHandle,
&stagingOffset, &newBufferAllocated));
......@@ -1177,7 +1200,7 @@ angle::Result FramebufferVk::readPixelsImpl(ContextVk *contextVk,
// created with the host coherent bit.
ANGLE_TRY(mReadPixelBuffer.invalidate(contextVk));
PackPixels(packPixelsParams, angleFormat, area.width * pixelBytes, readPixelBuffer,
PackPixels(packPixelsParams, *readFormat, area.width * readFormat->pixelBytes, readPixelBuffer,
static_cast<uint8_t *>(pixels));
return angle::Result::Continue();
......
......@@ -98,7 +98,7 @@ class FramebufferVk : public FramebufferImpl, public vk::CommandGraphResource
angle::Result readPixelsImpl(ContextVk *contextVk,
const gl::Rectangle &area,
const PackPixelsParams &packPixelsParams,
const VkImageAspectFlags &copyAspectFlags,
VkImageAspectFlagBits copyAspectFlags,
RenderTargetVk *renderTarget,
void *pixels);
......@@ -135,8 +135,7 @@ class FramebufferVk : public FramebufferImpl, public vk::CommandGraphResource
angle::Result blitWithReadback(ContextVk *contextVk,
const gl::Rectangle &copyArea,
bool blitDepthBuffer,
bool blitStencilBuffer,
VkImageAspectFlagBits aspect,
vk::CommandBuffer *commandBuffer,
RenderTargetVk *readRenderTarget,
RenderTargetVk *drawRenderTarget);
......
......@@ -14,8 +14,8 @@ class BlitFramebufferANGLETest : public ANGLETest
protected:
BlitFramebufferANGLETest()
{
setWindowWidth(256);
setWindowHeight(256);
setWindowWidth(32);
setWindowHeight(32);
setConfigRedBits(8);
setConfigGreenBits(8);
setConfigBlueBits(8);
......@@ -24,41 +24,41 @@ class BlitFramebufferANGLETest : public ANGLETest
setConfigStencilBits(8);
mCheckerProgram = 0;
mBlueProgram = 0;
mBlueProgram = 0;
mRedProgram = 0;
mOriginalFBO = 0;
mUserFBO = 0;
mUserColorBuffer = 0;
mUserFBO = 0;
mUserColorBuffer = 0;
mUserDepthStencilBuffer = 0;
mSmallFBO = 0;
mSmallColorBuffer = 0;
mSmallFBO = 0;
mSmallColorBuffer = 0;
mSmallDepthStencilBuffer = 0;
mColorOnlyFBO = 0;
mColorOnlyFBO = 0;
mColorOnlyColorBuffer = 0;
mDiffFormatFBO = 0;
mDiffFormatFBO = 0;
mDiffFormatColorBuffer = 0;
mDiffSizeFBO = 0;
mDiffSizeFBO = 0;
mDiffSizeColorBuffer = 0;
mMRTFBO = 0;
mMRTFBO = 0;
mMRTColorBuffer0 = 0;
mMRTColorBuffer1 = 0;
mRGBAColorbuffer = 0;
mRGBAFBO = 0;
mRGBAColorbuffer = 0;
mRGBAFBO = 0;
mRGBAMultisampledRenderbuffer = 0;
mRGBAMultisampledFBO = 0;
mBGRAColorbuffer = 0;
mBGRAFBO = 0;
mBGRAMultisampledRenderbuffer = 0;
mBGRAMultisampledFBO = 0;
mBGRAMultisampledFBO = 0;
}
virtual void SetUp()
......@@ -90,13 +90,17 @@ class BlitFramebufferANGLETest : public ANGLETest
glGenTextures(1, &mUserColorBuffer);
glGenRenderbuffers(1, &mUserDepthStencilBuffer);
glBindTexture(GL_TEXTURE_2D, mUserColorBuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mUserColorBuffer, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
mUserColorBuffer, 0);
glTexImage2D(GL_TEXTURE_2D, 0, format, getWindowWidth(), getWindowHeight(), 0, format,
GL_UNSIGNED_BYTE, nullptr);
glBindRenderbuffer(GL_RENDERBUFFER, mUserDepthStencilBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, getWindowWidth(), getWindowHeight());
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mUserDepthStencilBuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mUserDepthStencilBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, getWindowWidth(),
getWindowHeight());
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
mUserDepthStencilBuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
mUserDepthStencilBuffer);
ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
ASSERT_GL_NO_ERROR();
......@@ -108,11 +112,15 @@ class BlitFramebufferANGLETest : public ANGLETest
glBindTexture(GL_TEXTURE_2D, mSmallColorBuffer);
glTexImage2D(GL_TEXTURE_2D, 0, format, getWindowWidth() / 2, getWindowHeight() / 2, 0,
format, GL_UNSIGNED_BYTE, nullptr);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mSmallColorBuffer, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
mSmallColorBuffer, 0);
glBindRenderbuffer(GL_RENDERBUFFER, mSmallDepthStencilBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, getWindowWidth() / 2, getWindowHeight() / 2);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mSmallDepthStencilBuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mSmallDepthStencilBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, getWindowWidth() / 2,
getWindowHeight() / 2);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
mSmallDepthStencilBuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
mSmallDepthStencilBuffer);
ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
ASSERT_GL_NO_ERROR();
......@@ -123,7 +131,8 @@ class BlitFramebufferANGLETest : public ANGLETest
glBindTexture(GL_TEXTURE_2D, mColorOnlyColorBuffer);
glTexImage2D(GL_TEXTURE_2D, 0, format, getWindowWidth(), getWindowHeight(), 0, format,
GL_UNSIGNED_BYTE, nullptr);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mColorOnlyColorBuffer, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
mColorOnlyColorBuffer, 0);
ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
ASSERT_GL_NO_ERROR();
......@@ -134,7 +143,8 @@ class BlitFramebufferANGLETest : public ANGLETest
glBindTexture(GL_TEXTURE_2D, mDiffFormatColorBuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, getWindowWidth(), getWindowHeight(), 0, GL_RGB,
GL_UNSIGNED_SHORT_5_6_5, nullptr);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mDiffFormatColorBuffer, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
mDiffFormatColorBuffer, 0);
ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
ASSERT_GL_NO_ERROR();
......@@ -145,7 +155,8 @@ class BlitFramebufferANGLETest : public ANGLETest
glBindTexture(GL_TEXTURE_2D, mDiffSizeColorBuffer);
glTexImage2D(GL_TEXTURE_2D, 0, format, getWindowWidth() * 2, getWindowHeight() * 2, 0,
format, GL_UNSIGNED_BYTE, nullptr);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mDiffSizeColorBuffer, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
mDiffSizeColorBuffer, 0);
ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
ASSERT_GL_NO_ERROR();
......@@ -159,11 +170,13 @@ class BlitFramebufferANGLETest : public ANGLETest
glBindTexture(GL_TEXTURE_2D, mMRTColorBuffer0);
glTexImage2D(GL_TEXTURE_2D, 0, format, getWindowWidth(), getWindowHeight(), 0, format,
GL_UNSIGNED_BYTE, nullptr);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, mMRTColorBuffer0, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D,
mMRTColorBuffer0, 0);
glBindTexture(GL_TEXTURE_2D, mMRTColorBuffer1);
glTexImage2D(GL_TEXTURE_2D, 0, format, getWindowWidth(), getWindowHeight(), 0, format,
GL_UNSIGNED_BYTE, nullptr);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, mMRTColorBuffer1, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D,
mMRTColorBuffer1, 0);
ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
ASSERT_GL_NO_ERROR();
......@@ -180,7 +193,8 @@ class BlitFramebufferANGLETest : public ANGLETest
glGenFramebuffers(1, &mRGBAFBO);
glBindFramebuffer(GL_FRAMEBUFFER, mRGBAFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mRGBAColorbuffer, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
mRGBAColorbuffer, 0);
ASSERT_GL_NO_ERROR();
ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
......@@ -392,17 +406,17 @@ TEST_P(BlitFramebufferANGLETest, BlitColorToDefault)
glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(),
GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
EXPECT_GL_NO_ERROR();
glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
EXPECT_PIXEL_EQ( getWindowWidth() / 4, getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ( getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255);
EXPECT_PIXEL_EQ(getWindowWidth() / 4, getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255);
}
// Draw to system framebuffer, blit whole-buffer color to user-created framebuffer.
......@@ -410,9 +424,6 @@ TEST_P(BlitFramebufferANGLETest, ReverseColorBlit)
{
ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_ANGLE_framebuffer_blit"));
// TODO(lucferron): Diagnose and fix http://anglebug.com/2732
ANGLE_SKIP_TEST_IF(IsAdreno() && IsVulkan());
glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
......@@ -424,17 +435,17 @@ TEST_P(BlitFramebufferANGLETest, ReverseColorBlit)
glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mOriginalFBO);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mUserFBO);
glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(),
GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
EXPECT_GL_NO_ERROR();
glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
EXPECT_PIXEL_EQ( getWindowWidth() / 4, getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ( getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255);
EXPECT_PIXEL_EQ(getWindowWidth() / 4, getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255);
}
// blit from user-created FBO to system framebuffer, with the scissor test enabled.
......@@ -459,8 +470,8 @@ TEST_P(BlitFramebufferANGLETest, ScissoredBlit)
glScissor(getWindowWidth() / 2, 0, getWindowWidth() / 2, getWindowHeight());
glEnable(GL_SCISSOR_TEST);
glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(),
GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
EXPECT_GL_NO_ERROR();
......@@ -468,10 +479,10 @@ TEST_P(BlitFramebufferANGLETest, ScissoredBlit)
glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
EXPECT_PIXEL_EQ( getWindowWidth() / 4, getWindowHeight() / 4, 255, 255, 255, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ( getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 255, 255, 255);
EXPECT_PIXEL_EQ(getWindowWidth() / 4, getWindowHeight() / 4, 255, 255, 255, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 255, 255, 255);
}
// blit from system FBO to user-created framebuffer, with the scissor test enabled.
......@@ -479,9 +490,6 @@ TEST_P(BlitFramebufferANGLETest, ReverseScissoredBlit)
{
ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_ANGLE_framebuffer_blit"));
// TODO(lucferron): Diagnose and fix http://anglebug.com/2732
ANGLE_SKIP_TEST_IF(IsAdreno() && IsVulkan());
glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
......@@ -495,23 +503,23 @@ TEST_P(BlitFramebufferANGLETest, ReverseScissoredBlit)
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glScissor(getWindowWidth() / 2, 0, getWindowWidth() / 2, getWindowHeight());
glEnable(GL_SCISSOR_TEST);
glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(),
GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
EXPECT_GL_NO_ERROR();
glDisable(GL_SCISSOR_TEST);
glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
EXPECT_PIXEL_EQ( getWindowWidth() / 4, getWindowHeight() / 4, 255, 255, 255, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ( getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 255, 255, 255);
EXPECT_PIXEL_EQ(getWindowWidth() / 4, getWindowHeight() / 4, 255, 255, 255, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 255, 255, 255);
}
// blit from user-created FBO to system framebuffer, using region larger than buffer.
......@@ -533,17 +541,18 @@ TEST_P(BlitFramebufferANGLETest, OversizedBlit)
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glBlitFramebufferANGLE(0, 0, getWindowWidth() * 2, getWindowHeight() * 2, 0, 0, getWindowWidth() * 2, getWindowHeight() * 2,
GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBlitFramebufferANGLE(0, 0, getWindowWidth() * 2, getWindowHeight() * 2, 0, 0,
getWindowWidth() * 2, getWindowHeight() * 2, GL_COLOR_BUFFER_BIT,
GL_NEAREST);
EXPECT_GL_NO_ERROR();
glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
EXPECT_PIXEL_EQ( getWindowWidth() / 4, getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ( getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255);
EXPECT_PIXEL_EQ(getWindowWidth() / 4, getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255);
}
// blit from system FBO to user-created framebuffer, using region larger than buffer.
......@@ -551,9 +560,6 @@ TEST_P(BlitFramebufferANGLETest, ReverseOversizedBlit)
{
ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_ANGLE_framebuffer_blit"));
// TODO(lucferron): Diagnose and fix http://anglebug.com/2732
ANGLE_SKIP_TEST_IF(IsAdreno() && IsVulkan());
glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
......@@ -568,24 +574,22 @@ TEST_P(BlitFramebufferANGLETest, ReverseOversizedBlit)
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glBlitFramebufferANGLE(0, 0, getWindowWidth() * 2, getWindowHeight() * 2, 0, 0, getWindowWidth() * 2, getWindowHeight() * 2,
GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBlitFramebufferANGLE(0, 0, getWindowWidth() * 2, getWindowHeight() * 2, 0, 0,
getWindowWidth() * 2, getWindowHeight() * 2, GL_COLOR_BUFFER_BIT,
GL_NEAREST);
EXPECT_GL_NO_ERROR();
glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
EXPECT_PIXEL_EQ( getWindowWidth() / 4, getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ( getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255);
EXPECT_PIXEL_EQ(getWindowWidth() / 4, getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255);
}
// blit from user-created FBO to system framebuffer, with depth buffer.
TEST_P(BlitFramebufferANGLETest, BlitWithDepthUserToDefault)
{
// TODO(lucferron): Diagnose and fix http://anglebug.com/2729
ANGLE_SKIP_TEST_IF(IsAMD() && IsVulkan());
ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_ANGLE_framebuffer_blit"));
glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
......@@ -639,9 +643,6 @@ TEST_P(BlitFramebufferANGLETest, BlitWithDepthUserToDefault)
// blit from system FBO to user-created framebuffer, with depth buffer.
TEST_P(BlitFramebufferANGLETest, BlitWithDepthDefaultToUser)
{
// TODO(lucferron): Diagnose and fix http://anglebug.com/2729
ANGLE_SKIP_TEST_IF(IsAMD() && IsVulkan());
ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_ANGLE_framebuffer_blit"));
glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
......@@ -673,8 +674,9 @@ TEST_P(BlitFramebufferANGLETest, BlitWithDepthDefaultToUser)
glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mUserFBO);
glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mOriginalFBO);
glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(),
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
getWindowHeight(), GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
GL_NEAREST);
EXPECT_GL_NO_ERROR();
glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
......@@ -704,8 +706,8 @@ TEST_P(BlitFramebufferANGLETest, BlitSameBufferOriginal)
EXPECT_GL_NO_ERROR();
glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight(), getWindowWidth() / 2, 0, getWindowWidth(), getWindowHeight(),
GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight(), getWindowWidth() / 2, 0,
getWindowWidth(), getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
}
......@@ -722,8 +724,8 @@ TEST_P(BlitFramebufferANGLETest, BlitSameBufferUser)
EXPECT_GL_NO_ERROR();
glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight(), getWindowWidth() / 2, 0, getWindowWidth(), getWindowHeight(),
GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight(), getWindowWidth() / 2, 0,
getWindowWidth(), getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
}
......@@ -743,19 +745,20 @@ TEST_P(BlitFramebufferANGLETest, BlitPartialColor)
glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, 0, getWindowHeight() / 2, getWindowWidth() / 2, getWindowHeight(),
glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, 0,
getWindowHeight() / 2, getWindowWidth() / 2, getWindowHeight(),
GL_COLOR_BUFFER_BIT, GL_NEAREST);
EXPECT_GL_NO_ERROR();
glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
EXPECT_PIXEL_EQ( getWindowWidth() / 4, getWindowHeight() / 4, 255, 255, 255, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 255, 255, 255, 255);
EXPECT_PIXEL_EQ(getWindowWidth() / 4, getWindowHeight() / 4, 255, 255, 255, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 255, 255, 255, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 255, 255, 255);
EXPECT_PIXEL_EQ( getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 0, 0, 255);
}
TEST_P(BlitFramebufferANGLETest, BlitDifferentSizes)
......@@ -774,16 +777,16 @@ TEST_P(BlitFramebufferANGLETest, BlitDifferentSizes)
glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(),
GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
EXPECT_GL_NO_ERROR();
glBindFramebuffer(GL_FRAMEBUFFER, mSmallFBO);
EXPECT_PIXEL_EQ( getWindowWidth() / 4, getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ(getWindowWidth() / 4, getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_GL_NO_ERROR();
}
......@@ -801,7 +804,7 @@ TEST_P(BlitFramebufferANGLETest, BlitWithMissingAttachments)
glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mColorOnlyFBO);
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
// generate INVALID_OPERATION if the read FBO has no depth attachment
glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
......@@ -833,16 +836,13 @@ TEST_P(BlitFramebufferANGLETest, BlitStencil)
// https://code.google.com/p/angleproject/issues/detail?id=2205
ANGLE_SKIP_TEST_IF(IsIntel() && IsD3D9());
// TODO(lucferron): Diagnose and fix http://anglebug.com/2693
// TODO(yunchao.he): Diagnose and fix http://anglebug.com/2693
ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsVulkan());
// TODO(lucferron): Diagnose and fix http://anglebug.com/2729
ANGLE_SKIP_TEST_IF(IsAMD() && IsVulkan());
glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
glClearColor(0.0, 1.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearStencil(0x0);
// Scissor half the screen so we fill the stencil only halfway
......@@ -864,30 +864,31 @@ TEST_P(BlitFramebufferANGLETest, BlitStencil)
// helpful in debugging if we see white in any result.
glClearColor(1.0, 1.0, 1.0, 1.0);
glClearStencil(0x0);
glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
// depth blit request should be silently ignored, because the read FBO has no depth attachment
glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(),
GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
getWindowHeight(), GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
GL_NEAREST);
EXPECT_GL_NO_ERROR();
glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
EXPECT_PIXEL_EQ( getWindowWidth() / 4, getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ(getWindowWidth() / 4, getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255);
EXPECT_PIXEL_EQ( getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255);
EXPECT_PIXEL_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255);
glStencilFunc(GL_EQUAL, 0x1, 0xFF); // only pass if stencil buffer at pixel reads 0x1
glStencilFunc(GL_EQUAL, 0x1, 0xFF); // only pass if stencil buffer at pixel reads 0x1
drawQuad(mBlueProgram, essl1_shaders::PositionAttrib(),
0.8f); // blue quad will draw if stencil buffer was copied
glDisable(GL_STENCIL_TEST);
EXPECT_PIXEL_EQ( getWindowWidth() / 4, getWindowHeight() / 4, 0, 0, 255, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 0, 255, 255);
EXPECT_PIXEL_EQ(getWindowWidth() / 4, getWindowHeight() / 4, 0, 0, 255, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 0, 255, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255);
EXPECT_PIXEL_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255);
}
......@@ -908,8 +909,9 @@ TEST_P(BlitFramebufferANGLETest, BlitPartialDepthStencil)
glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, 0, 0,
getWindowWidth() / 2, getWindowHeight() / 2, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, 0, 0,
getWindowWidth() / 2, getWindowHeight() / 2, GL_DEPTH_BUFFER_BIT,
GL_NEAREST);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
}
......@@ -923,7 +925,7 @@ TEST_P(BlitFramebufferANGLETest, BlitMRT)
return;
}
GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT };
GLenum drawBuffers[] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT};
glBindFramebuffer(GL_FRAMEBUFFER, mMRTFBO);
glDrawBuffersEXT(2, drawBuffers);
......@@ -939,28 +941,31 @@ TEST_P(BlitFramebufferANGLETest, BlitMRT)
glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mColorOnlyFBO);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mMRTFBO);
glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(),
GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
EXPECT_GL_NO_ERROR();
glBindFramebuffer(GL_FRAMEBUFFER, mMRTFBO);
EXPECT_PIXEL_EQ( getWindowWidth() / 4, getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ( getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255);
EXPECT_PIXEL_EQ(getWindowWidth() / 4, getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, 0, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mMRTColorBuffer0, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mMRTColorBuffer0,
0);
EXPECT_PIXEL_EQ( getWindowWidth() / 4, getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ( getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255);
EXPECT_PIXEL_EQ(getWindowWidth() / 4, getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255);
EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 0, 0, 255);
EXPECT_PIXEL_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mMRTColorBuffer0, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, mMRTColorBuffer1, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mMRTColorBuffer0,
0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D,
mMRTColorBuffer1, 0);
}
// Test multisampled framebuffer blits if supported
......@@ -1041,7 +1046,7 @@ TEST_P(BlitFramebufferANGLETest, ErrorStretching)
glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, 0, 0,
glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, 0, 0,
getWindowWidth(), getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
}
......@@ -1062,8 +1067,8 @@ TEST_P(BlitFramebufferANGLETest, ErrorFlipping)
glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, getWindowWidth() / 2, getWindowHeight() / 2,
0, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, getWindowWidth() / 2,
getWindowHeight() / 2, 0, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
}
......@@ -1082,18 +1087,18 @@ TEST_P(BlitFramebufferANGLETest, Errors)
glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(),
GL_COLOR_BUFFER_BIT, GL_LINEAR);
glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_LINEAR);
EXPECT_GL_ERROR(GL_INVALID_ENUM);
glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(),
GL_COLOR_BUFFER_BIT | 234, GL_NEAREST);
glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
getWindowHeight(), GL_COLOR_BUFFER_BIT | 234, GL_NEAREST);
EXPECT_GL_ERROR(GL_INVALID_VALUE);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mDiffFormatFBO);
glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(),
GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
}
......@@ -1491,7 +1496,8 @@ TEST_P(BlitFramebufferTest, BlitFramebufferSizeOverflow)
EXPECT_GL_ERROR(GL_INVALID_VALUE);
}
// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
// Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against.
ANGLE_INSTANTIATE_TEST(BlitFramebufferANGLETest,
ES2_D3D9(),
ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE),
......
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