Commit 26084d0a by Jamie Madill Committed by Commit Bot

Vulkan: Create TextureVk's Image lazily.

This defers the actual Image initialization until the Image is used as either a Framebuffer Attachment or OpenGL Texture object. This will allow us to construct an Image from multiple sub resources, like when we're initializing a mip chain, or a cube map texture. Also adds a helper "hasDepthOrStencilBits" function to angle::Format. Bug: angleproject:2318 Change-Id: Ife861560216581a90fc6da32a583f69886c7daea Reviewed-on: https://chromium-review.googlesource.com/985202Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 3418fe80
...@@ -219,6 +219,12 @@ bool TextureState::isCubeComplete() const ...@@ -219,6 +219,12 @@ bool TextureState::isCubeComplete() const
return true; return true;
} }
const ImageDesc &TextureState::getBaseLevelDesc() const
{
ASSERT(mType != TextureType::CubeMap || isCubeComplete());
return getImageDesc(getBaseImageTarget(), getEffectiveBaseLevel());
}
void TextureState::setCrop(const gl::Rectangle& rect) void TextureState::setCrop(const gl::Rectangle& rect)
{ {
mCropRect = rect; mCropRect = rect;
......
...@@ -115,6 +115,9 @@ struct TextureState final : private angle::NonCopyable ...@@ -115,6 +115,9 @@ struct TextureState final : private angle::NonCopyable
GLenum getUsage() const { return mUsage; } GLenum getUsage() const { return mUsage; }
GLenum getDepthStencilTextureMode() const { return mDepthStencilTextureMode; } GLenum getDepthStencilTextureMode() const { return mDepthStencilTextureMode; }
// Returns the desc of the base level. Only valid for cube-complete/mip-complete textures.
const ImageDesc &getBaseLevelDesc() const;
// GLES1 emulation: For GL_OES_draw_texture // GLES1 emulation: For GL_OES_draw_texture
void setCrop(const gl::Rectangle& rect); void setCrop(const gl::Rectangle& rect);
const gl::Rectangle& getCrop() const; const gl::Rectangle& getCrop() const;
......
...@@ -41,6 +41,8 @@ struct Format final : private angle::NonCopyable ...@@ -41,6 +41,8 @@ struct Format final : private angle::NonCopyable
static const Format &Get(ID id); static const Format &Get(ID id);
static ID InternalFormatToID(GLenum internalFormat); static ID InternalFormatToID(GLenum internalFormat);
constexpr bool hasDepthOrStencilBits() const;
ID id; ID id;
// The closest matching GL internal format for the storage this format uses. Note that this // The closest matching GL internal format for the storage this format uses. Note that this
...@@ -108,6 +110,10 @@ constexpr Format::Format(ID id, ...@@ -108,6 +110,10 @@ constexpr Format::Format(ID id,
{ {
} }
constexpr bool Format::hasDepthOrStencilBits() const
{
return depthBits > 0 || stencilBits > 0;
}
} // namespace angle } // namespace angle
#include "libANGLE/renderer/Format_ID_autogen.inl" #include "libANGLE/renderer/Format_ID_autogen.inl"
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "libANGLE/renderer/vulkan/RenderTargetVk.h" #include "libANGLE/renderer/vulkan/RenderTargetVk.h"
#include "libANGLE/renderer/vulkan/RendererVk.h" #include "libANGLE/renderer/vulkan/RendererVk.h"
#include "libANGLE/renderer/vulkan/vk_format_utils.h" #include "libANGLE/renderer/vulkan/vk_format_utils.h"
#include "libANGLE/renderer/vulkan/vk_helpers.h"
namespace rx namespace rx
{ {
...@@ -142,7 +143,8 @@ void CommandGraphResource::onReadResource(CommandGraphNode *readingNode, Serial ...@@ -142,7 +143,8 @@ void CommandGraphResource::onReadResource(CommandGraphNode *readingNode, Serial
bool CommandGraphResource::checkResourceInUseAndRefreshDeps(RendererVk *renderer) bool CommandGraphResource::checkResourceInUseAndRefreshDeps(RendererVk *renderer)
{ {
if (!renderer->isResourceInUse(*this)) if (!renderer->isResourceInUse(*this) ||
(renderer->getCurrentQueueSerial() > mStoredQueueSerial))
{ {
mCurrentReadingNodes.clear(); mCurrentReadingNodes.clear();
mCurrentWritingNode = nullptr; mCurrentWritingNode = nullptr;
...@@ -243,6 +245,14 @@ void CommandGraphNode::storeRenderPassInfo(const Framebuffer &framebuffer, ...@@ -243,6 +245,14 @@ void CommandGraphNode::storeRenderPassInfo(const Framebuffer &framebuffer,
void CommandGraphNode::appendColorRenderTarget(Serial serial, RenderTargetVk *colorRenderTarget) void CommandGraphNode::appendColorRenderTarget(Serial serial, RenderTargetVk *colorRenderTarget)
{ {
ASSERT(mOutsideRenderPassCommands.valid());
// TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361
colorRenderTarget->image->changeLayoutWithStages(
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
&mOutsideRenderPassCommands);
mRenderPassDesc.packColorAttachment(*colorRenderTarget->image); mRenderPassDesc.packColorAttachment(*colorRenderTarget->image);
colorRenderTarget->resource->onWriteResource(this, serial); colorRenderTarget->resource->onWriteResource(this, serial);
} }
...@@ -250,6 +260,19 @@ void CommandGraphNode::appendColorRenderTarget(Serial serial, RenderTargetVk *co ...@@ -250,6 +260,19 @@ void CommandGraphNode::appendColorRenderTarget(Serial serial, RenderTargetVk *co
void CommandGraphNode::appendDepthStencilRenderTarget(Serial serial, void CommandGraphNode::appendDepthStencilRenderTarget(Serial serial,
RenderTargetVk *depthStencilRenderTarget) RenderTargetVk *depthStencilRenderTarget)
{ {
ASSERT(mOutsideRenderPassCommands.valid());
ASSERT(depthStencilRenderTarget->image->getFormat().textureFormat().hasDepthOrStencilBits());
// TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361
const angle::Format &format = depthStencilRenderTarget->image->getFormat().textureFormat();
VkImageAspectFlags aspectFlags = (format.depthBits > 0 ? VK_IMAGE_ASPECT_DEPTH_BIT : 0) |
(format.stencilBits > 0 ? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
depthStencilRenderTarget->image->changeLayoutWithStages(
aspectFlags, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
&mOutsideRenderPassCommands);
mRenderPassDesc.packDepthStencilAttachment(*depthStencilRenderTarget->image); mRenderPassDesc.packDepthStencilAttachment(*depthStencilRenderTarget->image);
depthStencilRenderTarget->resource->onWriteResource(this, serial); depthStencilRenderTarget->resource->onWriteResource(this, serial);
} }
......
...@@ -174,6 +174,7 @@ gl::Error ContextVk::setupDraw(const gl::Context *context, ...@@ -174,6 +174,7 @@ gl::Error ContextVk::setupDraw(const gl::Context *context,
ASSERT(texture); ASSERT(texture);
TextureVk *textureVk = vk::GetImpl(texture); TextureVk *textureVk = vk::GetImpl(texture);
ANGLE_TRY(textureVk->ensureImageInitialized(mRenderer));
textureVk->onReadResource(graphNode, mRenderer->getCurrentQueueSerial()); textureVk->onReadResource(graphNode, mRenderer->getCurrentQueueSerial());
} }
} }
......
...@@ -568,11 +568,6 @@ gl::Error FramebufferVk::getCommandGraphNodeForDraw(const gl::Context *context, ...@@ -568,11 +568,6 @@ gl::Error FramebufferVk::getCommandGraphNodeForDraw(const gl::Context *context,
RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex]; RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex];
ASSERT(colorRenderTarget); ASSERT(colorRenderTarget);
// TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361
colorRenderTarget->image->changeLayoutWithStages(
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
commandBuffer);
(*nodeOut)->appendColorRenderTarget(currentSerial, colorRenderTarget); (*nodeOut)->appendColorRenderTarget(currentSerial, colorRenderTarget);
attachmentClearValues.emplace_back(contextVk->getClearColorValue()); attachmentClearValues.emplace_back(contextVk->getClearColorValue());
} }
...@@ -580,15 +575,6 @@ gl::Error FramebufferVk::getCommandGraphNodeForDraw(const gl::Context *context, ...@@ -580,15 +575,6 @@ gl::Error FramebufferVk::getCommandGraphNodeForDraw(const gl::Context *context,
RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil(); RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil();
if (depthStencilRenderTarget) if (depthStencilRenderTarget)
{ {
// TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361
const angle::Format &format = depthStencilRenderTarget->image->getFormat().textureFormat();
VkImageAspectFlags aspectFlags = (format.depthBits > 0 ? VK_IMAGE_ASPECT_DEPTH_BIT : 0) |
(format.stencilBits > 0 ? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
depthStencilRenderTarget->image->changeLayoutWithStages(
aspectFlags, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
commandBuffer);
(*nodeOut)->appendDepthStencilRenderTarget(currentSerial, depthStencilRenderTarget); (*nodeOut)->appendDepthStencilRenderTarget(currentSerial, depthStencilRenderTarget);
attachmentClearValues.emplace_back(contextVk->getClearDepthStencilValue()); attachmentClearValues.emplace_back(contextVk->getClearDepthStencilValue());
} }
......
...@@ -18,6 +18,31 @@ ...@@ -18,6 +18,31 @@
namespace rx namespace rx
{ {
class StagingStorage final : angle::NonCopyable
{
public:
StagingStorage();
~StagingStorage();
void release(RendererVk *renderer);
gl::Error stageSubresourceUpdate(ContextVk *contextVk,
const gl::Extents &extents,
const gl::InternalFormat &formatInfo,
const gl::PixelUnpackState &unpack,
GLenum type,
const uint8_t *pixels);
vk::Error flushUpdatesToImage(RendererVk *renderer,
vk::ImageHelper *image,
vk::CommandBuffer *commandBuffer);
private:
vk::DynamicBuffer mStagingBuffer;
VkBuffer mCurrentBufferHandle;
VkBufferImageCopy mCurrentCopyRegion;
};
class TextureVk : public TextureImpl, public vk::CommandGraphResource class TextureVk : public TextureImpl, public vk::CommandGraphResource
{ {
public: public:
...@@ -116,18 +141,16 @@ class TextureVk : public TextureImpl, public vk::CommandGraphResource ...@@ -116,18 +141,16 @@ class TextureVk : public TextureImpl, public vk::CommandGraphResource
const vk::ImageView &getImageView() const; const vk::ImageView &getImageView() const;
const vk::Sampler &getSampler() const; const vk::Sampler &getSampler() const;
private: vk::Error ensureImageInitialized(RendererVk *renderer);
gl::Error setSubImageImpl(ContextVk *contextVk,
const gl::InternalFormat &formatInfo,
const gl::PixelUnpackState &unpack,
GLenum type,
const uint8_t *pixels);
private:
vk::ImageHelper mImage; vk::ImageHelper mImage;
vk::ImageView mImageView; vk::ImageView mImageView;
vk::Sampler mSampler; vk::Sampler mSampler;
RenderTargetVk mRenderTarget; RenderTargetVk mRenderTarget;
StagingStorage mStagingStorage;
}; };
} // namespace rx } // namespace rx
......
...@@ -141,7 +141,6 @@ gl::Error VertexArrayVk::streamIndexData(RendererVk *renderer, ...@@ -141,7 +141,6 @@ gl::Error VertexArrayVk::streamIndexData(RendererVk *renderer,
ANGLE_TRY(mDynamicIndexData.flush(renderer->getDevice())); ANGLE_TRY(mDynamicIndexData.flush(renderer->getDevice()));
mCurrentElementArrayBufferOffset = offset; mCurrentElementArrayBufferOffset = offset;
return gl::NoError(); return gl::NoError();
} }
......
...@@ -429,6 +429,19 @@ void CommandBuffer::copyBuffer(const VkBuffer &srcBuffer, ...@@ -429,6 +429,19 @@ void CommandBuffer::copyBuffer(const VkBuffer &srcBuffer,
vkCmdCopyBuffer(mHandle, srcBuffer, destBuffer, regionCount, regions); vkCmdCopyBuffer(mHandle, srcBuffer, destBuffer, regionCount, regions);
} }
void CommandBuffer::copyBufferToImage(VkBuffer srcBuffer,
const Image &dstImage,
VkImageLayout dstImageLayout,
uint32_t regionCount,
const VkBufferImageCopy *regions)
{
ASSERT(valid());
ASSERT(srcBuffer != VK_NULL_HANDLE);
ASSERT(dstImage.valid());
vkCmdCopyBufferToImage(mHandle, srcBuffer, dstImage.getHandle(), dstImageLayout, regionCount,
regions);
}
void CommandBuffer::clearColorImage(const vk::Image &image, void CommandBuffer::clearColorImage(const vk::Image &image,
VkImageLayout imageLayout, VkImageLayout imageLayout,
const VkClearColorValue &color, const VkClearColorValue &color,
...@@ -1251,8 +1264,21 @@ VkIndexType GetIndexType(GLenum elementType) ...@@ -1251,8 +1264,21 @@ VkIndexType GetIndexType(GLenum elementType)
return VK_INDEX_TYPE_MAX_ENUM; return VK_INDEX_TYPE_MAX_ENUM;
} }
} }
} // namespace gl_vk
void GetOffset(const gl::Offset &glOffset, VkOffset3D *vkOffset)
{
vkOffset->x = glOffset.x;
vkOffset->y = glOffset.y;
vkOffset->z = glOffset.z;
}
void GetExtent(const gl::Extents &glExtent, VkExtent3D *vkExtent)
{
vkExtent->width = glExtent.width;
vkExtent->height = glExtent.height;
vkExtent->depth = glExtent.depth;
}
} // namespace gl_vk
} // namespace rx } // namespace rx
std::ostream &operator<<(std::ostream &stream, const rx::vk::Error &error) std::ostream &operator<<(std::ostream &stream, const rx::vk::Error &error)
......
...@@ -356,6 +356,12 @@ class CommandBuffer : public WrappedObject<CommandBuffer, VkCommandBuffer> ...@@ -356,6 +356,12 @@ class CommandBuffer : public WrappedObject<CommandBuffer, VkCommandBuffer>
uint32_t regionCount, uint32_t regionCount,
const VkBufferCopy *regions); const VkBufferCopy *regions);
void copyBufferToImage(VkBuffer srcBuffer,
const Image &dstImage,
VkImageLayout dstImageLayout,
uint32_t regionCount,
const VkBufferImageCopy *regions);
void copyImage(const Image &srcImage, void copyImage(const Image &srcImage,
VkImageLayout srcImageLayout, VkImageLayout srcImageLayout,
const Image &dstImage, const Image &dstImage,
...@@ -651,6 +657,8 @@ VkFrontFace GetFrontFace(GLenum frontFace); ...@@ -651,6 +657,8 @@ VkFrontFace GetFrontFace(GLenum frontFace);
VkSampleCountFlagBits GetSamples(GLint sampleCount); VkSampleCountFlagBits GetSamples(GLint sampleCount);
VkComponentSwizzle GetSwizzle(const GLenum swizzle); VkComponentSwizzle GetSwizzle(const GLenum swizzle);
VkIndexType GetIndexType(GLenum elementType); VkIndexType GetIndexType(GLenum elementType);
void GetOffset(const gl::Offset &glOffset, VkOffset3D *vkOffset);
void GetExtent(const gl::Extents &glExtent, VkExtent3D *vkExtent);
} // namespace gl_vk } // namespace gl_vk
} // namespace rx } // namespace rx
......
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