Commit fa7503ca by Luc Ferron Committed by Commit Bot

Vulkan: Support EXT_texture_storage

This is a prerequisite to support incomplete textures. Bug: angleproject:2536 Change-Id: Ica40bbd185a67253f457148007b08f6735da788c Reviewed-on: https://chromium-review.googlesource.com/1050308Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Luc Ferron <lucferron@chromium.org>
parent 67d2cd07
...@@ -322,14 +322,41 @@ gl::Error TextureVk::copySubImage(const gl::Context *context, ...@@ -322,14 +322,41 @@ gl::Error TextureVk::copySubImage(const gl::Context *context,
return gl::InternalError(); return gl::InternalError();
} }
vk::Error TextureVk::getCommandBufferForWrite(RendererVk *renderer,
vk::CommandBuffer **outCommandBuffer)
{
const VkDevice device = renderer->getDevice();
updateQueueSerial(renderer->getCurrentQueueSerial());
if (!hasChildlessWritingNode())
{
beginWriteResource(renderer, outCommandBuffer);
}
else
{
vk::CommandGraphNode *node = getCurrentWritingNode();
*outCommandBuffer = node->getOutsideRenderPassCommands();
if (!(*outCommandBuffer)->valid())
{
ANGLE_TRY(node->beginOutsideRenderPassRecording(device, renderer->getCommandPool(),
outCommandBuffer));
}
}
return vk::NoError();
}
gl::Error TextureVk::setStorage(const gl::Context *context, gl::Error TextureVk::setStorage(const gl::Context *context,
gl::TextureType type, gl::TextureType type,
size_t levels, size_t levels,
GLenum internalFormat, GLenum internalFormat,
const gl::Extents &size) const gl::Extents &size)
{ {
UNIMPLEMENTED(); ContextVk *contextVk = GetAs<ContextVk>(context->getImplementation());
return gl::InternalError(); RendererVk *renderer = contextVk->getRenderer();
const vk::Format &format = renderer->getFormat(internalFormat);
vk::CommandBuffer *commandBuffer = nullptr;
ANGLE_TRY(getCommandBufferForWrite(renderer, &commandBuffer));
ANGLE_TRY(initImage(renderer, format, size, static_cast<uint32_t>(levels), commandBuffer));
return gl::NoError();
} }
gl::Error TextureVk::setEGLImageTarget(const gl::Context *context, gl::Error TextureVk::setEGLImageTarget(const gl::Context *context,
...@@ -378,7 +405,7 @@ gl::Error TextureVk::getAttachmentRenderTarget(const gl::Context *context, ...@@ -378,7 +405,7 @@ gl::Error TextureVk::getAttachmentRenderTarget(const gl::Context *context,
const gl::ImageIndex &imageIndex, const gl::ImageIndex &imageIndex,
FramebufferAttachmentRenderTarget **rtOut) FramebufferAttachmentRenderTarget **rtOut)
{ {
// TODO(jmadill): Handle cube textures. http://anglebug.com/2318 // TODO(jmadill): Handle cube textures. http://anglebug.com/2470
ASSERT(imageIndex.getType() == gl::TextureType::_2D); ASSERT(imageIndex.getType() == gl::TextureType::_2D);
// Non-zero mip level attachments are an ES 3.0 feature. // Non-zero mip level attachments are an ES 3.0 feature.
...@@ -400,56 +427,18 @@ vk::Error TextureVk::ensureImageInitialized(RendererVk *renderer) ...@@ -400,56 +427,18 @@ vk::Error TextureVk::ensureImageInitialized(RendererVk *renderer)
return vk::NoError(); return vk::NoError();
} }
VkDevice device = renderer->getDevice();
vk::CommandBuffer *commandBuffer = nullptr; vk::CommandBuffer *commandBuffer = nullptr;
ANGLE_TRY(getCommandBufferForWrite(renderer, &commandBuffer));
updateQueueSerial(renderer->getCurrentQueueSerial());
if (!hasChildlessWritingNode())
{
beginWriteResource(renderer, &commandBuffer);
}
else
{
vk::CommandGraphNode *node = getCurrentWritingNode();
commandBuffer = node->getOutsideRenderPassCommands();
if (!commandBuffer->valid())
{
ANGLE_TRY(node->beginOutsideRenderPassRecording(device, renderer->getCommandPool(),
&commandBuffer));
}
}
if (!mImage.valid()) if (!mImage.valid())
{ {
const gl::ImageDesc &baseLevelDesc = mState.getBaseLevelDesc(); const gl::ImageDesc &baseLevelDesc = mState.getBaseLevelDesc();
const gl::Extents &extents = baseLevelDesc.size;
const vk::Format &format = const vk::Format &format =
renderer->getFormat(baseLevelDesc.format.info->sizedInternalFormat); renderer->getFormat(baseLevelDesc.format.info->sizedInternalFormat);
const gl::Extents &extents = baseLevelDesc.size;
VkImageUsageFlags usage =
(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
const uint32_t levelCount = getLevelCount(); const uint32_t levelCount = getLevelCount();
ANGLE_TRY(mImage.init(device, mState.getType(), extents, format, 1, usage, levelCount));
VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
ANGLE_TRY(mImage.initMemory(device, renderer->getMemoryProperties(), flags));
gl::SwizzleState mappedSwizzle;
MapSwizzleState(format.internalFormat, mState.getSwizzleState(), &mappedSwizzle);
// TODO(jmadill): Separate imageviews for RenderTargets and Sampling.
ANGLE_TRY(mImage.initImageView(device, mState.getType(), VK_IMAGE_ASPECT_COLOR_BIT,
mappedSwizzle, &mMipmapImageView, levelCount));
ANGLE_TRY(mImage.initImageView(device, mState.getType(), VK_IMAGE_ASPECT_COLOR_BIT,
mappedSwizzle, &mBaseLevelImageView, 1));
// TODO(jmadill): Fold this into the RenderPass load/store ops. http://anglebug.com/2361 ANGLE_TRY(initImage(renderer, format, extents, levelCount, commandBuffer));
VkClearColorValue black = {{0}};
mImage.clearColor(black, commandBuffer);
} }
ANGLE_TRY(mPixelBuffer.flushUpdatesToImage(renderer, &mImage, commandBuffer)); ANGLE_TRY(mPixelBuffer.flushUpdatesToImage(renderer, &mImage, commandBuffer));
...@@ -540,6 +529,39 @@ const vk::Sampler &TextureVk::getSampler() const ...@@ -540,6 +529,39 @@ const vk::Sampler &TextureVk::getSampler() const
return mSampler; return mSampler;
} }
vk::Error TextureVk::initImage(RendererVk *renderer,
const vk::Format &format,
const gl::Extents &extents,
const uint32_t levelCount,
vk::CommandBuffer *commandBuffer)
{
const VkDevice device = renderer->getDevice();
const VkImageUsageFlags usage =
(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
ANGLE_TRY(mImage.init(device, mState.getType(), extents, format, 1, usage, levelCount));
const VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
ANGLE_TRY(mImage.initMemory(device, renderer->getMemoryProperties(), flags));
gl::SwizzleState mappedSwizzle;
MapSwizzleState(format.internalFormat, mState.getSwizzleState(), &mappedSwizzle);
// TODO(jmadill): Separate imageviews for RenderTargets and Sampling.
ANGLE_TRY(mImage.initImageView(device, mState.getType(), VK_IMAGE_ASPECT_COLOR_BIT,
mappedSwizzle, &mMipmapImageView, levelCount));
ANGLE_TRY(mImage.initImageView(device, mState.getType(), VK_IMAGE_ASPECT_COLOR_BIT,
mappedSwizzle, &mBaseLevelImageView, 1));
// TODO(jmadill): Fold this into the RenderPass load/store ops. http://anglebug.com/2361
VkClearColorValue black = {{0}};
mImage.clearColor(black, commandBuffer);
return vk::NoError();
}
void TextureVk::releaseImage(const gl::Context *context, RendererVk *renderer) void TextureVk::releaseImage(const gl::Context *context, RendererVk *renderer)
{ {
mImage.release(renderer->getCurrentQueueSerial(), renderer); mImage.release(renderer->getCurrentQueueSerial(), renderer);
......
...@@ -152,7 +152,13 @@ class TextureVk : public TextureImpl, public vk::CommandGraphResource ...@@ -152,7 +152,13 @@ class TextureVk : public TextureImpl, public vk::CommandGraphResource
vk::Error ensureImageInitialized(RendererVk *renderer); vk::Error ensureImageInitialized(RendererVk *renderer);
private: private:
vk::Error initImage(RendererVk *renderer,
const vk::Format &format,
const gl::Extents &extents,
const uint32_t levelCount,
vk::CommandBuffer *commandBuffer);
void releaseImage(const gl::Context *context, RendererVk *renderer); void releaseImage(const gl::Context *context, RendererVk *renderer);
vk::Error getCommandBufferForWrite(RendererVk *renderer, vk::CommandBuffer **outCommandBuffer);
uint32_t getLevelCount() const; uint32_t getLevelCount() const;
vk::ImageHelper mImage; vk::ImageHelper mImage;
......
...@@ -33,6 +33,7 @@ void GenerateCaps(const VkPhysicalDeviceProperties &physicalDeviceProperties, ...@@ -33,6 +33,7 @@ void GenerateCaps(const VkPhysicalDeviceProperties &physicalDeviceProperties,
// TODO(jmadill): Support full mapBufferRange extension. // TODO(jmadill): Support full mapBufferRange extension.
outExtensions->mapBuffer = true; outExtensions->mapBuffer = true;
outExtensions->mapBufferRange = true; outExtensions->mapBufferRange = true;
outExtensions->textureStorage = true;
// TODO(lucferron): Eventually remove everything above this line in this function as the caps // TODO(lucferron): Eventually remove everything above this line in this function as the caps
// get implemented. // get implemented.
......
...@@ -272,6 +272,9 @@ TEST_P(FramebufferFormatsTest, RenderbufferMultisample_STENCIL_INDEX8) ...@@ -272,6 +272,9 @@ TEST_P(FramebufferFormatsTest, RenderbufferMultisample_STENCIL_INDEX8)
// Test that binding an incomplete cube map is rejected by ANGLE. // Test that binding an incomplete cube map is rejected by ANGLE.
TEST_P(FramebufferFormatsTest, IncompleteCubeMap) TEST_P(FramebufferFormatsTest, IncompleteCubeMap)
{ {
// TODO(jmadill): Handle cube textures. http://anglebug.com/2470
ANGLE_SKIP_TEST_IF(IsVulkan());
// First make a complete CubeMap. // First make a complete CubeMap.
glGenTextures(1, &mTexture); glGenTextures(1, &mTexture);
glBindTexture(GL_TEXTURE_CUBE_MAP, mTexture); glBindTexture(GL_TEXTURE_CUBE_MAP, mTexture);
...@@ -322,6 +325,7 @@ TEST_P(FramebufferFormatsTest, ZeroHeightRenderbuffer) ...@@ -322,6 +325,7 @@ TEST_P(FramebufferFormatsTest, ZeroHeightRenderbuffer)
// Use this to select which configurations (e.g. which renderer, which GLES major version) these // Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against. // tests should be run against.
ANGLE_INSTANTIATE_TEST(FramebufferFormatsTest, ANGLE_INSTANTIATE_TEST(FramebufferFormatsTest,
ES2_VULKAN(),
ES2_D3D9(), ES2_D3D9(),
ES2_D3D11(), ES2_D3D11(),
ES3_D3D11(), ES3_D3D11(),
......
...@@ -1398,7 +1398,10 @@ TEST_P(TextureCubeTest, CubeMapFBO) ...@@ -1398,7 +1398,10 @@ TEST_P(TextureCubeTest, CubeMapFBO)
// Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a default color. // Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a default color.
TEST_P(Texture2DTest, TexStorage) TEST_P(Texture2DTest, TexStorage)
{ {
ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_texture_storage")); // TODO(lucferron): Follow up to clear with opaque black in TextureVk::initImageAndViews.
// http://anglebug.com/2536
ANGLE_SKIP_TEST_IF(IsVulkan() ||
getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_texture_storage"));
int width = getWindowWidth(); int width = getWindowWidth();
int height = getWindowHeight(); int height = getWindowHeight();
...@@ -1558,6 +1561,10 @@ TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGB) ...@@ -1558,6 +1561,10 @@ TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGB)
TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGBA) TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGBA)
{ {
// TODO(lucferron): copySubImage isn't implemented yet.
// http://anglebug.com/2501
ANGLE_SKIP_TEST_IF(IsVulkan());
// Ignore SDK layers messages on D3D11 FL 9.3 (http://anglebug.com/1284) // Ignore SDK layers messages on D3D11 FL 9.3 (http://anglebug.com/1284)
ANGLE_SKIP_TEST_IF(IsD3D11_FL93()); ANGLE_SKIP_TEST_IF(IsD3D11_FL93());
......
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