Commit d1860ea1 by Le Hoang Quyen Committed by Commit Bot

Metal: support OES_depth_texture

Also added Depth32 & Depth16 texture data upload tests. Bug: angleproject:2634 Change-Id: I103f1cda1dc915f0dc8b04f7aaa2d8c0f9220cda Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1919281 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 75875885
......@@ -20,6 +20,12 @@ struct FeaturesMtl : FeatureSetBase
Feature hasBaseVertexInstancedDraw = {
"has_base_vertex_instanced_draw", FeatureCategory::MetalFeatures,
"The renderer supports base vertex instanced draw", &members};
// Support depth texture filtering
Feature hasDepthTextureFiltering = {
"has_depth_texture_filtering", FeatureCategory::MetalFeatures,
"The renderer supports depth texture's filtering other than nearest", &members};
// Non-uniform compute shader dispatch support, i.e. Group size is not necessarily to be fixed:
Feature hasNonUniformDispatch = {
"has_non_uniform_dispatch", FeatureCategory::MetalFeatures,
......
......@@ -4,7 +4,7 @@
"src/libANGLE/renderer/metal/gen_mtl_format_table.py":
"b6468446dd1da3e44ac9dd11690b5bf1",
"src/libANGLE/renderer/metal/mtl_format_map.json":
"c6f5b6dda11e456cfbcaeec53eb46fa0",
"0166b70697732612bd46942e7ccf8e6e",
"src/libANGLE/renderer/metal/mtl_format_table_autogen.mm":
"706e07c2bf5b50fa031678a5c2372465"
"8796be69461e2bb07db3b81b6ef24432"
}
\ No newline at end of file
......@@ -1799,7 +1799,7 @@ void R11G11B10F::average(R11G11B10F *dst, const R11G11B10F *src1, const R11G11B1
void D24S8::ReadDepthStencil(DepthStencil *dst, const D24S8 *src)
{
dst->depth = gl::normalizedToFloat<24>(src->D);
dst->stencil = gl::getShiftedData<8, 24>(src->S);
dst->stencil = src->S;
}
void D24S8::WriteDepthStencil(D24S8 *dst, const DepthStencil *src)
......@@ -1810,22 +1810,24 @@ void D24S8::WriteDepthStencil(D24S8 *dst, const DepthStencil *src)
void S8::ReadDepthStencil(DepthStencil *dst, const S8 *src)
{
UNIMPLEMENTED();
dst->depth = 0;
dst->stencil = src->S;
}
void S8::WriteDepthStencil(S8 *dst, const DepthStencil *src)
{
UNIMPLEMENTED();
dst->S = src->stencil & 0xFF;
}
void D16::ReadDepthStencil(DepthStencil *dst, const D16 *src)
{
UNIMPLEMENTED();
dst->depth = gl::normalizedToFloat(src->D);
dst->stencil = 0;
}
void D16::WriteDepthStencil(D16 *dst, const DepthStencil *src)
{
UNIMPLEMENTED();
dst->D = gl::floatToNormalized<uint16_t>(static_cast<float>(src->depth));
}
void D24X8::ReadDepthStencil(DepthStencil *dst, const D24X8 *src)
......@@ -1835,7 +1837,7 @@ void D24X8::ReadDepthStencil(DepthStencil *dst, const D24X8 *src)
void D24X8::WriteDepthStencil(D24X8 *dst, const DepthStencil *src)
{
UNIMPLEMENTED();
dst->D = gl::floatToNormalized<24, uint32_t>(static_cast<float>(src->depth));
}
void D32F::ReadDepthStencil(DepthStencil *dst, const D32F *src)
......@@ -1845,23 +1847,24 @@ void D32F::ReadDepthStencil(DepthStencil *dst, const D32F *src)
void D32F::WriteDepthStencil(D32F *dst, const DepthStencil *src)
{
UNIMPLEMENTED();
dst->D = static_cast<float>(src->depth);
}
void D32::ReadDepthStencil(DepthStencil *dst, const D32 *src)
{
UNIMPLEMENTED();
dst->depth = gl::normalizedToFloat(src->D);
dst->stencil = 0;
}
void D32::WriteDepthStencil(D32 *dst, const DepthStencil *src)
{
UNIMPLEMENTED();
dst->D = gl::floatToNormalized<uint32_t>(static_cast<float>(src->depth));
}
void D32FS8X24::ReadDepthStencil(DepthStencil *dst, const D32FS8X24 *src)
{
dst->depth = src->D;
dst->stencil = gl::getShiftedData<8, 24>(static_cast<uint32_t>(src->S));
dst->stencil = src->S;
}
void D32FS8X24::WriteDepthStencil(D32FS8X24 *dst, const DepthStencil *src)
......
......@@ -726,8 +726,8 @@ static_assert(sizeof(R11G11B10F) == 4, "R11G11B10F struct not 32-bits.");
struct D24S8
{
uint32_t D : 24;
uint32_t S : 8;
uint32_t D : 24;
static void ReadDepthStencil(DepthStencil *dst, const D24S8 *src);
static void WriteDepthStencil(D24S8 *dst, const DepthStencil *src);
......
......@@ -347,7 +347,7 @@ class Framebuffer final : public angle::ObserverInterface,
DIRTY_BIT_COLOR_BUFFER_CONTENTS_0,
DIRTY_BIT_COLOR_BUFFER_CONTENTS_MAX =
DIRTY_BIT_COLOR_BUFFER_CONTENTS_0 + IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS,
DIRTY_BIT_DEPTH_BUFFER_CONTENTS,
DIRTY_BIT_DEPTH_BUFFER_CONTENTS = DIRTY_BIT_COLOR_BUFFER_CONTENTS_MAX,
DIRTY_BIT_STENCIL_BUFFER_CONTENTS,
DIRTY_BIT_DRAW_BUFFERS,
DIRTY_BIT_READ_BUFFER,
......
......@@ -614,11 +614,15 @@ void DisplayMtl::initializeFeatures()
{
// default values:
mFeatures.hasBaseVertexInstancedDraw.enabled = true;
mFeatures.hasDepthTextureFiltering.enabled = false;
mFeatures.hasNonUniformDispatch.enabled = true;
mFeatures.hasTextureSwizzle.enabled = false;
mFeatures.allowSeparatedDepthStencilBuffers.enabled = false;
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
mFeatures.hasDepthTextureFiltering.enabled = true;
// Texture swizzle is only supported if macos sdk 10.15 is present
# if defined(__MAC_10_15)
if (ANGLE_APPLE_AVAILABLE_XC(10.15, 13.0))
......
......@@ -161,6 +161,7 @@ class TextureMtl : public TextureImpl
private:
void releaseTexture(bool releaseImages);
angle::Result ensureSamplerStateCreated(const gl::Context *context);
// Ensure image at given index is created:
angle::Result ensureImageCreated(const gl::Context *context, const gl::ImageIndex &index);
angle::Result checkForEmulatedChannels(const gl::Context *context,
......
......@@ -274,6 +274,17 @@ class BlitCommandEncoder final : public CommandEncoder
BlitCommandEncoder &restart();
BlitCommandEncoder &copyBufferToTexture(const BufferRef &src,
size_t srcOffset,
size_t srcBytesPerRow,
size_t srcBytesPerImage,
MTLSize srcSize,
const TextureRef &dst,
uint32_t dstSlice,
uint32_t dstLevel,
MTLOrigin dstOrigin,
MTLBlitOption blitOption);
BlitCommandEncoder &copyTexture(const TextureRef &dst,
uint32_t dstSlice,
uint32_t dstLevel,
......
......@@ -840,6 +840,39 @@ BlitCommandEncoder &BlitCommandEncoder::restart()
}
}
BlitCommandEncoder &BlitCommandEncoder::copyBufferToTexture(const BufferRef &src,
size_t srcOffset,
size_t srcBytesPerRow,
size_t srcBytesPerImage,
MTLSize srcSize,
const TextureRef &dst,
uint32_t dstSlice,
uint32_t dstLevel,
MTLOrigin dstOrigin,
MTLBlitOption blitOption)
{
if (!src || !dst)
{
return *this;
}
cmdBuffer().setReadDependency(src);
cmdBuffer().setWriteDependency(dst);
[get() copyFromBuffer:src->get()
sourceOffset:srcOffset
sourceBytesPerRow:srcBytesPerRow
sourceBytesPerImage:srcBytesPerImage
sourceSize:srcSize
toTexture:dst->get()
destinationSlice:dstSlice
destinationLevel:dstLevel
destinationOrigin:dstOrigin
options:blitOption];
return *this;
}
BlitCommandEncoder &BlitCommandEncoder::copyTexture(const TextureRef &dst,
uint32_t dstSlice,
uint32_t dstLevel,
......
......@@ -323,6 +323,10 @@ class Context : public ErrorHandler
#define ANGLE_MTL_TRY(context, test) ANGLE_MTL_CHECK(context, test, GL_INVALID_OPERATION)
#define ANGLE_MTL_UNREACHABLE(context) \
UNREACHABLE(); \
ANGLE_MTL_TRY(context, false)
} // namespace mtl
} // namespace rx
......
......@@ -69,7 +69,8 @@
"A32_FLOAT": "R32G32B32A32_FLOAT",
"L32_FLOAT": "R32G32B32A32_FLOAT",
"L32A32_FLOAT": "R32G32B32A32_FLOAT",
"D24_UNORM_X8_UINT": "D32_FLOAT"
"D24_UNORM_X8_UINT": "D32_FLOAT",
"D32_UNORM": "D32_FLOAT"
},
"override_ios": {
"D24_UNORM_S8_UINT": "D32_FLOAT_S8X24_UINT",
......
......@@ -262,6 +262,11 @@ void Format::init(const DisplayMtl *display, angle::FormatID intendedFormatId_)
this->actualFormatId = angle::FormatID::D32_FLOAT;
break;
case angle::FormatID::D32_UNORM:
this->metalFormat = MTLPixelFormatDepth32Float;
this->actualFormatId = angle::FormatID::D32_FLOAT;
break;
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
case angle::FormatID::L16A16_FLOAT:
if (metalDevice.depth24Stencil8PixelFormatSupported)
......
......@@ -34,6 +34,14 @@ bool OverrideTextureCaps(const DisplayMtl *display, angle::FormatID formatId, gl
case angle::FormatID::R8G8B8A8_UNORM_SRGB:
case angle::FormatID::B8G8R8A8_UNORM:
case angle::FormatID::B8G8R8A8_UNORM_SRGB:
// NOTE: even though iOS devices don't support filtering depth textures, we still report as
// supported here in order for the OES_depth_texture extension to be enabled.
// During draw call, the filter modes will be converted to nearest.
case angle::FormatID::D16_UNORM:
case angle::FormatID::D24_UNORM_S8_UINT:
case angle::FormatID::D32_FLOAT_S8X24_UINT:
case angle::FormatID::D32_FLOAT:
case angle::FormatID::D32_UNORM:
caps->texturable = caps->filterable = caps->textureAttachment = caps->renderbuffer =
true;
return true;
......@@ -112,11 +120,13 @@ void GenerateTextureCapsMap(const FormatTable &formatTable,
tmpTextureExtensions.compressedTexturePVRTCsRGB = true;
}
#endif
tmpTextureExtensions.sRGB = true;
tmpTextureExtensions.depth32 = true;
tmpTextureExtensions.depth24OES = true;
tmpTextureExtensions.rgb8rgba8 = true;
tmpTextureExtensions.textureStorage = true;
tmpTextureExtensions.sRGB = true;
tmpTextureExtensions.depth32 = true;
tmpTextureExtensions.depth24OES = true;
tmpTextureExtensions.rgb8rgba8 = true;
tmpTextureExtensions.textureStorage = true;
tmpTextureExtensions.depthTextureOES = true;
tmpTextureExtensions.depthTextureANGLE = true;
auto formatVerifier = [&](const gl::InternalFormat &internalFormatInfo) {
angle::FormatID angleFormatId =
......@@ -146,14 +156,6 @@ void GenerateTextureCapsMap(const FormatTable &formatTable,
textureCaps.sampleCounts.insert(0);
textureCaps.sampleCounts.insert(1);
if (textureCaps.filterable && mtlFormat.actualFormatId == angle::FormatID::D32_FLOAT)
{
// Only MacOS support filterable for D32_FLOAT texture
#if !TARGET_OS_OSX || TARGET_OS_MACCATALYST
textureCaps.filterable = false;
#endif
}
textureCapsMap.set(mtlFormat.intendedFormatId, textureCaps);
if (intendedAngleFormat.isBlock)
......
......@@ -112,6 +112,9 @@ class Texture final : public Resource,
static TextureRef MakeFromMetal(id<MTLTexture> metalTexture);
// Allow CPU to read & write data directly to this texture?
bool isCPUAccessible() const;
void replaceRegion(ContextMtl *context,
MTLRegion region,
uint32_t mipmapLevel,
......@@ -130,6 +133,8 @@ class Texture final : public Resource,
TextureRef createCubeFaceView(uint32_t face);
// Create a view of one slice at a level.
TextureRef createSliceMipView(uint32_t slice, uint32_t level);
// Create a view with different format
TextureRef createViewWithDifferentFormat(MTLPixelFormat format);
MTLTextureType textureType() const;
MTLPixelFormat pixelFormat() const;
......@@ -163,6 +168,7 @@ class Texture final : public Resource,
bool supportTextureView);
// Create a texture view
Texture(Texture *original, MTLPixelFormat format);
Texture(Texture *original, MTLTextureType type, NSRange mipmapLevelRange, uint32_t slice);
void syncContent(ContextMtl *context);
......
......@@ -201,6 +201,18 @@ Texture::Texture(ContextMtl *context,
}
}
Texture::Texture(Texture *original, MTLPixelFormat format)
: Resource(original),
mColorWritableMask(original->mColorWritableMask) // Share color write mask property
{
ANGLE_MTL_OBJC_SCOPE
{
auto view = [original->get() newTextureViewWithPixelFormat:format];
set([view ANGLE_MTL_AUTORELEASE]);
}
}
Texture::Texture(Texture *original, MTLTextureType type, NSRange mipmapLevelRange, uint32_t slice)
: Resource(original),
mColorWritableMask(original->mColorWritableMask) // Share color write mask property
......@@ -242,6 +254,17 @@ void Texture::syncContent(ContextMtl *context)
#endif
}
bool Texture::isCPUAccessible() const
{
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
if (get().storageMode == MTLStorageModeManaged)
{
return true;
}
#endif
return get().storageMode == MTLStorageModeShared;
}
void Texture::replaceRegion(ContextMtl *context,
MTLRegion region,
uint32_t mipmapLevel,
......@@ -253,6 +276,9 @@ void Texture::replaceRegion(ContextMtl *context,
{
return;
}
ASSERT(isCPUAccessible());
CommandQueue &cmdQueue = context->cmdQueue();
syncContent(context);
......@@ -279,6 +305,8 @@ void Texture::getBytes(ContextMtl *context,
uint32_t mipmapLevel,
uint8_t *dataOut)
{
ASSERT(isCPUAccessible());
CommandQueue &cmdQueue = context->cmdQueue();
syncContent(context);
......@@ -327,6 +355,11 @@ TextureRef Texture::createSliceMipView(uint32_t slice, uint32_t level)
}
}
TextureRef Texture::createViewWithDifferentFormat(MTLPixelFormat format)
{
return TextureRef(new Texture(this, format));
}
MTLPixelFormat Texture::pixelFormat() const
{
return get().pixelFormat;
......
......@@ -48,6 +48,10 @@ struct StencilDesc
struct DepthStencilDesc
{
DepthStencilDesc();
DepthStencilDesc(const DepthStencilDesc &src);
DepthStencilDesc(DepthStencilDesc &&src);
DepthStencilDesc &operator=(const DepthStencilDesc &src);
bool operator==(const DepthStencilDesc &rhs) const;
......@@ -78,9 +82,13 @@ struct DepthStencilDesc
struct SamplerDesc
{
SamplerDesc();
SamplerDesc(const SamplerDesc &src);
SamplerDesc(SamplerDesc &&src);
explicit SamplerDesc(const gl::SamplerState &glState);
SamplerDesc &operator=(const SamplerDesc &src);
// Set default values. All filters are nearest, and addresModes are clamp to edge.
void reset();
......@@ -207,6 +215,10 @@ constexpr PrimitiveTopologyClass kPrimitiveTopologyClassPoint = MTLPrimitiveTopo
struct RenderPipelineDesc
{
RenderPipelineDesc();
RenderPipelineDesc(const RenderPipelineDesc &src);
RenderPipelineDesc(RenderPipelineDesc &&src);
RenderPipelineDesc &operator=(const RenderPipelineDesc &src);
bool operator==(const RenderPipelineDesc &rhs) const;
......
......@@ -245,6 +245,20 @@ DepthStencilDesc::DepthStencilDesc()
{
memset(this, 0, sizeof(*this));
}
DepthStencilDesc::DepthStencilDesc(const DepthStencilDesc &src)
{
memcpy(this, &src, sizeof(*this));
}
DepthStencilDesc::DepthStencilDesc(DepthStencilDesc &&src)
{
memcpy(this, &src, sizeof(*this));
}
DepthStencilDesc &DepthStencilDesc::operator=(const DepthStencilDesc &src)
{
memcpy(this, &src, sizeof(*this));
return *this;
}
bool DepthStencilDesc::operator==(const DepthStencilDesc &rhs) const
{
......@@ -388,6 +402,14 @@ SamplerDesc::SamplerDesc()
{
memset(this, 0, sizeof(*this));
}
SamplerDesc::SamplerDesc(const SamplerDesc &src)
{
memcpy(this, &src, sizeof(*this));
}
SamplerDesc::SamplerDesc(SamplerDesc &&src)
{
memcpy(this, &src, sizeof(*this));
}
SamplerDesc::SamplerDesc(const gl::SamplerState &glState) : SamplerDesc()
{
......@@ -402,6 +424,12 @@ SamplerDesc::SamplerDesc(const gl::SamplerState &glState) : SamplerDesc()
maxAnisotropy = static_cast<uint32_t>(glState.getMaxAnisotropy());
}
SamplerDesc &SamplerDesc::operator=(const SamplerDesc &src)
{
memcpy(this, &src, sizeof(*this));
return *this;
}
void SamplerDesc::reset()
{
rAddressMode = MTLSamplerAddressModeClampToEdge;
......@@ -570,12 +598,28 @@ RenderPipelineDesc::RenderPipelineDesc()
rasterizationEnabled = true;
}
bool RenderPipelineDesc::operator==(const RenderPipelineDesc &rhs) const
RenderPipelineDesc::RenderPipelineDesc(const RenderPipelineDesc &src)
{
memcpy(this, &src, sizeof(*this));
}
RenderPipelineDesc::RenderPipelineDesc(RenderPipelineDesc &&src)
{
return ANGLE_PROP_EQ(*this, rhs, vertexDescriptor) &&
ANGLE_PROP_EQ(*this, rhs, outputDescriptor) &&
memcpy(this, &src, sizeof(*this));
}
RenderPipelineDesc &RenderPipelineDesc::operator=(const RenderPipelineDesc &src)
{
memcpy(this, &src, sizeof(*this));
return *this;
}
ANGLE_PROP_EQ(*this, rhs, inputPrimitiveTopology);
bool RenderPipelineDesc::operator==(const RenderPipelineDesc &rhs) const
{
// NOTE(hqle): Use a faster way to compare, i.e take into account
// the number of active vertex attributes & render targets.
// If that way is used, hash() method must be changed also.
return memcmp(this, &rhs, sizeof(*this)) == 0;
}
size_t RenderPipelineDesc::hash() const
......
......@@ -704,14 +704,14 @@ TEST_P(DepthStencilFormatsTest, VerifyDepthStencilUploadData)
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glStencilFunc(GL_EQUAL, kStencilRef, 0xFF);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
glClear(GL_COLOR_BUFFER_BIT);
drawQuad(program.get(), essl1_shaders::PositionAttrib(), 1.0f);
ASSERT_GL_NO_ERROR();
glBindFramebuffer(GL_READ_FRAMEBUFFER, fb);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::red);
ASSERT_GL_NO_ERROR();
......@@ -735,6 +735,152 @@ TEST_P(DepthStencilFormatsTest, VerifyDepthStencilUploadData)
EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::black);
}
// Verify that depth texture's data can be uploaded correctly
TEST_P(DepthStencilFormatsTest, VerifyDepth32UploadData)
{
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_depth_texture"));
GLTexture tex;
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
ASSERT_GL_NO_ERROR();
// normalized 0.99 = 0xfd70a3d6
std::vector<GLuint> depthData(1, 0xfd70a3d6);
GLTexture rbDepth;
glBindTexture(GL_TEXTURE_2D, rbDepth);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1, 1, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
depthData.data());
ASSERT_GL_NO_ERROR();
GLFramebuffer fbo;
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rbDepth, 0);
EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
ASSERT_GL_NO_ERROR();
ANGLE_GL_PROGRAM(programRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_GEQUAL);
glClearColor(0, 1, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
// Fail Depth Test and color buffer is unchanged
float depthValue = 0.98f;
drawQuad(programRed.get(), essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
// Pass Depth Test and draw red
depthValue = 1.0f;
drawQuad(programRed.get(), essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
ASSERT_GL_NO_ERROR();
// Change depth texture data
glBindTexture(GL_TEXTURE_2D, rbDepth);
depthData[0] = 0x7fffffff; // 0.5
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
depthData.data());
ASSERT_GL_NO_ERROR();
ANGLE_GL_PROGRAM(programGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
// Fail Depth Test and color buffer is unchanged
depthValue = 0.48f;
drawQuad(programGreen.get(), essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
ASSERT_GL_NO_ERROR();
ANGLE_GL_PROGRAM(programBlue, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
glClearDepthf(0.0f);
glClear(GL_DEPTH_BUFFER_BIT);
// Pass Depth Test and draw blue
depthValue = 0.01f;
drawQuad(programBlue.get(), essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
glDisable(GL_DEPTH_TEST);
ASSERT_GL_NO_ERROR();
}
// Verify that 16 bits depth texture's data can be uploaded correctly
TEST_P(DepthStencilFormatsTest, VerifyDepth16UploadData)
{
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_depth_texture"));
GLTexture tex;
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
ASSERT_GL_NO_ERROR();
// normalized 0.99 = 0xfd6f
std::vector<GLushort> depthData(1, 0xfd6f);
GLTexture rbDepth;
glBindTexture(GL_TEXTURE_2D, rbDepth);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1, 1, 0, GL_DEPTH_COMPONENT,
GL_UNSIGNED_SHORT, depthData.data());
ASSERT_GL_NO_ERROR();
GLFramebuffer fbo;
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rbDepth, 0);
EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
ASSERT_GL_NO_ERROR();
ANGLE_GL_PROGRAM(programRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_GEQUAL);
glClearColor(0, 1, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
// Fail Depth Test and color buffer is unchanged
float depthValue = 0.98f;
drawQuad(programRed.get(), essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
// Pass Depth Test and draw red
depthValue = 1.0f;
drawQuad(programRed.get(), essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
ASSERT_GL_NO_ERROR();
// Change depth texture data
glBindTexture(GL_TEXTURE_2D, rbDepth);
depthData[0] = 0x7fff; // 0.5
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
depthData.data());
ASSERT_GL_NO_ERROR();
ANGLE_GL_PROGRAM(programGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
// Fail Depth Test and color buffer is unchanged
depthValue = 0.48f;
drawQuad(programGreen.get(), essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
ASSERT_GL_NO_ERROR();
ANGLE_GL_PROGRAM(programBlue, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
glClearDepthf(0.0f);
glClear(GL_DEPTH_BUFFER_BIT);
// Pass Depth Test and draw blue
depthValue = 0.01f;
drawQuad(programBlue.get(), essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
glDisable(GL_DEPTH_TEST);
ASSERT_GL_NO_ERROR();
}
// Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against.
ANGLE_INSTANTIATE_TEST_ES2(DepthStencilFormatsTest);
......
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