Commit 22695bf5 by Luc Ferron Committed by Commit Bot

Vulkan: Support cube mimaps generation

Bug: angleproject:2502 Change-Id: I953d99d04608cec04aad824b8b38f388ed1e4c2b Reviewed-on: https://chromium-review.googlesource.com/1069544 Commit-Queue: Luc Ferron <lucferron@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent c5181706
...@@ -316,6 +316,7 @@ gl::Error PixelBuffer::stageSubresourceUpdateAndGetData(RendererVk *renderer, ...@@ -316,6 +316,7 @@ gl::Error PixelBuffer::stageSubresourceUpdateAndGetData(RendererVk *renderer,
gl::Error TextureVk::generateMipmapLevels(ContextVk *contextVk, gl::Error TextureVk::generateMipmapLevels(ContextVk *contextVk,
const angle::Format &sourceFormat, const angle::Format &sourceFormat,
GLuint layer,
GLuint firstMipLevel, GLuint firstMipLevel,
GLuint maxMipLevel, GLuint maxMipLevel,
const size_t sourceWidth, const size_t sourceWidth,
...@@ -345,7 +346,7 @@ gl::Error TextureVk::generateMipmapLevels(ContextVk *contextVk, ...@@ -345,7 +346,7 @@ gl::Error TextureVk::generateMipmapLevels(ContextVk *contextVk,
ANGLE_TRY(mPixelBuffer.stageSubresourceUpdateAndGetData( ANGLE_TRY(mPixelBuffer.stageSubresourceUpdateAndGetData(
renderer, mipAllocationSize, renderer, mipAllocationSize,
gl::ImageIndex::MakeFromType(mState.getType(), currentMipLevel, 0, 1), mipLevelExtents, gl::ImageIndex::MakeFromType(mState.getType(), currentMipLevel, layer), mipLevelExtents,
gl::Offset(), &destData)); gl::Offset(), &destData));
// Generate the mipmap into that new buffer // Generate the mipmap into that new buffer
...@@ -591,10 +592,8 @@ gl::Error TextureVk::setImageExternal(const gl::Context *context, ...@@ -591,10 +592,8 @@ gl::Error TextureVk::setImageExternal(const gl::Context *context,
gl::Error TextureVk::generateMipmap(const gl::Context *context) gl::Error TextureVk::generateMipmap(const gl::Context *context)
{ {
ContextVk *contextVk = vk::GetImpl(context); ContextVk *contextVk = vk::GetImpl(context);
vk::CommandBuffer *commandBuffer = nullptr; RendererVk *renderer = contextVk->getRenderer();
RendererVk *renderer = contextVk->getRenderer();
getCommandBufferForWrite(renderer, &commandBuffer);
// Some data is pending, or the image has not been defined at all yet // Some data is pending, or the image has not been defined at all yet
if (!mImage.valid()) if (!mImage.valid())
...@@ -614,22 +613,36 @@ gl::Error TextureVk::generateMipmap(const gl::Context *context) ...@@ -614,22 +613,36 @@ gl::Error TextureVk::generateMipmap(const gl::Context *context)
// Before we loop to generate all the next levels, we can get the source level and copy it to a // Before we loop to generate all the next levels, we can get the source level and copy it to a
// buffer. // buffer.
const angle::Format &angleFormat = mImage.getFormat().textureFormat(); const angle::Format &angleFormat = mImage.getFormat().textureFormat();
VkBuffer baseLevelBufferHandle = VK_NULL_HANDLE; uint32_t imageLayerCount = GetImageLayerCount(mState.getType());
uint8_t *baseLevelBuffer = nullptr;
bool newBufferAllocated = false; bool newBufferAllocated = false;
uint32_t baseLevelBufferOffset = 0;
const gl::Extents baseLevelExtents = mImage.getExtents(); const gl::Extents baseLevelExtents = mImage.getExtents();
GLuint sourceRowPitch = baseLevelExtents.width * angleFormat.pixelBytes; GLuint sourceRowPitch = baseLevelExtents.width * angleFormat.pixelBytes;
size_t baseLevelAllocationSize = sourceRowPitch * baseLevelExtents.height; size_t baseLevelAllocationSize = sourceRowPitch * baseLevelExtents.height;
ANGLE_TRY(mPixelBuffer.allocate(renderer, baseLevelAllocationSize, &baseLevelBuffer, vk::CommandBuffer *commandBuffer = nullptr;
&baseLevelBufferHandle, &baseLevelBufferOffset, getCommandBufferForWrite(renderer, &commandBuffer);
&newBufferAllocated));
// Requirement of the copyImageToBuffer, the source image must be in SRC_OPTIMAL layout.
mImage.changeLayoutWithStages(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, commandBuffer);
size_t totalAllocationSize = baseLevelAllocationSize * imageLayerCount;
VkBuffer copyBufferHandle;
uint8_t *baseLevelBuffers;
uint32_t copyBaseOffset;
// Allocate enough memory to copy every level 0 image (one for each layer of the texture).
ANGLE_TRY(mPixelBuffer.allocate(renderer, totalAllocationSize, &baseLevelBuffers,
&copyBufferHandle, &copyBaseOffset, &newBufferAllocated));
// Do only one copy for all layers at once.
VkBufferImageCopy region; VkBufferImageCopy region;
region.bufferImageHeight = baseLevelExtents.height; region.bufferImageHeight = baseLevelExtents.height;
region.bufferOffset = static_cast<VkDeviceSize>(baseLevelBufferOffset); region.bufferOffset = static_cast<VkDeviceSize>(copyBaseOffset);
region.bufferRowLength = baseLevelExtents.width; region.bufferRowLength = baseLevelExtents.width;
region.imageExtent.width = baseLevelExtents.width; region.imageExtent.width = baseLevelExtents.width;
region.imageExtent.height = baseLevelExtents.height; region.imageExtent.height = baseLevelExtents.height;
...@@ -639,15 +652,11 @@ gl::Error TextureVk::generateMipmap(const gl::Context *context) ...@@ -639,15 +652,11 @@ gl::Error TextureVk::generateMipmap(const gl::Context *context)
region.imageOffset.z = 0; region.imageOffset.z = 0;
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.imageSubresource.baseArrayLayer = 0; region.imageSubresource.baseArrayLayer = 0;
region.imageSubresource.layerCount = 1; region.imageSubresource.layerCount = imageLayerCount;
region.imageSubresource.mipLevel = mState.getEffectiveBaseLevel(); region.imageSubresource.mipLevel = mState.getEffectiveBaseLevel();
mImage.changeLayoutWithStages(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, commandBuffer->copyImageToBuffer(mImage.getImage(), mImage.getCurrentLayout(), copyBufferHandle,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 1, &region);
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, commandBuffer);
commandBuffer->copyImageToBuffer(mImage.getImage(), mImage.getCurrentLayout(),
baseLevelBufferHandle, 1, &region);
ANGLE_TRY(renderer->finish(context)); ANGLE_TRY(renderer->finish(context));
...@@ -657,9 +666,15 @@ gl::Error TextureVk::generateMipmap(const gl::Context *context) ...@@ -657,9 +666,15 @@ gl::Error TextureVk::generateMipmap(const gl::Context *context)
// We now have the base level available to be manipulated in the baseLevelBuffer pointer. // We now have the base level available to be manipulated in the baseLevelBuffer pointer.
// Generate all the missing mipmaps with the slow path. We can optimize with vkCmdBlitImage // Generate all the missing mipmaps with the slow path. We can optimize with vkCmdBlitImage
// later. // later.
ANGLE_TRY(generateMipmapLevels(contextVk, angleFormat, mState.getEffectiveBaseLevel() + 1, // For each layer, use the copied data to generate all the mips.
mState.getMipmapMaxLevel(), baseLevelExtents.width, for (GLuint layer = 0; layer < imageLayerCount; layer++)
baseLevelExtents.height, sourceRowPitch, baseLevelBuffer)); {
size_t bufferOffset = layer * baseLevelAllocationSize;
ANGLE_TRY(generateMipmapLevels(
contextVk, angleFormat, layer, mState.getEffectiveBaseLevel() + 1,
mState.getMipmapMaxLevel(), baseLevelExtents.width, baseLevelExtents.height,
sourceRowPitch, baseLevelBuffers + bufferOffset));
}
return gl::NoError(); return gl::NoError();
} }
......
...@@ -177,6 +177,7 @@ class TextureVk : public TextureImpl, public vk::CommandGraphResource ...@@ -177,6 +177,7 @@ class TextureVk : public TextureImpl, public vk::CommandGraphResource
private: private:
gl::Error generateMipmapLevels(ContextVk *contextVk, gl::Error generateMipmapLevels(ContextVk *contextVk,
const angle::Format &sourceFormat, const angle::Format &sourceFormat,
GLuint layer,
GLuint firstMipLevel, GLuint firstMipLevel,
GLuint maxMipLevel, GLuint maxMipLevel,
size_t sourceWidth, size_t sourceWidth,
......
...@@ -80,17 +80,6 @@ VkImageCreateFlags GetImageCreateFlags(gl::TextureType textureType) ...@@ -80,17 +80,6 @@ VkImageCreateFlags GetImageCreateFlags(gl::TextureType textureType)
} }
} }
uint32_t GetImageLayerCount(gl::TextureType textureType)
{
if (textureType == gl::TextureType::CubeMap)
{
return gl::CUBE_FACE_COUNT;
}
else
{
return 1;
}
}
} // anonymous namespace } // anonymous namespace
// DynamicBuffer implementation. // DynamicBuffer implementation.
......
...@@ -149,6 +149,18 @@ vk::Error AllocateBufferOrImageMemory(VkDevice device, ...@@ -149,6 +149,18 @@ vk::Error AllocateBufferOrImageMemory(VkDevice device,
} }
} // anonymous namespace } // anonymous namespace
uint32_t GetImageLayerCount(gl::TextureType textureType)
{
if (textureType == gl::TextureType::CubeMap)
{
return gl::CUBE_FACE_COUNT;
}
else
{
return 1;
}
}
const char *g_VkLoaderLayersPathEnv = "VK_LAYER_PATH"; const char *g_VkLoaderLayersPathEnv = "VK_LAYER_PATH";
const char *g_VkICDPathEnv = "VK_ICD_FILENAMES"; const char *g_VkICDPathEnv = "VK_ICD_FILENAMES";
......
...@@ -69,6 +69,8 @@ bool GetAvailableValidationLayers(const std::vector<VkLayerProperties> &layerPro ...@@ -69,6 +69,8 @@ bool GetAvailableValidationLayers(const std::vector<VkLayerProperties> &layerPro
const char *const **enabledLayerNames, const char *const **enabledLayerNames,
uint32_t *enabledLayerCount); uint32_t *enabledLayerCount);
uint32_t GetImageLayerCount(gl::TextureType textureType);
extern const char *g_VkLoaderLayersPathEnv; extern const char *g_VkLoaderLayersPathEnv;
extern const char *g_VkICDPathEnv; extern const char *g_VkICDPathEnv;
......
...@@ -237,7 +237,6 @@ ...@@ -237,7 +237,6 @@
2593 VULKAN : dEQP-GLES2.functional.shaders.invariance.mediump.loop_4 = SKIP 2593 VULKAN : dEQP-GLES2.functional.shaders.invariance.mediump.loop_4 = SKIP
2594 VULKAN : dEQP-GLES2.functional.shaders.fragdata.valid_static_index = SKIP 2594 VULKAN : dEQP-GLES2.functional.shaders.fragdata.valid_static_index = SKIP
2595 VULKAN : dEQP-GLES2.functional.shaders.random.all_features.fragment* = SKIP 2595 VULKAN : dEQP-GLES2.functional.shaders.random.all_features.fragment* = SKIP
2161 VULKAN : dEQP-GLES2.functional.texture.mipmap.cube.generate.* = SKIP
2596 VULKAN : dEQP-GLES2.functional.texture.completeness.2d.extra_level = SKIP 2596 VULKAN : dEQP-GLES2.functional.texture.completeness.2d.extra_level = SKIP
2596 VULKAN : dEQP-GLES2.functional.texture.completeness.cube.extra_level = SKIP 2596 VULKAN : dEQP-GLES2.functional.texture.completeness.cube.extra_level = SKIP
2597 VULKAN : dEQP-GLES2.functional.fbo.render.color_clear.* = SKIP 2597 VULKAN : dEQP-GLES2.functional.fbo.render.color_clear.* = SKIP
......
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