Commit 08f8fa66 by Geoff Lang Committed by Commit Bot

Vulkan: Merge the PixelBuffer logic into ImageHelper.

To support EGL images efficiently, the pixel buffer needs to be tightly coupled with the image it will upload data to allowing textures to upload data to EGL images sourced from renderbuffers. The data will be uploaded to the image in the correct order if it comes from multiple sources and the check for pending uploads does not need to traverse EGL image siblings. BUG=angleproject:2668 Change-Id: Iebf59ed1e358ddc76843b8bcfac39b0363f66a3f Reviewed-on: https://chromium-review.googlesource.com/c/1405710 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent 9544002e
...@@ -34,7 +34,9 @@ void RenderbufferVk::onDestroy(const gl::Context *context) ...@@ -34,7 +34,9 @@ void RenderbufferVk::onDestroy(const gl::Context *context)
ContextVk *contextVk = vk::GetImpl(context); ContextVk *contextVk = vk::GetImpl(context);
RendererVk *renderer = contextVk->getRenderer(); RendererVk *renderer = contextVk->getRenderer();
mImage.release(renderer); mImage.releaseImage(renderer);
mImage.releaseStagingBuffer(renderer);
renderer->releaseObject(renderer->getCurrentQueueSerial(), &mImageView); renderer->releaseObject(renderer->getCurrentQueueSerial(), &mImageView);
} }
...@@ -54,7 +56,7 @@ angle::Result RenderbufferVk::setStorage(const gl::Context *context, ...@@ -54,7 +56,7 @@ angle::Result RenderbufferVk::setStorage(const gl::Context *context,
static_cast<GLsizei>(width) != mState.getWidth() || static_cast<GLsizei>(width) != mState.getWidth() ||
static_cast<GLsizei>(height) != mState.getHeight()) static_cast<GLsizei>(height) != mState.getHeight())
{ {
mImage.release(renderer); mImage.releaseImage(renderer);
renderer->releaseObject(renderer->getCurrentQueueSerial(), &mImageView); renderer->releaseObject(renderer->getCurrentQueueSerial(), &mImageView);
} }
} }
......
...@@ -111,7 +111,8 @@ void OffscreenSurfaceVk::AttachmentImage::destroy(const egl::Display *display) ...@@ -111,7 +111,8 @@ void OffscreenSurfaceVk::AttachmentImage::destroy(const egl::Display *display)
const DisplayVk *displayVk = vk::GetImpl(display); const DisplayVk *displayVk = vk::GetImpl(display);
RendererVk *renderer = displayVk->getRenderer(); RendererVk *renderer = displayVk->getRenderer();
image.release(renderer); image.releaseImage(renderer);
image.releaseStagingBuffer(renderer);
renderer->releaseObject(renderer->getCurrentQueueSerial(), &imageView); renderer->releaseObject(renderer->getCurrentQueueSerial(), &imageView);
} }
...@@ -294,7 +295,8 @@ void WindowSurfaceVk::destroy(const egl::Display *display) ...@@ -294,7 +295,8 @@ void WindowSurfaceVk::destroy(const egl::Display *display)
// We might not need to flush the pipe here. // We might not need to flush the pipe here.
(void)renderer->finish(displayVk); (void)renderer->finish(displayVk);
mDepthStencilImage.release(renderer); mDepthStencilImage.releaseImage(renderer);
mDepthStencilImage.releaseStagingBuffer(renderer);
mDepthStencilImageView.destroy(device); mDepthStencilImageView.destroy(device);
for (SwapchainImage &swapchainImage : mSwapchainImages) for (SwapchainImage &swapchainImage : mSwapchainImages)
......
...@@ -18,106 +18,6 @@ ...@@ -18,106 +18,6 @@
namespace rx namespace rx
{ {
class PixelBuffer final : angle::NonCopyable
{
public:
PixelBuffer(RendererVk *renderer);
~PixelBuffer();
void release(RendererVk *renderer);
void removeStagedUpdates(RendererVk *renderer, const gl::ImageIndex &index);
angle::Result stageSubresourceUpdate(ContextVk *contextVk,
const gl::ImageIndex &index,
const gl::Extents &extents,
const gl::Offset &offset,
const gl::InternalFormat &formatInfo,
const gl::PixelUnpackState &unpack,
GLenum type,
const uint8_t *pixels);
angle::Result stageSubresourceUpdateAndGetData(ContextVk *contextVk,
size_t allocationSize,
const gl::ImageIndex &imageIndex,
const gl::Extents &extents,
const gl::Offset &offset,
uint8_t **destData);
angle::Result stageSubresourceUpdateFromFramebuffer(const gl::Context *context,
const gl::ImageIndex &index,
const gl::Rectangle &sourceArea,
const gl::Offset &dstOffset,
const gl::Extents &dstExtent,
const gl::InternalFormat &formatInfo,
FramebufferVk *framebufferVk);
void stageSubresourceUpdateFromImage(vk::ImageHelper *image,
const gl::ImageIndex &index,
const gl::Offset &destOffset,
const gl::Extents &extents);
// This will use the underlying dynamic buffer to allocate some memory to be used as a src or
// dst.
angle::Result allocate(ContextVk *contextVk,
size_t sizeInBytes,
uint8_t **ptrOut,
VkBuffer *handleOut,
VkDeviceSize *offsetOut,
bool *newBufferAllocatedOut);
angle::Result flushUpdatesToImage(ContextVk *contextVk,
uint32_t levelCount,
vk::ImageHelper *image,
vk::CommandBuffer *commandBuffer);
bool empty() const;
private:
struct SubresourceUpdate
{
SubresourceUpdate();
SubresourceUpdate(VkBuffer bufferHandle, const VkBufferImageCopy &copyRegion);
SubresourceUpdate(vk::ImageHelper *image, const VkImageCopy &copyRegion);
SubresourceUpdate(const SubresourceUpdate &other);
void release(RendererVk *renderer);
const VkImageSubresourceLayers &dstSubresource() const
{
return updateSource == UpdateSource::Buffer ? buffer.copyRegion.imageSubresource
: image.copyRegion.dstSubresource;
}
bool isUpdateToLayerLevel(uint32_t layerIndex, uint32_t levelIndex) const;
enum class UpdateSource
{
Buffer,
Image,
};
struct BufferUpdate
{
VkBuffer bufferHandle;
VkBufferImageCopy copyRegion;
};
struct ImageUpdate
{
vk::ImageHelper *image;
VkImageCopy copyRegion;
};
UpdateSource updateSource;
union
{
BufferUpdate buffer;
ImageUpdate image;
};
};
vk::DynamicBuffer mStagingBuffer;
std::vector<SubresourceUpdate> mSubresourceUpdates;
};
class TextureVk : public TextureImpl class TextureVk : public TextureImpl
{ {
public: public:
...@@ -308,7 +208,8 @@ class TextureVk : public TextureImpl ...@@ -308,7 +208,8 @@ class TextureVk : public TextureImpl
const gl::Extents &extents, const gl::Extents &extents,
const uint32_t levelCount, const uint32_t levelCount,
vk::CommandBuffer *commandBuffer); vk::CommandBuffer *commandBuffer);
void releaseImage(const gl::Context *context, RendererVk *renderer); void releaseImage(RendererVk *renderer);
void releaseStagingBuffer(RendererVk *renderer);
uint32_t getLevelCount() const; uint32_t getLevelCount() const;
angle::Result initCubeMapRenderTargets(ContextVk *contextVk); angle::Result initCubeMapRenderTargets(ContextVk *contextVk);
...@@ -326,8 +227,6 @@ class TextureVk : public TextureImpl ...@@ -326,8 +227,6 @@ class TextureVk : public TextureImpl
RenderTargetVk mRenderTarget; RenderTargetVk mRenderTarget;
std::vector<RenderTargetVk> mCubeMapRenderTargets; std::vector<RenderTargetVk> mCubeMapRenderTargets;
PixelBuffer mPixelBuffer;
}; };
} // namespace rx } // namespace rx
......
...@@ -33,6 +33,7 @@ class DynamicBuffer : angle::NonCopyable ...@@ -33,6 +33,7 @@ class DynamicBuffer : angle::NonCopyable
{ {
public: public:
DynamicBuffer(VkBufferUsageFlags usage, size_t minSize, bool hostVisible); DynamicBuffer(VkBufferUsageFlags usage, size_t minSize, bool hostVisible);
DynamicBuffer(DynamicBuffer &&other);
~DynamicBuffer(); ~DynamicBuffer();
// Init is called after the buffer creation so that the alignment can be specified later. // Init is called after the buffer creation so that the alignment can be specified later.
...@@ -477,6 +478,8 @@ class ImageHelper final : public CommandGraphResource ...@@ -477,6 +478,8 @@ class ImageHelper final : public CommandGraphResource
ImageHelper(ImageHelper &&other); ImageHelper(ImageHelper &&other);
~ImageHelper() override; ~ImageHelper() override;
void initStagingBuffer(RendererVk *renderer);
angle::Result init(Context *context, angle::Result init(Context *context,
gl::TextureType textureType, gl::TextureType textureType,
const gl::Extents &extents, const gl::Extents &extents,
...@@ -514,7 +517,8 @@ class ImageHelper final : public CommandGraphResource ...@@ -514,7 +517,8 @@ class ImageHelper final : public CommandGraphResource
VkImageUsageFlags usage, VkImageUsageFlags usage,
uint32_t layerCount); uint32_t layerCount);
void release(RendererVk *renderer); void releaseImage(RendererVk *renderer);
void releaseStagingBuffer(RendererVk *renderer);
bool valid() const { return mImage.valid(); } bool valid() const { return mImage.valid(); }
...@@ -573,7 +577,94 @@ class ImageHelper final : public CommandGraphResource ...@@ -573,7 +577,94 @@ class ImageHelper final : public CommandGraphResource
angle::Result generateMipmapsWithBlit(ContextVk *contextVk, GLuint maxLevel); angle::Result generateMipmapsWithBlit(ContextVk *contextVk, GLuint maxLevel);
// Data staging
void removeStagedUpdates(RendererVk *renderer, const gl::ImageIndex &index);
angle::Result stageSubresourceUpdate(ContextVk *contextVk,
const gl::ImageIndex &index,
const gl::Extents &extents,
const gl::Offset &offset,
const gl::InternalFormat &formatInfo,
const gl::PixelUnpackState &unpack,
GLenum type,
const uint8_t *pixels);
angle::Result stageSubresourceUpdateAndGetData(ContextVk *contextVk,
size_t allocationSize,
const gl::ImageIndex &imageIndex,
const gl::Extents &extents,
const gl::Offset &offset,
uint8_t **destData);
angle::Result stageSubresourceUpdateFromFramebuffer(const gl::Context *context,
const gl::ImageIndex &index,
const gl::Rectangle &sourceArea,
const gl::Offset &dstOffset,
const gl::Extents &dstExtent,
const gl::InternalFormat &formatInfo,
FramebufferVk *framebufferVk);
void stageSubresourceUpdateFromImage(vk::ImageHelper *image,
const gl::ImageIndex &index,
const gl::Offset &destOffset,
const gl::Extents &extents);
// This will use the underlying dynamic buffer to allocate some memory to be used as a src or
// dst.
angle::Result allocateStagingMemory(ContextVk *contextVk,
size_t sizeInBytes,
uint8_t **ptrOut,
VkBuffer *handleOut,
VkDeviceSize *offsetOut,
bool *newBufferAllocatedOut);
angle::Result flushStagedUpdates(ContextVk *contextVk,
uint32_t levelCount,
vk::CommandBuffer *commandBuffer);
bool hasStagedUpdates() const;
private: private:
struct SubresourceUpdate
{
SubresourceUpdate();
SubresourceUpdate(VkBuffer bufferHandle, const VkBufferImageCopy &copyRegion);
SubresourceUpdate(vk::ImageHelper *image, const VkImageCopy &copyRegion);
SubresourceUpdate(const SubresourceUpdate &other);
void release(RendererVk *renderer);
const VkImageSubresourceLayers &dstSubresource() const
{
return updateSource == UpdateSource::Buffer ? buffer.copyRegion.imageSubresource
: image.copyRegion.dstSubresource;
}
bool isUpdateToLayerLevel(uint32_t layerIndex, uint32_t levelIndex) const;
enum class UpdateSource
{
Buffer,
Image,
};
struct BufferUpdate
{
VkBuffer bufferHandle;
VkBufferImageCopy copyRegion;
};
struct ImageUpdate
{
vk::ImageHelper *image;
VkImageCopy copyRegion;
};
UpdateSource updateSource;
union
{
BufferUpdate buffer;
ImageUpdate image;
};
};
// Vulkan objects. // Vulkan objects.
Image mImage; Image mImage;
DeviceMemory mDeviceMemory; DeviceMemory mDeviceMemory;
...@@ -589,6 +680,10 @@ class ImageHelper final : public CommandGraphResource ...@@ -589,6 +680,10 @@ class ImageHelper final : public CommandGraphResource
// Cached properties. // Cached properties.
uint32_t mLayerCount; uint32_t mLayerCount;
uint32_t mLevelCount; uint32_t mLevelCount;
// Staging buffer
vk::DynamicBuffer mStagingBuffer;
std::vector<SubresourceUpdate> mSubresourceUpdates;
}; };
class FramebufferHelper : public CommandGraphResource class FramebufferHelper : public CommandGraphResource
......
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