Commit 7e81056a by Mohan Maiya Committed by Commit Bot

Vulkan: Support integer type incomplete texture

Support both signed and unsigned integer type incomplete textures. Bug: angleproject:5502 Bug: angleproject:4432 Tests: IncompleteTextureTestES3.*IntegerType* dEQP.KHR_GLES31/core_sample_variables_mask_rgba8*i_* Change-Id: Ic8c972aac0ca8589b26333b66dd0cc5fb5134043 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2613245 Commit-Queue: Mohan Maiya <m.maiya@samsung.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent 572afd90
...@@ -971,7 +971,8 @@ angle::Result Context11::getIncompleteTexture(const gl::Context *context, ...@@ -971,7 +971,8 @@ angle::Result Context11::getIncompleteTexture(const gl::Context *context,
gl::TextureType type, gl::TextureType type,
gl::Texture **textureOut) gl::Texture **textureOut)
{ {
return mIncompleteTextures.getIncompleteTexture(context, type, this, textureOut); return mIncompleteTextures.getIncompleteTexture(context, type, gl::SamplerFormat::Float, this,
textureOut);
} }
angle::Result Context11::initializeMultisampleTextureToBlack(const gl::Context *context, angle::Result Context11::initializeMultisampleTextureToBlack(const gl::Context *context,
......
...@@ -480,7 +480,8 @@ angle::Result Context9::getIncompleteTexture(const gl::Context *context, ...@@ -480,7 +480,8 @@ angle::Result Context9::getIncompleteTexture(const gl::Context *context,
gl::TextureType type, gl::TextureType type,
gl::Texture **textureOut) gl::Texture **textureOut)
{ {
return mIncompleteTextures.getIncompleteTexture(context, type, nullptr, textureOut); return mIncompleteTextures.getIncompleteTexture(context, type, gl::SamplerFormat::Float,
nullptr, textureOut);
} }
void Context9::handleResult(HRESULT hr, void Context9::handleResult(HRESULT hr,
......
...@@ -237,7 +237,8 @@ angle::Result ContextMtl::ensureIncompleteTexturesCreated(const gl::Context *con ...@@ -237,7 +237,8 @@ angle::Result ContextMtl::ensureIncompleteTexturesCreated(const gl::Context *con
for (gl::TextureType texType : supportedTextureTypes) for (gl::TextureType texType : supportedTextureTypes)
{ {
gl::Texture *texture; gl::Texture *texture;
ANGLE_TRY(mIncompleteTextures.getIncompleteTexture(context, texType, nullptr, &texture)); ANGLE_TRY(mIncompleteTextures.getIncompleteTexture(
context, texType, gl::SamplerFormat::Float, nullptr, &texture));
TextureMtl *textureMtl = mtl::GetImpl(texture); TextureMtl *textureMtl = mtl::GetImpl(texture);
textureMtl->getNativeTexture()->get().label = @"IncompleteTexture"; textureMtl->getNativeTexture()->get().label = @"IncompleteTexture";
...@@ -1347,7 +1348,8 @@ angle::Result ContextMtl::getIncompleteTexture(const gl::Context *context, ...@@ -1347,7 +1348,8 @@ angle::Result ContextMtl::getIncompleteTexture(const gl::Context *context,
gl::TextureType type, gl::TextureType type,
gl::Texture **textureOut) gl::Texture **textureOut)
{ {
return mIncompleteTextures.getIncompleteTexture(context, type, nullptr, textureOut); return mIncompleteTextures.getIncompleteTexture(context, type, gl::SamplerFormat::Float,
nullptr, textureOut);
} }
void ContextMtl::endRenderEncoding(mtl::RenderCommandEncoder *encoder) void ContextMtl::endRenderEncoding(mtl::RenderCommandEncoder *encoder)
......
...@@ -49,6 +49,25 @@ constexpr std::array<SamplePositionsArray, 5> kSamplePositions = { ...@@ -49,6 +49,25 @@ constexpr std::array<SamplePositionsArray, 5> kSamplePositions = {
0.375f, 0.875f, 0.5f, 0.0625f, 0.25f, 0.125f, 0.125f, 0.75f, 0.375f, 0.875f, 0.5f, 0.0625f, 0.25f, 0.125f, 0.125f, 0.75f,
0.0f, 0.5f, 0.9375f, 0.25f, 0.875f, 0.9375f, 0.0625f, 0.0f}}}}; 0.0f, 0.5f, 0.9375f, 0.25f, 0.875f, 0.9375f, 0.0625f, 0.0f}}}};
struct IncompleteTextureParameters
{
GLenum sizedInternalFormat;
GLenum format;
GLenum type;
GLubyte clearColor[4];
};
// Note that for gl::SamplerFormat::Shadow, the clearColor datatype needs to be GLushort and as such
// we will reinterpret GLubyte[4] as GLushort[2].
constexpr angle::PackedEnumMap<gl::SamplerFormat, IncompleteTextureParameters>
kIncompleteTextureParameters = {
{gl::SamplerFormat::Float, {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, {0, 0, 0, 255}}},
{gl::SamplerFormat::Unsigned,
{GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, {0, 0, 0, 255}}},
{gl::SamplerFormat::Signed, {GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE, {0, 0, 0, 127}}},
{gl::SamplerFormat::Shadow,
{GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, {0, 0, 0, 0}}}};
void CopyColor(gl::ColorF *color) void CopyColor(gl::ColorF *color)
{ {
// No-op // No-op
...@@ -206,6 +225,7 @@ void SetFloatUniformMatrixFast(unsigned int arrayElementOffset, ...@@ -206,6 +225,7 @@ void SetFloatUniformMatrixFast(unsigned int arrayElementOffset,
memcpy(targetData, valueData, matrixSize * count); memcpy(targetData, valueData, matrixSize * count);
} }
} // anonymous namespace } // anonymous namespace
void RotateRectangle(const SurfaceRotation rotation, void RotateRectangle(const SurfaceRotation rotation,
...@@ -552,12 +572,15 @@ IncompleteTextureSet::~IncompleteTextureSet() {} ...@@ -552,12 +572,15 @@ IncompleteTextureSet::~IncompleteTextureSet() {}
void IncompleteTextureSet::onDestroy(const gl::Context *context) void IncompleteTextureSet::onDestroy(const gl::Context *context)
{ {
// Clear incomplete textures. // Clear incomplete textures.
for (auto &incompleteTexture : mIncompleteTextures) for (auto &incompleteTextures : mIncompleteTextures)
{ {
if (incompleteTexture.get() != nullptr) for (auto &incompleteTexture : incompleteTextures)
{ {
incompleteTexture->onDestroy(context); if (incompleteTexture.get() != nullptr)
incompleteTexture.set(context, nullptr); {
incompleteTexture->onDestroy(context);
incompleteTexture.set(context, nullptr);
}
} }
} }
if (mIncompleteTextureBufferAttachment != nullptr) if (mIncompleteTextureBufferAttachment != nullptr)
...@@ -570,10 +593,11 @@ void IncompleteTextureSet::onDestroy(const gl::Context *context) ...@@ -570,10 +593,11 @@ void IncompleteTextureSet::onDestroy(const gl::Context *context)
angle::Result IncompleteTextureSet::getIncompleteTexture( angle::Result IncompleteTextureSet::getIncompleteTexture(
const gl::Context *context, const gl::Context *context,
gl::TextureType type, gl::TextureType type,
gl::SamplerFormat format,
MultisampleTextureInitializer *multisampleInitializer, MultisampleTextureInitializer *multisampleInitializer,
gl::Texture **textureOut) gl::Texture **textureOut)
{ {
*textureOut = mIncompleteTextures[type].get(); *textureOut = mIncompleteTextures[format][type].get();
if (*textureOut != nullptr) if (*textureOut != nullptr)
{ {
return angle::Result::Continue; return angle::Result::Continue;
...@@ -581,11 +605,12 @@ angle::Result IncompleteTextureSet::getIncompleteTexture( ...@@ -581,11 +605,12 @@ angle::Result IncompleteTextureSet::getIncompleteTexture(
ContextImpl *implFactory = context->getImplementation(); ContextImpl *implFactory = context->getImplementation();
const GLubyte color[] = {0, 0, 0, 255};
const gl::Extents colorSize(1, 1, 1); const gl::Extents colorSize(1, 1, 1);
gl::PixelUnpackState unpack; gl::PixelUnpackState unpack;
unpack.alignment = 1; unpack.alignment = 1;
const gl::Box area(0, 0, 0, 1, 1, 1); const gl::Box area(0, 0, 0, 1, 1, 1);
const IncompleteTextureParameters &incompleteTextureParam =
kIncompleteTextureParameters[format];
// If a texture is external use a 2D texture for the incomplete texture // If a texture is external use a 2D texture for the incomplete texture
gl::TextureType createType = (type == gl::TextureType::External) ? gl::TextureType::_2D : type; gl::TextureType createType = (type == gl::TextureType::External) ? gl::TextureType::_2D : type;
...@@ -597,9 +622,6 @@ angle::Result IncompleteTextureSet::getIncompleteTexture( ...@@ -597,9 +622,6 @@ angle::Result IncompleteTextureSet::getIncompleteTexture(
// This is a bit of a kludge but is necessary to consume the error. // This is a bit of a kludge but is necessary to consume the error.
gl::Context *mutableContext = const_cast<gl::Context *>(context); gl::Context *mutableContext = const_cast<gl::Context *>(context);
// TODO: the caller should specify the basic type of the image (i.e. float, int or uint) so a
// different incomplete texture is created per type. In Vulkan, it's invalid to bind a unorm
// texture for example if the shader expects uint. http://anglebug.com/4432#c5
if (createType == gl::TextureType::Buffer) if (createType == gl::TextureType::Buffer)
{ {
constexpr uint32_t kBufferInitData = 0; constexpr uint32_t kBufferInitData = 0;
...@@ -611,20 +633,23 @@ angle::Result IncompleteTextureSet::getIncompleteTexture( ...@@ -611,20 +633,23 @@ angle::Result IncompleteTextureSet::getIncompleteTexture(
} }
else if (createType == gl::TextureType::_2DMultisample) else if (createType == gl::TextureType::_2DMultisample)
{ {
ANGLE_TRY( ANGLE_TRY(t->setStorageMultisample(mutableContext, createType, 1,
t->setStorageMultisample(mutableContext, createType, 1, GL_RGBA8, colorSize, true)); incompleteTextureParam.sizedInternalFormat, colorSize,
true));
} }
else else
{ {
ANGLE_TRY(t->setStorage(mutableContext, createType, 1, GL_RGBA8, colorSize)); ANGLE_TRY(t->setStorage(mutableContext, createType, 1,
incompleteTextureParam.sizedInternalFormat, colorSize));
} }
if (type == gl::TextureType::CubeMap) if (type == gl::TextureType::CubeMap)
{ {
for (gl::TextureTarget face : gl::AllCubeFaceTextureTargets()) for (gl::TextureTarget face : gl::AllCubeFaceTextureTargets())
{ {
ANGLE_TRY(t->setSubImage(mutableContext, unpack, nullptr, face, 0, area, GL_RGBA, ANGLE_TRY(t->setSubImage(mutableContext, unpack, nullptr, face, 0, area,
GL_UNSIGNED_BYTE, color)); incompleteTextureParam.format, incompleteTextureParam.type,
incompleteTextureParam.clearColor));
} }
} }
else if (type == gl::TextureType::_2DMultisample) else if (type == gl::TextureType::_2DMultisample)
...@@ -634,19 +659,29 @@ angle::Result IncompleteTextureSet::getIncompleteTexture( ...@@ -634,19 +659,29 @@ angle::Result IncompleteTextureSet::getIncompleteTexture(
} }
else if (type == gl::TextureType::Buffer) else if (type == gl::TextureType::Buffer)
{ {
ANGLE_TRY(t->setBuffer(context, mIncompleteTextureBufferAttachment, GL_RGBA8UI)); ANGLE_TRY(t->setBuffer(context, mIncompleteTextureBufferAttachment,
incompleteTextureParam.sizedInternalFormat));
} }
else else
{ {
ANGLE_TRY(t->setSubImage(mutableContext, unpack, nullptr, ANGLE_TRY(t->setSubImage(mutableContext, unpack, nullptr,
gl::NonCubeTextureTypeToTarget(createType), 0, area, GL_RGBA, gl::NonCubeTextureTypeToTarget(createType), 0, area,
GL_UNSIGNED_BYTE, color)); incompleteTextureParam.format, incompleteTextureParam.type,
incompleteTextureParam.clearColor));
}
if (format == gl::SamplerFormat::Shadow)
{
// To avoid the undefined spec behavior for shadow samplers with a depth texture, we set the
// compare mode to GL_COMPARE_REF_TO_TEXTURE
ASSERT(!t->hasObservers());
t->setCompareMode(context, GL_COMPARE_REF_TO_TEXTURE);
} }
ANGLE_TRY(t->syncState(context, gl::Command::Other)); ANGLE_TRY(t->syncState(context, gl::Command::Other));
mIncompleteTextures[type].set(context, t.release()); mIncompleteTextures[format][type].set(context, t.release());
*textureOut = mIncompleteTextures[type].get(); *textureOut = mIncompleteTextures[format][type].get();
return angle::Result::Continue; return angle::Result::Continue;
} }
......
...@@ -207,11 +207,14 @@ class IncompleteTextureSet final : angle::NonCopyable ...@@ -207,11 +207,14 @@ class IncompleteTextureSet final : angle::NonCopyable
angle::Result getIncompleteTexture(const gl::Context *context, angle::Result getIncompleteTexture(const gl::Context *context,
gl::TextureType type, gl::TextureType type,
gl::SamplerFormat format,
MultisampleTextureInitializer *multisampleInitializer, MultisampleTextureInitializer *multisampleInitializer,
gl::Texture **textureOut); gl::Texture **textureOut);
private: private:
gl::TextureMap mIncompleteTextures; using TextureMapWithSamplerFormat = angle::PackedEnumMap<gl::SamplerFormat, gl::TextureMap>;
TextureMapWithSamplerFormat mIncompleteTextures;
gl::Buffer *mIncompleteTextureBufferAttachment; gl::Buffer *mIncompleteTextureBufferAttachment;
}; };
......
...@@ -574,9 +574,10 @@ void ContextVk::onDestroy(const gl::Context *context) ...@@ -574,9 +574,10 @@ void ContextVk::onDestroy(const gl::Context *context)
angle::Result ContextVk::getIncompleteTexture(const gl::Context *context, angle::Result ContextVk::getIncompleteTexture(const gl::Context *context,
gl::TextureType type, gl::TextureType type,
gl::SamplerFormat format,
gl::Texture **textureOut) gl::Texture **textureOut)
{ {
return mIncompleteTextures.getIncompleteTexture(context, type, this, textureOut); return mIncompleteTextures.getIncompleteTexture(context, type, format, this, textureOut);
} }
angle::Result ContextVk::initialize() angle::Result ContextVk::initialize()
...@@ -4138,7 +4139,9 @@ angle::Result ContextVk::updateActiveTextures(const gl::Context *context) ...@@ -4138,7 +4139,9 @@ angle::Result ContextVk::updateActiveTextures(const gl::Context *context)
// Null textures represent incomplete textures. // Null textures represent incomplete textures.
if (isIncompleteTexture) if (isIncompleteTexture)
{ {
ANGLE_TRY(getIncompleteTexture(context, textureType, &texture)); ANGLE_TRY(getIncompleteTexture(
context, textureType, executable->getSamplerFormatForTextureUnitIndex(textureUnit),
&texture));
} }
TextureVk *textureVk = vk::GetImpl(texture); TextureVk *textureVk = vk::GetImpl(texture);
......
...@@ -351,6 +351,7 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText ...@@ -351,6 +351,7 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText
gl::BlendStateExt::ColorMaskStorage::Type getClearColorMasks() const; gl::BlendStateExt::ColorMaskStorage::Type getClearColorMasks() const;
angle::Result getIncompleteTexture(const gl::Context *context, angle::Result getIncompleteTexture(const gl::Context *context,
gl::TextureType type, gl::TextureType type,
gl::SamplerFormat format,
gl::Texture **textureOut); gl::Texture **textureOut);
void updateColorMasks(const gl::BlendStateExt &blendStateExt); void updateColorMasks(const gl::BlendStateExt &blendStateExt);
void updateSampleMaskWithRasterizationSamples(const uint32_t rasterizationSamples); void updateSampleMaskWithRasterizationSamples(const uint32_t rasterizationSamples);
......
...@@ -58,9 +58,6 @@ ...@@ -58,9 +58,6 @@
4723 VULKAN NVIDIA : KHR-GLES31.core.shader_image_size.advanced-nonMS-vs-uint = SKIP 4723 VULKAN NVIDIA : KHR-GLES31.core.shader_image_size.advanced-nonMS-vs-uint = SKIP
4723 VULKAN NVIDIA : KHR-GLES31.core.program_interface_query.transform-feedback-types = SKIP 4723 VULKAN NVIDIA : KHR-GLES31.core.program_interface_query.transform-feedback-types = SKIP
// Incompatible between incomplete texture and sampler format (isampler2D or usampler2D):
3588 VULKAN : KHR-GLES31.core.sample_variables.mask.rgba8*i.* = FAIL
// Geometry shader support // Geometry shader support
5483 VULKAN : KHR-GLES31.core.draw_indirect.basic-mode-*adjacency = SKIP 5483 VULKAN : KHR-GLES31.core.draw_indirect.basic-mode-*adjacency = SKIP
...@@ -96,7 +93,7 @@ ...@@ -96,7 +93,7 @@
4159 VULKAN PIXEL2ORXL : KHR-GLES31.core.draw_indirect.advanced-twoPass-transformFeedback-arrays = FAIL 4159 VULKAN PIXEL2ORXL : KHR-GLES31.core.draw_indirect.advanced-twoPass-transformFeedback-arrays = FAIL
// Fails to link the shader program on Pixel2 and Pixel2 XL // Fails to link the shader program on Pixel2 and Pixel2 XL
3588 VULKAN PIXEL2ORXL : KHR-GLES31.core.sample_variables.mask.rgba8.samples_*.mask_* = FAIL 5572 VULKAN PIXEL2ORXL : KHR-GLES31.core.sample_variables.mask.rgba8*.samples_*.mask_* = FAIL
// Failing on Android with SwiftShader // Failing on Android with SwiftShader
4300 SWIFTSHADER ANDROID : KHR-GLES31.core.shader_integer_mix.mix-bvec4 = FAIL 4300 SWIFTSHADER ANDROID : KHR-GLES31.core.shader_integer_mix.mix-bvec4 = FAIL
......
...@@ -245,10 +245,6 @@ void main() ...@@ -245,10 +245,6 @@ void main()
// Verifies that an incomplete integer texture has a signed integer type default value. // Verifies that an incomplete integer texture has a signed integer type default value.
TEST_P(IncompleteTextureTestES3, IntegerType) TEST_P(IncompleteTextureTestES3, IntegerType)
{ {
// On Vulkan, D3D, and Metal backend, creating the incomplete texture which has a signed integer
// type, isn't supported.
ANGLE_SKIP_TEST_IF(IsVulkan() || IsD3D() || IsMetal());
// GLES backend on Adreno has a problem to create a incomplete texture, although it doesn't go // GLES backend on Adreno has a problem to create a incomplete texture, although it doesn't go
// through the routine which creates a incomplete texture in the ANGLE driver. // through the routine which creates a incomplete texture in the ANGLE driver.
ANGLE_SKIP_TEST_IF(IsAdreno() && IsAndroid() && IsOpenGLES()); ANGLE_SKIP_TEST_IF(IsAdreno() && IsAndroid() && IsOpenGLES());
...@@ -303,10 +299,6 @@ void main() ...@@ -303,10 +299,6 @@ void main()
// Verifies that an incomplete unsigned integer texture has an unsigned integer type default value. // Verifies that an incomplete unsigned integer texture has an unsigned integer type default value.
TEST_P(IncompleteTextureTestES3, UnsignedIntegerType) TEST_P(IncompleteTextureTestES3, UnsignedIntegerType)
{ {
// On Vulkan, D3D, and Metal backend, creating the incomplete texture which has a unsigned
// integer type, isn't supported.
ANGLE_SKIP_TEST_IF(IsVulkan() || IsD3D() || IsMetal());
// GLES backend on Adreno has a problem to create a incomplete texture, although it doesn't go // GLES backend on Adreno has a problem to create a incomplete texture, although it doesn't go
// through the routine which creates a incomplete texture in the ANGLE driver. // through the routine which creates a incomplete texture in the ANGLE driver.
ANGLE_SKIP_TEST_IF(IsAdreno() && IsAndroid() && IsOpenGLES()); ANGLE_SKIP_TEST_IF(IsAdreno() && IsAndroid() && IsOpenGLES());
...@@ -362,14 +354,16 @@ void main() ...@@ -362,14 +354,16 @@ void main()
// Verifies that we are able to create an incomplete shadow texture. // Verifies that we are able to create an incomplete shadow texture.
TEST_P(IncompleteTextureTestES3, ShadowType) TEST_P(IncompleteTextureTestES3, ShadowType)
{ {
// On Vulkan, D3D, and Metal backend, creating the incomplete texture which has a shadow type,
// isn't supported.
ANGLE_SKIP_TEST_IF(IsVulkan() || IsD3D() || IsMetal());
// GLES backend on Adreno has a problem to create a incomplete texture, although it doesn't go // GLES backend on Adreno has a problem to create a incomplete texture, although it doesn't go
// through the routine which creates a incomplete texture in the ANGLE driver. // through the routine which creates a incomplete texture in the ANGLE driver.
ANGLE_SKIP_TEST_IF(IsAdreno() && IsAndroid() && IsOpenGLES()); ANGLE_SKIP_TEST_IF(IsAdreno() && IsAndroid() && IsOpenGLES());
// http://crbug.com/1168370
ANGLE_SKIP_TEST_IF(IsOSX() && IsARM64() && IsOpenGL());
// http://anglebug.com/5594
ANGLE_SKIP_TEST_IF(IsD3D11() || IsOSX());
constexpr char kVS[] = R"(#version 300 es constexpr char kVS[] = R"(#version 300 es
in highp vec2 position; in highp vec2 position;
out highp vec3 texCoord; out highp vec3 texCoord;
...@@ -388,10 +382,6 @@ void main() ...@@ -388,10 +382,6 @@ void main()
color = vec4(vec3(texture(tex, texCoord)), 1.0f); color = vec4(vec3(texture(tex, texCoord)), 1.0f);
})"; })";
// http://anglebug.com/5107
// Metal doesn't support a shadow sampler when the GL_TEXTURE_COMPARE_MODE value is GL_NONE.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
constexpr GLColor clearColor = {10, 40, 20, 30}; constexpr GLColor clearColor = {10, 40, 20, 30};
constexpr GLColor blackColor = {0, 0, 0, 255}; constexpr GLColor blackColor = {0, 0, 0, 255};
......
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