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,
gl::TextureType type,
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,
......
......@@ -480,7 +480,8 @@ angle::Result Context9::getIncompleteTexture(const gl::Context *context,
gl::TextureType type,
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,
......
......@@ -237,7 +237,8 @@ angle::Result ContextMtl::ensureIncompleteTexturesCreated(const gl::Context *con
for (gl::TextureType texType : supportedTextureTypes)
{
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->getNativeTexture()->get().label = @"IncompleteTexture";
......@@ -1347,7 +1348,8 @@ angle::Result ContextMtl::getIncompleteTexture(const gl::Context *context,
gl::TextureType type,
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)
......
......@@ -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.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)
{
// No-op
......@@ -206,6 +225,7 @@ void SetFloatUniformMatrixFast(unsigned int arrayElementOffset,
memcpy(targetData, valueData, matrixSize * count);
}
} // anonymous namespace
void RotateRectangle(const SurfaceRotation rotation,
......@@ -552,12 +572,15 @@ IncompleteTextureSet::~IncompleteTextureSet() {}
void IncompleteTextureSet::onDestroy(const gl::Context *context)
{
// Clear incomplete textures.
for (auto &incompleteTexture : mIncompleteTextures)
for (auto &incompleteTextures : mIncompleteTextures)
{
if (incompleteTexture.get() != nullptr)
for (auto &incompleteTexture : incompleteTextures)
{
incompleteTexture->onDestroy(context);
incompleteTexture.set(context, nullptr);
if (incompleteTexture.get() != nullptr)
{
incompleteTexture->onDestroy(context);
incompleteTexture.set(context, nullptr);
}
}
}
if (mIncompleteTextureBufferAttachment != nullptr)
......@@ -570,10 +593,11 @@ void IncompleteTextureSet::onDestroy(const gl::Context *context)
angle::Result IncompleteTextureSet::getIncompleteTexture(
const gl::Context *context,
gl::TextureType type,
gl::SamplerFormat format,
MultisampleTextureInitializer *multisampleInitializer,
gl::Texture **textureOut)
{
*textureOut = mIncompleteTextures[type].get();
*textureOut = mIncompleteTextures[format][type].get();
if (*textureOut != nullptr)
{
return angle::Result::Continue;
......@@ -581,11 +605,12 @@ angle::Result IncompleteTextureSet::getIncompleteTexture(
ContextImpl *implFactory = context->getImplementation();
const GLubyte color[] = {0, 0, 0, 255};
const gl::Extents colorSize(1, 1, 1);
gl::PixelUnpackState unpack;
unpack.alignment = 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
gl::TextureType createType = (type == gl::TextureType::External) ? gl::TextureType::_2D : type;
......@@ -597,9 +622,6 @@ angle::Result IncompleteTextureSet::getIncompleteTexture(
// This is a bit of a kludge but is necessary to consume the error.
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)
{
constexpr uint32_t kBufferInitData = 0;
......@@ -611,20 +633,23 @@ angle::Result IncompleteTextureSet::getIncompleteTexture(
}
else if (createType == gl::TextureType::_2DMultisample)
{
ANGLE_TRY(
t->setStorageMultisample(mutableContext, createType, 1, GL_RGBA8, colorSize, true));
ANGLE_TRY(t->setStorageMultisample(mutableContext, createType, 1,
incompleteTextureParam.sizedInternalFormat, colorSize,
true));
}
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)
{
for (gl::TextureTarget face : gl::AllCubeFaceTextureTargets())
{
ANGLE_TRY(t->setSubImage(mutableContext, unpack, nullptr, face, 0, area, GL_RGBA,
GL_UNSIGNED_BYTE, color));
ANGLE_TRY(t->setSubImage(mutableContext, unpack, nullptr, face, 0, area,
incompleteTextureParam.format, incompleteTextureParam.type,
incompleteTextureParam.clearColor));
}
}
else if (type == gl::TextureType::_2DMultisample)
......@@ -634,19 +659,29 @@ angle::Result IncompleteTextureSet::getIncompleteTexture(
}
else if (type == gl::TextureType::Buffer)
{
ANGLE_TRY(t->setBuffer(context, mIncompleteTextureBufferAttachment, GL_RGBA8UI));
ANGLE_TRY(t->setBuffer(context, mIncompleteTextureBufferAttachment,
incompleteTextureParam.sizedInternalFormat));
}
else
{
ANGLE_TRY(t->setSubImage(mutableContext, unpack, nullptr,
gl::NonCubeTextureTypeToTarget(createType), 0, area, GL_RGBA,
GL_UNSIGNED_BYTE, color));
gl::NonCubeTextureTypeToTarget(createType), 0, area,
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));
mIncompleteTextures[type].set(context, t.release());
*textureOut = mIncompleteTextures[type].get();
mIncompleteTextures[format][type].set(context, t.release());
*textureOut = mIncompleteTextures[format][type].get();
return angle::Result::Continue;
}
......
......@@ -207,11 +207,14 @@ class IncompleteTextureSet final : angle::NonCopyable
angle::Result getIncompleteTexture(const gl::Context *context,
gl::TextureType type,
gl::SamplerFormat format,
MultisampleTextureInitializer *multisampleInitializer,
gl::Texture **textureOut);
private:
gl::TextureMap mIncompleteTextures;
using TextureMapWithSamplerFormat = angle::PackedEnumMap<gl::SamplerFormat, gl::TextureMap>;
TextureMapWithSamplerFormat mIncompleteTextures;
gl::Buffer *mIncompleteTextureBufferAttachment;
};
......
......@@ -574,9 +574,10 @@ void ContextVk::onDestroy(const gl::Context *context)
angle::Result ContextVk::getIncompleteTexture(const gl::Context *context,
gl::TextureType type,
gl::SamplerFormat format,
gl::Texture **textureOut)
{
return mIncompleteTextures.getIncompleteTexture(context, type, this, textureOut);
return mIncompleteTextures.getIncompleteTexture(context, type, format, this, textureOut);
}
angle::Result ContextVk::initialize()
......@@ -4138,7 +4139,9 @@ angle::Result ContextVk::updateActiveTextures(const gl::Context *context)
// Null textures represent incomplete textures.
if (isIncompleteTexture)
{
ANGLE_TRY(getIncompleteTexture(context, textureType, &texture));
ANGLE_TRY(getIncompleteTexture(
context, textureType, executable->getSamplerFormatForTextureUnitIndex(textureUnit),
&texture));
}
TextureVk *textureVk = vk::GetImpl(texture);
......
......@@ -351,6 +351,7 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText
gl::BlendStateExt::ColorMaskStorage::Type getClearColorMasks() const;
angle::Result getIncompleteTexture(const gl::Context *context,
gl::TextureType type,
gl::SamplerFormat format,
gl::Texture **textureOut);
void updateColorMasks(const gl::BlendStateExt &blendStateExt);
void updateSampleMaskWithRasterizationSamples(const uint32_t rasterizationSamples);
......
......@@ -58,9 +58,6 @@
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
// Incompatible between incomplete texture and sampler format (isampler2D or usampler2D):
3588 VULKAN : KHR-GLES31.core.sample_variables.mask.rgba8*i.* = FAIL
// Geometry shader support
5483 VULKAN : KHR-GLES31.core.draw_indirect.basic-mode-*adjacency = SKIP
......@@ -96,7 +93,7 @@
4159 VULKAN PIXEL2ORXL : KHR-GLES31.core.draw_indirect.advanced-twoPass-transformFeedback-arrays = FAIL
// 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
4300 SWIFTSHADER ANDROID : KHR-GLES31.core.shader_integer_mix.mix-bvec4 = FAIL
......
......@@ -245,10 +245,6 @@ void main()
// Verifies that an incomplete integer texture has a signed integer type default value.
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
// through the routine which creates a incomplete texture in the ANGLE driver.
ANGLE_SKIP_TEST_IF(IsAdreno() && IsAndroid() && IsOpenGLES());
......@@ -303,10 +299,6 @@ void main()
// Verifies that an incomplete unsigned integer texture has an unsigned integer type default value.
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
// through the routine which creates a incomplete texture in the ANGLE driver.
ANGLE_SKIP_TEST_IF(IsAdreno() && IsAndroid() && IsOpenGLES());
......@@ -362,14 +354,16 @@ void main()
// Verifies that we are able to create an incomplete shadow texture.
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
// through the routine which creates a incomplete texture in the ANGLE driver.
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
in highp vec2 position;
out highp vec3 texCoord;
......@@ -388,10 +382,6 @@ void main()
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 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