Commit 4576f1d0 by Ian Elliott Committed by Commit Bot

Vulkan: Implement multisample textures

This functionality is exercised by running angle_deqp_gles31_tests with the following sets of command arguments: --gtest_filter=dEQP.GLES31/functional_texture_multisample* --use-angle=vulkan --gtest_filter=dEQP.GLES31/functional_state_query_texture_level_texture_2d_multisample* --use-angle=vulkan --gtest_filter=dEQP.GLES31/functional_state_query_texture_texture_2d_multisample_texture_immutable* --use-angle=vulkan The following are some high-level design notes: - Texture::setStorageMultisample() handles converting the "requested number of samples" to the actual number of samples used (e.g. converting 3 to 4), supported by the underlying back-end). The actual number used is stored in gl::TextureState::mImageDescs, for use by other GLES commands. - ANGLE uses the Vulkan standard sample locations/positions. If the underlying Vulkan driver's VkPhysicalDeviceLimits::standardSampleLocations is false, ANGLE limits itself to GLES 2.0 (i.e. before GLES 3.0 which adds multisample renderbuffers). - The Vulkan specification currently doesn't support ANGLE providing support for GLES 1-sample textures, because of the following Vulkan specification statement: - If the image was created with VkImageCreateInfo::samples equal to VK_SAMPLE_COUNT_1_BIT, the instruction must: have MS = 0. - At least one Vulkan driver returns different VkPhysicalDeviceLimits::*SampleCounts for different formats. Because of this, ANGLE does a logical-AND of all values in order to only support the commonly-available numbers of samples. The detailed design document is located at: https://docs.google.com/document/d/1NiM8gAR74iGGXGTE6IP1ChdDUZjhtXRuJdtEp_wGFEM/edit?usp=sharing Bug: angleproject:3565 Bug: angleproject:4103 Bug: angleproject:4104 Bug: angleproject:4196 Bug: angleproject:4197 Bug: angleproject:4198 Change-Id: I28921badf9568427799b0af347198b5df06c2db0 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1919982 Commit-Queue: Ian Elliott <ianelliott@google.com> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent d68bf3e2
...@@ -1329,8 +1329,9 @@ angle::Result FramebufferVk::getSamplePosition(const gl::Context *context, ...@@ -1329,8 +1329,9 @@ angle::Result FramebufferVk::getSamplePosition(const gl::Context *context,
size_t index, size_t index,
GLfloat *xy) const GLfloat *xy) const
{ {
ANGLE_VK_UNREACHABLE(vk::GetImpl(context)); int sampleCount = getSamples();
return angle::Result::Stop; rx::GetSamplePosition(sampleCount, index, xy);
return angle::Result::Continue;
} }
angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk, angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
......
...@@ -1256,6 +1256,14 @@ gl::Version RendererVk::getMaxSupportedESVersion() const ...@@ -1256,6 +1256,14 @@ gl::Version RendererVk::getMaxSupportedESVersion() const
// Limit to ES2.0 if there are any blockers for 3.0. // Limit to ES2.0 if there are any blockers for 3.0.
// TODO: http://anglebug.com/3972 Limit to GLES 2.0 if flat shading can't be emulated // TODO: http://anglebug.com/3972 Limit to GLES 2.0 if flat shading can't be emulated
// Multisample textures (ES3.1) and multisample renderbuffers (ES3.0) require the Vulkan driver
// to support the standard sample locations (in order to pass dEQP tests that check these
// locations). If the Vulkan implementation can't support that, we cannot support 3.0/3.1.
if (mPhysicalDeviceProperties.limits.standardSampleLocations != VK_TRUE)
{
maxVersion = std::min(maxVersion, gl::Version(2, 0));
}
// If the command buffer doesn't support queries, we can't support ES3. // If the command buffer doesn't support queries, we can't support ES3.
if (!vk::CommandBuffer::SupportsQueries(mPhysicalDeviceFeatures)) if (!vk::CommandBuffer::SupportsQueries(mPhysicalDeviceFeatures))
{ {
......
...@@ -74,6 +74,7 @@ void GetRenderTargetLayerCountAndIndex(vk::ImageHelper *image, ...@@ -74,6 +74,7 @@ void GetRenderTargetLayerCountAndIndex(vk::ImageHelper *image,
switch (index.getType()) switch (index.getType())
{ {
case gl::TextureType::_2D: case gl::TextureType::_2D:
case gl::TextureType::_2DMultisample:
*layerIndex = 0; *layerIndex = 0;
*layerCount = 1; *layerCount = 1;
return; return;
...@@ -89,6 +90,7 @@ void GetRenderTargetLayerCountAndIndex(vk::ImageHelper *image, ...@@ -89,6 +90,7 @@ void GetRenderTargetLayerCountAndIndex(vk::ImageHelper *image,
return; return;
case gl::TextureType::_2DArray: case gl::TextureType::_2DArray:
case gl::TextureType::_2DMultisampleArray:
*layerIndex = index.hasLayer() ? index.getLayerIndex() : 0; *layerIndex = index.hasLayer() ? index.getLayerIndex() : 0;
*layerCount = image->getLayerCount(); *layerCount = image->getLayerCount();
return; return;
...@@ -754,6 +756,16 @@ angle::Result TextureVk::setStorage(const gl::Context *context, ...@@ -754,6 +756,16 @@ angle::Result TextureVk::setStorage(const gl::Context *context,
GLenum internalFormat, GLenum internalFormat,
const gl::Extents &size) const gl::Extents &size)
{ {
return setStorageMultisample(context, type, 1, internalFormat, size, true);
}
angle::Result TextureVk::setStorageMultisample(const gl::Context *context,
gl::TextureType type,
GLsizei samples,
GLint internalformat,
const gl::Extents &size,
bool fixedSampleLocations)
{
ContextVk *contextVk = GetAs<ContextVk>(context->getImplementation()); ContextVk *contextVk = GetAs<ContextVk>(context->getImplementation());
RendererVk *renderer = contextVk->getRenderer(); RendererVk *renderer = contextVk->getRenderer();
...@@ -762,7 +774,7 @@ angle::Result TextureVk::setStorage(const gl::Context *context, ...@@ -762,7 +774,7 @@ angle::Result TextureVk::setStorage(const gl::Context *context,
releaseAndDeleteImage(contextVk); releaseAndDeleteImage(contextVk);
} }
const vk::Format &format = renderer->getFormat(internalFormat); const vk::Format &format = renderer->getFormat(internalformat);
ANGLE_TRY(ensureImageAllocated(contextVk, format)); ANGLE_TRY(ensureImageAllocated(contextVk, format));
if (mImage->valid()) if (mImage->valid())
...@@ -1571,17 +1583,6 @@ angle::Result TextureVk::syncState(const gl::Context *context, ...@@ -1571,17 +1583,6 @@ angle::Result TextureVk::syncState(const gl::Context *context,
return angle::Result::Continue; return angle::Result::Continue;
} }
angle::Result TextureVk::setStorageMultisample(const gl::Context *context,
gl::TextureType type,
GLsizei samples,
GLint internalformat,
const gl::Extents &size,
bool fixedSampleLocations)
{
ANGLE_VK_UNREACHABLE(vk::GetImpl(context));
return angle::Result::Stop;
}
angle::Result TextureVk::initializeContents(const gl::Context *context, angle::Result TextureVk::initializeContents(const gl::Context *context,
const gl::ImageIndex &imageIndex) const gl::ImageIndex &imageIndex)
{ {
...@@ -1672,8 +1673,9 @@ angle::Result TextureVk::initImage(ContextVk *contextVk, ...@@ -1672,8 +1673,9 @@ angle::Result TextureVk::initImage(ContextVk *contextVk,
VkExtent3D vkExtent; VkExtent3D vkExtent;
uint32_t layerCount; uint32_t layerCount;
gl_vk::GetExtentsAndLayerCount(mState.getType(), extents, &vkExtent, &layerCount); gl_vk::GetExtentsAndLayerCount(mState.getType(), extents, &vkExtent, &layerCount);
GLint samples = mState.getBaseLevelDesc().samples ? mState.getBaseLevelDesc().samples : 1;
ANGLE_TRY(mImage->init(contextVk, mState.getType(), vkExtent, format, 1, mImageUsageFlags, ANGLE_TRY(mImage->init(contextVk, mState.getType(), vkExtent, format, samples, mImageUsageFlags,
mState.getEffectiveBaseLevel(), mState.getEffectiveMaxLevel(), mState.getEffectiveBaseLevel(), mState.getEffectiveMaxLevel(),
levelCount, layerCount)); levelCount, layerCount));
......
...@@ -50,9 +50,11 @@ void FillTextureFormatCaps(RendererVk *renderer, VkFormat format, gl::TextureCap ...@@ -50,9 +50,11 @@ void FillTextureFormatCaps(RendererVk *renderer, VkFormat format, gl::TextureCap
} }
if (hasDepthAttachmentFeatureBit) if (hasDepthAttachmentFeatureBit)
{ {
vk_gl::AddSampleCounts(physicalDeviceLimits.framebufferDepthSampleCounts, // Some drivers report different depth and stencil sample counts. We'll AND those
&outTextureCaps->sampleCounts); // counts together, limiting all depth and/or stencil formats to the lower number of
vk_gl::AddSampleCounts(physicalDeviceLimits.framebufferStencilSampleCounts, // sample counts.
vk_gl::AddSampleCounts((physicalDeviceLimits.framebufferDepthSampleCounts &
physicalDeviceLimits.framebufferStencilSampleCounts),
&outTextureCaps->sampleCounts); &outTextureCaps->sampleCounts);
} }
} }
......
...@@ -1628,7 +1628,7 @@ void BufferHelper::changeQueue(uint32_t newQueueFamilyIndex, CommandBuffer *comm ...@@ -1628,7 +1628,7 @@ void BufferHelper::changeQueue(uint32_t newQueueFamilyIndex, CommandBuffer *comm
ImageHelper::ImageHelper() ImageHelper::ImageHelper()
: CommandGraphResource(CommandGraphResourceType::Image), : CommandGraphResource(CommandGraphResourceType::Image),
mFormat(nullptr), mFormat(nullptr),
mSamples(0), mSamples(1),
mCurrentLayout(ImageLayout::Undefined), mCurrentLayout(ImageLayout::Undefined),
mCurrentQueueFamilyIndex(std::numeric_limits<uint32_t>::max()), mCurrentQueueFamilyIndex(std::numeric_limits<uint32_t>::max()),
mBaseLevel(0), mBaseLevel(0),
......
...@@ -627,9 +627,6 @@ ...@@ -627,9 +627,6 @@
// Front-end query bugs: // Front-end query bugs:
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.shader_storage_block.buffer_data_size.* = FAIL 3596 VULKAN : dEQP-GLES31.functional.program_interface_query.shader_storage_block.buffer_data_size.* = FAIL
// Shader support:
3565 VULKAN : dEQP-GLES31.functional.shaders.builtin_functions.texture_size.samples_* = SKIP
// SSBO synchronization: // SSBO synchronization:
4097 VULKAN PIXEL2ORXL : dEQP-GLES31.functional.synchronization.in_invocation.ssbo_alias_overwrite = FAIL 4097 VULKAN PIXEL2ORXL : dEQP-GLES31.functional.synchronization.in_invocation.ssbo_alias_overwrite = FAIL
...@@ -655,9 +652,32 @@ ...@@ -655,9 +652,32 @@
// Need to support non-color when staging image updates // Need to support non-color when staging image updates
4080 ANDROID VULKAN : dEQP-GLES31.functional.stencil_texturing.misc.base_level = SKIP 4080 ANDROID VULKAN : dEQP-GLES31.functional.stencil_texturing.misc.base_level = SKIP
// Multisampled textures: //// Multisampled textures:
3565 VULKAN : dEQP-GLES31.functional.texture.multisample.* = SKIP // The following tests pass, but fail because of Vulkan validation-layer errors, which are the result
3565 VULKAN : dEQP-GLES31.functional.state_query.texture*multisample.* = SKIP // of a Vulkan spec statement that 1-sample textures can't be used with multisample shaders.
// Issue 4197 tracks the external dependencies (Vulkan spec and validation-layer changes).
4197 VULKAN : dEQP-GLES31.functional.texture.multisample.samples_1.sample_position = FAIL
4197 VULKAN : dEQP-GLES31.functional.texture.multisample.samples_1.sample_mask* = FAIL
4197 VULKAN : dEQP-GLES31.functional.texture.multisample.samples_1.use_texture_*_2d = FAIL
// The following test fails with the Intel Windows Vulkan driver (which appears to have swapped
// the standard positions for 2 samples):
4198 INTEL VULKAN : dEQP-GLES31.functional.texture.multisample.samples_2.sample_position = FAIL
// TODO: Investigate why these are failing:
3565 LINUX VULKAN : dEQP-GLES31.functional.texture.multisample.samples_10.use_texture_depth_2d = FAIL
3565 LINUX VULKAN : dEQP-GLES31.functional.texture.multisample.samples_12.use_texture_depth_2d = FAIL
3565 LINUX VULKAN : dEQP-GLES31.functional.texture.multisample.samples_13.use_texture_depth_2d = FAIL
3565 LINUX VULKAN : dEQP-GLES31.functional.texture.multisample.samples_16.use_texture_depth_2d = FAIL
// TODO: Investigate why these are failing/crashing:
3565 SWIFTSHADER : dEQP-GLES31.functional.texture.multisample.samples_1.sample_mask_and*alpha_to_coverage = SKIP
3565 SWIFTSHADER : dEQP-GLES31.functional.texture.multisample.samples_3.sample_position = FAIL
3565 SWIFTSHADER : dEQP-GLES31.functional.texture.multisample.samples_4.sample_position = FAIL
// Multisampled shader support:
// The following tests pass, but fail because of Vulkan validation-layer errors, which are likely
// a bug in the validation layers:
3565 VULKAN : dEQP-GLES31.functional.shaders.builtin_functions.texture_size.samples_1_texture_2d = FAIL
3565 VULKAN : dEQP-GLES31.functional.shaders.builtin_functions.texture_size.samples_1_texture_int_2d = FAIL
3565 VULKAN : dEQP-GLES31.functional.shaders.builtin_functions.texture_size.samples_1_texture_uint_2d = FAIL
// Vulkan creates the image view with the same format as the texture. // Vulkan creates the image view with the same format as the texture.
3885 VULKAN : dEQP-GLES31.functional.image_load_store.*.format_reinterpret.* = FAIL 3885 VULKAN : dEQP-GLES31.functional.image_load_store.*.format_reinterpret.* = FAIL
...@@ -686,13 +706,6 @@ ...@@ -686,13 +706,6 @@
4102 SWIFTSHADER : dEQP-GLES31.functional.state_query.integer.max_framebuffer_width_getinteger = FAIL 4102 SWIFTSHADER : dEQP-GLES31.functional.state_query.integer.max_framebuffer_width_getinteger = FAIL
4102 SWIFTSHADER : dEQP-GLES31.functional.state_query.integer.max_framebuffer_width_getinteger64 = FAIL 4102 SWIFTSHADER : dEQP-GLES31.functional.state_query.integer.max_framebuffer_width_getinteger64 = FAIL
4103 SWIFTSHADER : dEQP-GLES31.functional.state_query.texture_level.texture_2d_multisample.* = FAIL
4104 SWIFTSHADER : dEQP-GLES31.functional.state_query.texture.texture_2d_multisample.texture_immutable_format_float = FAIL
4104 SWIFTSHADER : dEQP-GLES31.functional.state_query.texture.texture_2d_multisample.texture_immutable_format_integer = FAIL
4104 SWIFTSHADER : dEQP-GLES31.functional.state_query.texture.texture_2d_multisample.texture_immutable_levels_float = FAIL
4104 SWIFTSHADER : dEQP-GLES31.functional.state_query.texture.texture_2d_multisample.texture_immutable_levels_integer = FAIL
4105 SWIFTSHADER : dEQP-GLES31.functional.stencil_texturing.format.depth24_stencil8_cube = FAIL 4105 SWIFTSHADER : dEQP-GLES31.functional.stencil_texturing.format.depth24_stencil8_cube = FAIL
4105 SWIFTSHADER : dEQP-GLES31.functional.stencil_texturing.format.depth32f_stencil8_cube = FAIL 4105 SWIFTSHADER : dEQP-GLES31.functional.stencil_texturing.format.depth32f_stencil8_cube = FAIL
......
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