Commit b83b0f5e by Alexis Hetu Committed by Commit Bot

Add support for NV_read_depth, NV_read_stencil and NV_depth_buffer_float2 extensions

This cl adds the ability for the ReadPixels function to read other attachments than the color attachment. Checks were added for both depth and stencil attachments. A new test was added (DepthStencilFormatsTest.DepthStencilReadback) to test this new functionality. As the name mentions, it's used to test reading from the depth and stencil attachments using ReadPixels. Bug: angleproject:4295 Change-Id: I6fe9be11f05d6055a5883b4315f870e7c0ac41ad Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2031702 Commit-Queue: Alexis Hétu <sugoi@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 7939e367
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
"src/libANGLE/es3_format_type_combinations.json": "src/libANGLE/es3_format_type_combinations.json":
"b44b222c27eea6839c0da3076ee540fc", "b44b222c27eea6839c0da3076ee540fc",
"src/libANGLE/format_map_autogen.cpp": "src/libANGLE/format_map_autogen.cpp":
"e0dedb4a47ca7eab2d33d20430a30d05", "d30939d53e3a549416e9a893b170e344",
"src/libANGLE/format_map_data.json": "src/libANGLE/format_map_data.json":
"2edab4db12a1cc131f26e0e5680b7d0c", "742cf47524160757a2cec43116dc153c",
"src/libANGLE/gen_format_map.py": "src/libANGLE/gen_format_map.py":
"38320d844e6629e09afc5ccdc484e9aa", "38320d844e6629e09afc5ccdc484e9aa",
"src/libANGLE/renderer/angle_format.py": "src/libANGLE/renderer/angle_format.py":
......
...@@ -223,19 +223,32 @@ static bool DeterminePackedDepthStencilSupport(const TextureCapsMap &textureCaps ...@@ -223,19 +223,32 @@ static bool DeterminePackedDepthStencilSupport(const TextureCapsMap &textureCaps
// Checks for GL_NV_read_depth support // Checks for GL_NV_read_depth support
static bool DetermineReadDepthSupport(const TextureCapsMap &textureCaps) static bool DetermineReadDepthSupport(const TextureCapsMap &textureCaps)
{ {
return false; constexpr GLenum requiredFormats[] = {
GL_DEPTH_COMPONENT16,
};
return GetFormatSupport(textureCaps, requiredFormats, true, false, true, false, false);
} }
// Checks for GL_NV_read_stencil support // Checks for GL_NV_read_stencil support
static bool DetermineReadStencilSupport(const TextureCapsMap &textureCaps) static bool DetermineReadStencilSupport(const TextureCapsMap &textureCaps)
{ {
return false; constexpr GLenum requiredFormats[] = {
GL_STENCIL_INDEX8,
};
return GetFormatSupport(textureCaps, requiredFormats, false, false, true, false, false);
} }
// Checks for GL_NV_depth_buffer_float2 support // Checks for GL_NV_depth_buffer_float2 support
static bool DetermineDepthBufferFloat2Support(const TextureCapsMap &textureCaps) static bool DetermineDepthBufferFloat2Support(const TextureCapsMap &textureCaps)
{ {
return false; constexpr GLenum requiredFormats[] = {
GL_DEPTH_COMPONENT32F,
GL_DEPTH32F_STENCIL8,
};
return GetFormatSupport(textureCaps, requiredFormats, true, false, true, false, false);
} }
// Checks for GL_OES_rgb8_rgba8 support // Checks for GL_OES_rgb8_rgba8 support
...@@ -850,9 +863,9 @@ const ExtensionInfoMap &GetExtensionInfoMap() ...@@ -850,9 +863,9 @@ const ExtensionInfoMap &GetExtensionInfoMap()
map["GL_OES_packed_depth_stencil"] = esOnlyExtension(&Extensions::packedDepthStencilOES); map["GL_OES_packed_depth_stencil"] = esOnlyExtension(&Extensions::packedDepthStencilOES);
map["GL_OES_get_program_binary"] = enableableExtension(&Extensions::getProgramBinaryOES); map["GL_OES_get_program_binary"] = enableableExtension(&Extensions::getProgramBinaryOES);
map["GL_OES_rgb8_rgba8"] = enableableExtension(&Extensions::rgb8rgba8OES); map["GL_OES_rgb8_rgba8"] = enableableExtension(&Extensions::rgb8rgba8OES);
map["GL_NV_read_depth"] = esOnlyExtension(&Extensions::readDepthNV); map["GL_NV_read_depth"] = enableableExtension(&Extensions::readDepthNV);
map["GL_NV_read_stencil"] = esOnlyExtension(&Extensions::readStencilNV); map["GL_NV_read_stencil"] = enableableExtension(&Extensions::readStencilNV);
map["GL_NV_depth_buffer_float2"] = esOnlyExtension(&Extensions::depthBufferFloat2NV); map["GL_NV_depth_buffer_float2"] = enableableExtension(&Extensions::depthBufferFloat2NV);
map["GL_EXT_texture_format_BGRA8888"] = enableableExtension(&Extensions::textureFormatBGRA8888); map["GL_EXT_texture_format_BGRA8888"] = enableableExtension(&Extensions::textureFormatBGRA8888);
map["GL_EXT_texture_type_2_10_10_10_REV"] = enableableExtension(&Extensions::textureFormat2101010REV); map["GL_EXT_texture_type_2_10_10_10_REV"] = enableableExtension(&Extensions::textureFormat2101010REV);
map["GL_EXT_read_format_bgra"] = enableableExtension(&Extensions::readFormatBGRA); map["GL_EXT_read_format_bgra"] = enableableExtension(&Extensions::readFormatBGRA);
......
...@@ -432,6 +432,19 @@ const FramebufferAttachment *FramebufferState::getReadAttachment() const ...@@ -432,6 +432,19 @@ const FramebufferAttachment *FramebufferState::getReadAttachment() const
return framebufferAttachment.isAttached() ? &framebufferAttachment : nullptr; return framebufferAttachment.isAttached() ? &framebufferAttachment : nullptr;
} }
const FramebufferAttachment *FramebufferState::getReadPixelsAttachment(GLenum readFormat) const
{
switch (readFormat)
{
case GL_DEPTH_COMPONENT:
return getDepthAttachment();
case GL_STENCIL_INDEX_OES:
return getStencilOrDepthStencilAttachment();
default:
return getReadAttachment();
}
}
const FramebufferAttachment *FramebufferState::getFirstNonNullAttachment() const const FramebufferAttachment *FramebufferState::getFirstNonNullAttachment() const
{ {
auto *colorAttachment = getFirstColorAttachment(); auto *colorAttachment = getFirstColorAttachment();
......
...@@ -78,6 +78,7 @@ class FramebufferState final : angle::NonCopyable ...@@ -78,6 +78,7 @@ class FramebufferState final : angle::NonCopyable
const FramebufferAttachment *getDepthAttachment() const; const FramebufferAttachment *getDepthAttachment() const;
const FramebufferAttachment *getStencilAttachment() const; const FramebufferAttachment *getStencilAttachment() const;
const FramebufferAttachment *getDepthStencilAttachment() const; const FramebufferAttachment *getDepthStencilAttachment() const;
const FramebufferAttachment *getReadPixelsAttachment(GLenum readFormat) const;
const std::vector<GLenum> &getDrawBufferStates() const { return mDrawBufferStates; } const std::vector<GLenum> &getDrawBufferStates() const { return mDrawBufferStates; }
DrawBufferMask getEnabledDrawBuffers() const { return mEnabledDrawBuffers; } DrawBufferMask getEnabledDrawBuffers() const { return mEnabledDrawBuffers; }
......
...@@ -299,6 +299,8 @@ GLenum GetSizedFormatInternal(GLenum format, GLenum type) ...@@ -299,6 +299,8 @@ GLenum GetSizedFormatInternal(GLenum format, GLenum type)
return GL_DEPTH_COMPONENT32F; return GL_DEPTH_COMPONENT32F;
case GL_UNSIGNED_INT: case GL_UNSIGNED_INT:
return GL_DEPTH_COMPONENT32_OES; return GL_DEPTH_COMPONENT32_OES;
case GL_UNSIGNED_INT_24_8:
return GL_DEPTH24_STENCIL8;
case GL_UNSIGNED_SHORT: case GL_UNSIGNED_SHORT:
return GL_DEPTH_COMPONENT16; return GL_DEPTH_COMPONENT16;
default: default:
...@@ -564,6 +566,16 @@ GLenum GetSizedFormatInternal(GLenum format, GLenum type) ...@@ -564,6 +566,16 @@ GLenum GetSizedFormatInternal(GLenum format, GLenum type)
} }
break; break;
case GL_STENCIL_INDEX_OES:
switch (type)
{
case GL_UNSIGNED_BYTE:
return GL_STENCIL_INDEX8;
default:
break;
}
break;
case GL_NONE: case GL_NONE:
return GL_NONE; return GL_NONE;
......
...@@ -155,11 +155,15 @@ ...@@ -155,11 +155,15 @@
"GL_DEPTH_COMPONENT": { "GL_DEPTH_COMPONENT": {
"GL_UNSIGNED_SHORT": "GL_DEPTH_COMPONENT16", "GL_UNSIGNED_SHORT": "GL_DEPTH_COMPONENT16",
"GL_UNSIGNED_INT": "GL_DEPTH_COMPONENT32_OES", "GL_UNSIGNED_INT": "GL_DEPTH_COMPONENT32_OES",
"GL_UNSIGNED_INT_24_8": "GL_DEPTH24_STENCIL8",
"GL_FLOAT": "GL_DEPTH_COMPONENT32F" "GL_FLOAT": "GL_DEPTH_COMPONENT32F"
}, },
"GL_STENCIL": { "GL_STENCIL": {
"GL_UNSIGNED_BYTE": "GL_STENCIL_INDEX8" "GL_UNSIGNED_BYTE": "GL_STENCIL_INDEX8"
}, },
"GL_STENCIL_INDEX_OES": {
"GL_UNSIGNED_BYTE": "GL_STENCIL_INDEX8"
},
"GL_DEPTH_STENCIL": { "GL_DEPTH_STENCIL": {
"GL_UNSIGNED_INT_24_8": "GL_DEPTH24_STENCIL8", "GL_UNSIGNED_INT_24_8": "GL_DEPTH24_STENCIL8",
"GL_FLOAT_32_UNSIGNED_INT_24_8_REV": "GL_DEPTH32F_STENCIL8" "GL_FLOAT_32_UNSIGNED_INT_24_8_REV": "GL_DEPTH32F_STENCIL8"
......
...@@ -852,7 +852,7 @@ static InternalFormatInfoMap BuildInternalFormatInfoMap() ...@@ -852,7 +852,7 @@ static InternalFormatInfoMap BuildInternalFormatInfoMap()
AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT32F, true, 32, 0, 0, GL_DEPTH_COMPONENT, GL_FLOAT, GL_FLOAT, RequireES<3, 0>, RequireESOrExt<3, 0, &Extensions::depthTextureANGLE>, RequireES<3, 0>, RequireES<3, 0>, RequireES<3, 0>); AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT32F, true, 32, 0, 0, GL_DEPTH_COMPONENT, GL_FLOAT, GL_FLOAT, RequireES<3, 0>, RequireESOrExt<3, 0, &Extensions::depthTextureANGLE>, RequireES<3, 0>, RequireES<3, 0>, RequireES<3, 0>);
AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT32_OES, true, 32, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>, AlwaysSupported, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>, RequireExtOrExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES, &Extensions::depth32OES>, RequireExtOrExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES, &Extensions::depth32OES>); AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT32_OES, true, 32, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>, AlwaysSupported, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>, RequireExtOrExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES, &Extensions::depth32OES>, RequireExtOrExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES, &Extensions::depth32OES>);
AddDepthStencilFormat(&map, GL_DEPTH24_STENCIL8, true, 24, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_NORMALIZED, RequireESOrExt<3, 0, &Extensions::depthTextureANGLE>, AlwaysSupported, RequireESOrExtOrExt<3, 0, &Extensions::depthTextureANGLE, &Extensions::packedDepthStencilOES>, RequireESOrExtOrExt<3, 0, &Extensions::depthTextureANGLE, &Extensions::packedDepthStencilOES>, RequireESOrExtOrExt<3, 0, &Extensions::depthTextureANGLE, &Extensions::packedDepthStencilOES>); AddDepthStencilFormat(&map, GL_DEPTH24_STENCIL8, true, 24, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_NORMALIZED, RequireESOrExt<3, 0, &Extensions::depthTextureANGLE>, AlwaysSupported, RequireESOrExtOrExt<3, 0, &Extensions::depthTextureANGLE, &Extensions::packedDepthStencilOES>, RequireESOrExtOrExt<3, 0, &Extensions::depthTextureANGLE, &Extensions::packedDepthStencilOES>, RequireESOrExtOrExt<3, 0, &Extensions::depthTextureANGLE, &Extensions::packedDepthStencilOES>);
AddDepthStencilFormat(&map, GL_DEPTH32F_STENCIL8, true, 32, 8, 24, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_FLOAT, RequireES<3, 0>, AlwaysSupported, RequireES<3, 0>, RequireES<3, 0>, RequireES<3, 0>); AddDepthStencilFormat(&map, GL_DEPTH32F_STENCIL8, true, 32, 8, 24, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_FLOAT, RequireESOrExt<3, 0, &Extensions::depthBufferFloat2NV>, AlwaysSupported, RequireESOrExt<3, 0, &Extensions::depthBufferFloat2NV>, RequireESOrExt<3, 0, &Extensions::depthBufferFloat2NV>, RequireESOrExt<3, 0, &Extensions::depthBufferFloat2NV>);
// STENCIL_INDEX8 is special-cased, see around the bottom of the list. // STENCIL_INDEX8 is special-cased, see around the bottom of the list.
// Luminance alpha formats // Luminance alpha formats
...@@ -1097,9 +1097,11 @@ static InternalFormatInfoMap BuildInternalFormatInfoMap() ...@@ -1097,9 +1097,11 @@ static InternalFormatInfoMap BuildInternalFormatInfoMap()
AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT, false, 16, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, RequireES<1, 0>, AlwaysSupported, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>); AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT, false, 16, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, RequireES<1, 0>, AlwaysSupported, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>);
AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT, false, 24, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireES<1, 0>, AlwaysSupported, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>); AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT, false, 24, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireES<1, 0>, AlwaysSupported, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>);
AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT, false, 32, 0, 0, GL_DEPTH_COMPONENT, GL_FLOAT, GL_FLOAT, RequireES<1, 0>, AlwaysSupported, RequireES<1, 0>, RequireES<1, 0>, RequireES<1, 0>); AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT, false, 32, 0, 0, GL_DEPTH_COMPONENT, GL_FLOAT, GL_FLOAT, RequireES<1, 0>, AlwaysSupported, RequireES<1, 0>, RequireES<1, 0>, RequireES<1, 0>);
AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT, false, 24, 8, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_NORMALIZED, RequireESOrExt<3, 0, &Extensions::packedDepthStencilOES>, AlwaysSupported, RequireExtAndExt<&Extensions::packedDepthStencilOES, &Extensions::depthTextureANGLE>, RequireExtAndExt<&Extensions::packedDepthStencilOES, &Extensions::depthTextureANGLE>, RequireExtAndExt<&Extensions::packedDepthStencilOES, &Extensions::depthTextureANGLE>);
AddDepthStencilFormat(&map, GL_DEPTH_STENCIL, false, 24, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_NORMALIZED, RequireESOrExt<3, 0, &Extensions::packedDepthStencilOES>, AlwaysSupported, RequireExtAndExt<&Extensions::packedDepthStencilOES, &Extensions::depthTextureANGLE>, RequireExtAndExt<&Extensions::packedDepthStencilOES, &Extensions::depthTextureANGLE>, RequireExtAndExt<&Extensions::packedDepthStencilOES, &Extensions::depthTextureANGLE>); AddDepthStencilFormat(&map, GL_DEPTH_STENCIL, false, 24, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_NORMALIZED, RequireESOrExt<3, 0, &Extensions::packedDepthStencilOES>, AlwaysSupported, RequireExtAndExt<&Extensions::packedDepthStencilOES, &Extensions::depthTextureANGLE>, RequireExtAndExt<&Extensions::packedDepthStencilOES, &Extensions::depthTextureANGLE>, RequireExtAndExt<&Extensions::packedDepthStencilOES, &Extensions::depthTextureANGLE>);
AddDepthStencilFormat(&map, GL_DEPTH_STENCIL, false, 32, 8, 24, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_FLOAT, RequireESOrExt<3, 0, &Extensions::packedDepthStencilOES>, AlwaysSupported, RequireExt<&Extensions::packedDepthStencilOES>, RequireExt<&Extensions::packedDepthStencilOES>, RequireExt<&Extensions::packedDepthStencilOES>); AddDepthStencilFormat(&map, GL_DEPTH_STENCIL, false, 32, 8, 24, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_FLOAT, RequireESOrExt<3, 0, &Extensions::packedDepthStencilOES>, AlwaysSupported, RequireExt<&Extensions::packedDepthStencilOES>, RequireExt<&Extensions::packedDepthStencilOES>, RequireExt<&Extensions::packedDepthStencilOES>);
AddDepthStencilFormat(&map, GL_STENCIL, false, 0, 8, 0, GL_STENCIL, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireES<1, 0>, NeverSupported , RequireES<1, 0>, RequireES<1, 0>, RequireES<1, 0>); AddDepthStencilFormat(&map, GL_STENCIL, false, 0, 8, 0, GL_STENCIL, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireES<1, 0>, NeverSupported , RequireES<1, 0>, RequireES<1, 0>, RequireES<1, 0>);
AddDepthStencilFormat(&map, GL_STENCIL_INDEX, false, 0, 8, 0, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireES<3, 1>, NeverSupported , RequireES<3, 1>, RequireES<3, 1>, RequireES<3, 1>);
// clang-format on // clang-format on
return map; return map;
......
...@@ -239,7 +239,7 @@ angle::Result FramebufferD3D::readPixels(const gl::Context *context, ...@@ -239,7 +239,7 @@ angle::Result FramebufferD3D::readPixels(const gl::Context *context,
void *pixels) void *pixels)
{ {
// Clip read area to framebuffer. // Clip read area to framebuffer.
const gl::Extents fbSize = getState().getReadAttachment()->getSize(); const gl::Extents fbSize = getState().getReadPixelsAttachment(format)->getSize();
const gl::Rectangle fbRect(0, 0, fbSize.width, fbSize.height); const gl::Rectangle fbRect(0, 0, fbSize.width, fbSize.height);
gl::Rectangle clippedArea; gl::Rectangle clippedArea;
if (!ClipRectangle(area, fbRect, &clippedArea)) if (!ClipRectangle(area, fbRect, &clippedArea))
......
...@@ -253,7 +253,7 @@ angle::Result Framebuffer11::readPixelsImpl(const gl::Context *context, ...@@ -253,7 +253,7 @@ angle::Result Framebuffer11::readPixelsImpl(const gl::Context *context,
const gl::PixelPackState &pack, const gl::PixelPackState &pack,
uint8_t *pixels) uint8_t *pixels)
{ {
const gl::FramebufferAttachment *readAttachment = mState.getReadAttachment(); const gl::FramebufferAttachment *readAttachment = mState.getReadPixelsAttachment(format);
ASSERT(readAttachment); ASSERT(readAttachment);
gl::Buffer *packBuffer = context->getState().getTargetBuffer(gl::BufferBinding::PixelPack); gl::Buffer *packBuffer = context->getState().getTargetBuffer(gl::BufferBinding::PixelPack);
......
...@@ -1654,6 +1654,11 @@ void GenerateCaps(ID3D11Device *device, ...@@ -1654,6 +1654,11 @@ void GenerateCaps(ID3D11Device *device,
// It treats it as a red-channel-only texture. // It treats it as a red-channel-only texture.
extensions->depthTextureOES = false; extensions->depthTextureOES = false;
// readPixels on depth & stencil not working with D3D11 backend.
extensions->readDepthNV = false;
extensions->readStencilNV = false;
extensions->depthBufferFloat2NV = false;
// D3D11 Feature Level 10_0+ uses SV_IsFrontFace in HLSL to emulate gl_FrontFacing. // D3D11 Feature Level 10_0+ uses SV_IsFrontFace in HLSL to emulate gl_FrontFacing.
// D3D11 Feature Level 9_3 doesn't support SV_IsFrontFace, and has no equivalent, so can't // D3D11 Feature Level 9_3 doesn't support SV_IsFrontFace, and has no equivalent, so can't
// support gl_FrontFacing. // support gl_FrontFacing.
......
...@@ -374,6 +374,12 @@ angle::Result RearrangeEXTTextureNorm16Pixels(const gl::Context *context, ...@@ -374,6 +374,12 @@ angle::Result RearrangeEXTTextureNorm16Pixels(const gl::Context *context,
return angle::Result::Continue; return angle::Result::Continue;
} }
bool IsValidUnsignedShortReadPixelsFormat(GLenum readFormat, const gl::Context *context)
{
return (readFormat == GL_RED) || (readFormat == GL_RG) || (readFormat == GL_RGBA) ||
((readFormat == GL_DEPTH_COMPONENT) && (context->getExtensions().readDepthNV));
}
} // namespace } // namespace
FramebufferGL::FramebufferGL(const gl::FramebufferState &data, FramebufferGL::FramebufferGL(const gl::FramebufferState &data,
...@@ -627,7 +633,7 @@ angle::Result FramebufferGL::readPixels(const gl::Context *context, ...@@ -627,7 +633,7 @@ angle::Result FramebufferGL::readPixels(const gl::Context *context,
const angle::FeaturesGL &features = GetFeaturesGL(context); const angle::FeaturesGL &features = GetFeaturesGL(context);
// Clip read area to framebuffer. // Clip read area to framebuffer.
const auto *readAttachment = mState.getReadAttachment(); const auto *readAttachment = mState.getReadPixelsAttachment(format);
const gl::Extents fbSize = readAttachment->getSize(); const gl::Extents fbSize = readAttachment->getSize();
const gl::Rectangle fbRect(0, 0, fbSize.width, fbSize.height); const gl::Rectangle fbRect(0, 0, fbSize.width, fbSize.height);
gl::Rectangle clippedArea; gl::Rectangle clippedArea;
...@@ -650,7 +656,7 @@ angle::Result FramebufferGL::readPixels(const gl::Context *context, ...@@ -650,7 +656,7 @@ angle::Result FramebufferGL::readPixels(const gl::Context *context,
if (features.readPixelsUsingImplementationColorReadFormatForNorm16.enabled && if (features.readPixelsUsingImplementationColorReadFormatForNorm16.enabled &&
readType == GL_UNSIGNED_SHORT) readType == GL_UNSIGNED_SHORT)
{ {
ANGLE_CHECK(contextGL, readFormat == GL_RED || readFormat == GL_RG || readFormat == GL_RGBA, ANGLE_CHECK(contextGL, IsValidUnsignedShortReadPixelsFormat(readFormat, context),
"glReadPixels: GL_IMPLEMENTATION_COLOR_READ_FORMAT advertised by the driver is " "glReadPixels: GL_IMPLEMENTATION_COLOR_READ_FORMAT advertised by the driver is "
"not handled by RGBA16 readPixels workaround.", "not handled by RGBA16 readPixels workaround.",
GL_INVALID_OPERATION); GL_INVALID_OPERATION);
......
...@@ -618,6 +618,11 @@ void DisplayMtl::initializeTextureCaps() const ...@@ -618,6 +618,11 @@ void DisplayMtl::initializeTextureCaps() const
// Re-verify texture extensions. // Re-verify texture extensions.
mNativeExtensions.setTextureExtensionSupport(mNativeTextureCaps); mNativeExtensions.setTextureExtensionSupport(mNativeTextureCaps);
// Disable all depth buffer and stencil buffer readback extensions until we need them
mNativeExtensions.readDepthNV = false;
mNativeExtensions.readStencilNV = false;
mNativeExtensions.depthBufferFloat2NV = false;
} }
void DisplayMtl::initializeFeatures() void DisplayMtl::initializeFeatures()
......
...@@ -131,7 +131,7 @@ angle::Result FramebufferNULL::readPixels(const gl::Context *context, ...@@ -131,7 +131,7 @@ angle::Result FramebufferNULL::readPixels(const gl::Context *context,
} }
// Clip read area to framebuffer. // Clip read area to framebuffer.
const gl::Extents fbSize = getState().getReadAttachment()->getSize(); const gl::Extents fbSize = getState().getReadPixelsAttachment(format)->getSize();
const gl::Rectangle fbRect(0, 0, fbSize.width, fbSize.height); const gl::Rectangle fbRect(0, 0, fbSize.width, fbSize.height);
gl::Rectangle area; gl::Rectangle area;
if (!ClipRectangle(origArea, fbRect, &area)) if (!ClipRectangle(origArea, fbRect, &area))
......
...@@ -444,7 +444,7 @@ angle::Result FramebufferVk::readPixels(const gl::Context *context, ...@@ -444,7 +444,7 @@ angle::Result FramebufferVk::readPixels(const gl::Context *context,
void *pixels) void *pixels)
{ {
// Clip read area to framebuffer. // Clip read area to framebuffer.
const gl::Extents &fbSize = getState().getReadAttachment()->getSize(); const gl::Extents &fbSize = getState().getReadPixelsAttachment(format)->getSize();
const gl::Rectangle fbRect(0, 0, fbSize.width, fbSize.height); const gl::Rectangle fbRect(0, 0, fbSize.width, fbSize.height);
ContextVk *contextVk = vk::GetImpl(context); ContextVk *contextVk = vk::GetImpl(context);
...@@ -470,8 +470,8 @@ angle::Result FramebufferVk::readPixels(const gl::Context *context, ...@@ -470,8 +470,8 @@ angle::Result FramebufferVk::readPixels(const gl::Context *context,
params.reverseRowOrder = !params.reverseRowOrder; params.reverseRowOrder = !params.reverseRowOrder;
} }
ANGLE_TRY(readPixelsImpl(contextVk, params.area, params, VK_IMAGE_ASPECT_COLOR_BIT, ANGLE_TRY(readPixelsImpl(contextVk, params.area, params, getReadPixelsAspectFlags(format),
getColorReadRenderTarget(), getReadPixelsRenderTarget(format),
static_cast<uint8_t *>(pixels) + outputSkipBytes)); static_cast<uint8_t *>(pixels) + outputSkipBytes));
mReadPixelBuffer.releaseInFlightBuffers(contextVk); mReadPixelBuffer.releaseInFlightBuffers(contextVk);
return angle::Result::Continue; return angle::Result::Continue;
...@@ -498,6 +498,31 @@ RenderTargetVk *FramebufferVk::getColorReadRenderTarget() const ...@@ -498,6 +498,31 @@ RenderTargetVk *FramebufferVk::getColorReadRenderTarget() const
return renderTarget; return renderTarget;
} }
RenderTargetVk *FramebufferVk::getReadPixelsRenderTarget(GLenum format) const
{
switch (format)
{
case GL_DEPTH_COMPONENT:
case GL_STENCIL_INDEX_OES:
return getDepthStencilRenderTarget();
default:
return getColorReadRenderTarget();
}
}
VkImageAspectFlagBits FramebufferVk::getReadPixelsAspectFlags(GLenum format) const
{
switch (format)
{
case GL_DEPTH_COMPONENT:
return VK_IMAGE_ASPECT_DEPTH_BIT;
case GL_STENCIL_INDEX_OES:
return VK_IMAGE_ASPECT_STENCIL_BIT;
default:
return VK_IMAGE_ASPECT_COLOR_BIT;
}
}
angle::Result FramebufferVk::blitWithCommand(ContextVk *contextVk, angle::Result FramebufferVk::blitWithCommand(ContextVk *contextVk,
const gl::Rectangle &sourceArea, const gl::Rectangle &sourceArea,
const gl::Rectangle &destArea, const gl::Rectangle &destArea,
......
...@@ -166,6 +166,9 @@ class FramebufferVk : public FramebufferImpl ...@@ -166,6 +166,9 @@ class FramebufferVk : public FramebufferImpl
void clearCache(ContextVk *contextVk); void clearCache(ContextVk *contextVk);
void updateDepthStencilAttachmentSerial(ContextVk *contextVk); void updateDepthStencilAttachmentSerial(ContextVk *contextVk);
RenderTargetVk *getReadPixelsRenderTarget(GLenum format) const;
VkImageAspectFlagBits getReadPixelsAspectFlags(GLenum format) const;
WindowSurfaceVk *mBackbuffer; WindowSurfaceVk *mBackbuffer;
vk::RenderPassDesc mRenderPassDesc; vk::RenderPassDesc mRenderPassDesc;
......
...@@ -3371,14 +3371,16 @@ angle::Result ImageHelper::readPixels(ContextVk *contextVk, ...@@ -3371,14 +3371,16 @@ angle::Result ImageHelper::readPixels(ContextVk *contextVk,
resolvedImage.get().retain(&contextVk->getResourceUseList()); resolvedImage.get().retain(&contextVk->getResourceUseList());
} }
VkImageAspectFlags layoutChangeAspectFlags = src->getAspectFlags();
// Note that although we're reading from the image, we need to update the layout below. // Note that although we're reading from the image, we need to update the layout below.
CommandBuffer *commandBuffer; CommandBuffer *commandBuffer;
if (isMultisampled) if (isMultisampled)
{ {
ANGLE_TRY(contextVk->onImageWrite(copyAspectFlags, ImageLayout::TransferDst, ANGLE_TRY(contextVk->onImageWrite(layoutChangeAspectFlags, ImageLayout::TransferDst,
&resolvedImage.get())); &resolvedImage.get()));
} }
ANGLE_TRY(contextVk->onImageRead(copyAspectFlags, ImageLayout::TransferSrc, this)); ANGLE_TRY(contextVk->onImageRead(layoutChangeAspectFlags, ImageLayout::TransferSrc, this));
ANGLE_TRY(contextVk->endRenderPassAndGetCommandBuffer(&commandBuffer)); ANGLE_TRY(contextVk->endRenderPassAndGetCommandBuffer(&commandBuffer));
const angle::Format *readFormat = &mFormat->actualImageFormat(); const angle::Format *readFormat = &mFormat->actualImageFormat();
...@@ -3426,7 +3428,7 @@ angle::Result ImageHelper::readPixels(ContextVk *contextVk, ...@@ -3426,7 +3428,7 @@ angle::Result ImageHelper::readPixels(ContextVk *contextVk,
resolve(&resolvedImage.get(), resolveRegion, commandBuffer); resolve(&resolvedImage.get(), resolveRegion, commandBuffer);
ANGLE_TRY(contextVk->onImageRead(copyAspectFlags, ImageLayout::TransferSrc, ANGLE_TRY(contextVk->onImageRead(layoutChangeAspectFlags, ImageLayout::TransferSrc,
&resolvedImage.get())); &resolvedImage.get()));
// Make the resolved image the target of buffer copy. // Make the resolved image the target of buffer copy.
......
...@@ -161,6 +161,38 @@ bool ValidReadPixelsFormatEnum(const Context *context, GLenum format) ...@@ -161,6 +161,38 @@ bool ValidReadPixelsFormatEnum(const Context *context, GLenum format)
} }
} }
bool ValidReadPixelsUnsignedNormalizedDepthType(const Context *context,
const gl::InternalFormat *info,
GLenum type)
{
bool supportsReadDepthNV = (context->getExtensions().readDepthNV && (info->depthBits > 0) &&
(info->componentCount == 1));
bool isGLES31 = (context->getClientVersion() >= ES_3_1);
switch (type)
{
case GL_UNSIGNED_SHORT:
return supportsReadDepthNV ||
(isGLES31 && (info->sizedInternalFormat == GL_DEPTH_COMPONENT16));
case GL_UNSIGNED_INT:
return supportsReadDepthNV ||
(isGLES31 && ((info->sizedInternalFormat == GL_DEPTH_COMPONENT16) ||
(info->internalFormat == GL_DEPTH_COMPONENT24)));
case GL_UNSIGNED_INT_24_8:
return supportsReadDepthNV ||
(isGLES31 && (info->sizedInternalFormat == GL_DEPTH24_STENCIL8));
default:
return false;
}
}
bool ValidReadPixelsFloatDepthType(const Context *context,
const gl::InternalFormat *info,
GLenum type)
{
return context->getExtensions().readDepthNV && (type == GL_FLOAT) &&
context->getExtensions().depthBufferFloat2NV && (info->componentCount == 1);
}
bool ValidReadPixelsFormatType(const Context *context, bool ValidReadPixelsFormatType(const Context *context,
const gl::InternalFormat *info, const gl::InternalFormat *info,
GLenum format, GLenum format,
...@@ -171,12 +203,21 @@ bool ValidReadPixelsFormatType(const Context *context, ...@@ -171,12 +203,21 @@ bool ValidReadPixelsFormatType(const Context *context,
case GL_UNSIGNED_NORMALIZED: case GL_UNSIGNED_NORMALIZED:
// TODO(geofflang): Don't accept BGRA here. Some chrome internals appear to try to use // TODO(geofflang): Don't accept BGRA here. Some chrome internals appear to try to use
// ReadPixels with BGRA even if the extension is not present // ReadPixels with BGRA even if the extension is not present
return (format == GL_RGBA && type == GL_UNSIGNED_BYTE && info->pixelBytes >= 1) || switch (format)
(context->getExtensions().textureNorm16 && format == GL_RGBA && {
type == GL_UNSIGNED_SHORT && info->pixelBytes >= 2) || case GL_RGBA:
(context->getExtensions().readFormatBGRA && format == GL_BGRA_EXT && return ((type == GL_UNSIGNED_BYTE) && info->pixelBytes >= 1) ||
type == GL_UNSIGNED_BYTE); (context->getExtensions().textureNorm16 && (type == GL_UNSIGNED_SHORT) &&
info->pixelBytes >= 2);
case GL_BGRA_EXT:
return context->getExtensions().readFormatBGRA && (type == GL_UNSIGNED_BYTE);
case GL_STENCIL_INDEX_OES:
return context->getExtensions().readStencilNV && (type == GL_UNSIGNED_BYTE);
case GL_DEPTH_COMPONENT:
return ValidReadPixelsUnsignedNormalizedDepthType(context, info, type);
default:
return false;
}
case GL_SIGNED_NORMALIZED: case GL_SIGNED_NORMALIZED:
return (format == GL_RGBA && type == GL_BYTE && info->pixelBytes >= 1) || return (format == GL_RGBA && type == GL_BYTE && info->pixelBytes >= 1) ||
(context->getExtensions().textureNorm16 && format == GL_RGBA && (context->getExtensions().textureNorm16 && format == GL_RGBA &&
...@@ -189,8 +230,15 @@ bool ValidReadPixelsFormatType(const Context *context, ...@@ -189,8 +230,15 @@ bool ValidReadPixelsFormatType(const Context *context,
return (format == GL_RGBA_INTEGER && type == GL_UNSIGNED_INT); return (format == GL_RGBA_INTEGER && type == GL_UNSIGNED_INT);
case GL_FLOAT: case GL_FLOAT:
return (format == GL_RGBA && type == GL_FLOAT); switch (format)
{
case GL_RGBA:
return (type == GL_FLOAT);
case GL_DEPTH_COMPONENT:
return ValidReadPixelsFloatDepthType(context, info, type);
default:
return false;
}
default: default:
UNREACHABLE(); UNREACHABLE();
return false; return false;
...@@ -5620,7 +5668,20 @@ bool ValidateReadPixelsBase(const Context *context, ...@@ -5620,7 +5668,20 @@ bool ValidateReadPixelsBase(const Context *context,
return false; return false;
} }
const FramebufferAttachment *readBuffer = readFramebuffer->getReadColorAttachment(); const FramebufferAttachment *readBuffer = nullptr;
switch (format)
{
case GL_DEPTH_COMPONENT:
readBuffer = readFramebuffer->getDepthAttachment();
break;
case GL_STENCIL_INDEX_OES:
readBuffer = readFramebuffer->getStencilOrDepthStencilAttachment();
break;
default:
readBuffer = readFramebuffer->getReadColorAttachment();
break;
}
// WebGL 1.0 [Section 6.26] Reading From a Missing Attachment // WebGL 1.0 [Section 6.26] Reading From a Missing Attachment
// In OpenGL ES it is undefined what happens when an operation tries to read from a missing // In OpenGL ES it is undefined what happens when an operation tries to read from a missing
// attachment and WebGL defines it to be an error. We do the check unconditionnaly as the // attachment and WebGL defines it to be an error. We do the check unconditionnaly as the
...@@ -5663,11 +5724,21 @@ bool ValidateReadPixelsBase(const Context *context, ...@@ -5663,11 +5724,21 @@ bool ValidateReadPixelsBase(const Context *context,
} }
GLenum currentFormat = GL_NONE; GLenum currentFormat = GL_NONE;
ANGLE_VALIDATION_TRY( GLenum currentType = GL_NONE;
readFramebuffer->getImplementationColorReadFormat(context, &currentFormat));
GLenum currentType = GL_NONE; switch (format)
ANGLE_VALIDATION_TRY(readFramebuffer->getImplementationColorReadType(context, &currentType)); {
case GL_DEPTH_COMPONENT:
case GL_STENCIL_INDEX_OES:
// Only rely on ValidReadPixelsFormatType for depth/stencil formats
break;
default:
ANGLE_VALIDATION_TRY(
readFramebuffer->getImplementationColorReadFormat(context, &currentFormat));
ANGLE_VALIDATION_TRY(
readFramebuffer->getImplementationColorReadType(context, &currentType));
break;
}
bool validFormatTypeCombination = bool validFormatTypeCombination =
ValidReadPixelsFormatType(context, readBuffer->getFormat().info, format, type); ValidReadPixelsFormatType(context, readBuffer->getFormat().info, format, type);
......
...@@ -1397,6 +1397,14 @@ bool ValidateES2TexImageParametersBase(const Context *context, ...@@ -1397,6 +1397,14 @@ bool ValidateES2TexImageParametersBase(const Context *context,
case GL_UNSIGNED_SHORT: case GL_UNSIGNED_SHORT:
case GL_UNSIGNED_INT: case GL_UNSIGNED_INT:
break; break;
case GL_FLOAT:
if (!context->getExtensions().depthBufferFloat2NV)
{
context->validationError(GL_INVALID_OPERATION,
kMismatchedTypeAndFormat);
return false;
}
break;
default: default:
context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat); context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
return false; return false;
......
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