diff --git a/src/libANGLE/renderer/vulkan/BufferVk.cpp b/src/libANGLE/renderer/vulkan/BufferVk.cpp index 57aa91766..5a4b5e5e5 100644 --- a/src/libANGLE/renderer/vulkan/BufferVk.cpp +++ b/src/libANGLE/renderer/vulkan/BufferVk.cpp @@ -18,8 +18,7 @@ namespace rx { -BufferVk::BufferVk(const gl::BufferState &state) - : BufferImpl(state), mAllocatedMemoryPropertyFlags(0) +BufferVk::BufferVk(const gl::BufferState &state) : BufferImpl(state) { } @@ -37,8 +36,7 @@ void BufferVk::destroy(const gl::Context *context) void BufferVk::release(RendererVk *renderer) { - renderer->releaseObject(getStoredQueueSerial(), &mBuffer); - renderer->releaseObject(getStoredQueueSerial(), &mBufferMemory); + mBuffer.release(renderer); } gl::Error BufferVk::setData(const gl::Context *context, @@ -54,12 +52,12 @@ gl::Error BufferVk::setData(const gl::Context *context, // Release and re-create the memory and buffer. release(contextVk->getRenderer()); + // We could potentially use multiple backing buffers for different usages. + // For now keep a single buffer with all relevant usage flags. const VkImageUsageFlags usageFlags = (VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT); - // TODO(jmadill): Proper usage bit implementation. Likely will involve multiple backing - // buffers like in D3D11. VkBufferCreateInfo createInfo; createInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; createInfo.pNext = nullptr; @@ -70,14 +68,11 @@ gl::Error BufferVk::setData(const gl::Context *context, createInfo.queueFamilyIndexCount = 0; createInfo.pQueueFamilyIndices = nullptr; - ANGLE_TRY(mBuffer.init(contextVk, createInfo)); - // Assume host vislble/coherent memory available. const VkMemoryPropertyFlags memoryPropertyFlags = (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); - ANGLE_TRY(vk::AllocateBufferMemory(contextVk, memoryPropertyFlags, - &mAllocatedMemoryPropertyFlags, &mBuffer, - &mBufferMemory)); + + ANGLE_TRY(mBuffer.init(contextVk, createInfo, memoryPropertyFlags)); } if (data && size > 0) @@ -94,8 +89,7 @@ gl::Error BufferVk::setSubData(const gl::Context *context, size_t size, size_t offset) { - ASSERT(mBuffer.getHandle() != VK_NULL_HANDLE); - ASSERT(mBufferMemory.getHandle() != VK_NULL_HANDLE); + ASSERT(mBuffer.valid()); ContextVk *contextVk = vk::GetImpl(context); ANGLE_TRY(setDataImpl(contextVk, static_cast(data), size, offset)); @@ -115,8 +109,7 @@ gl::Error BufferVk::copySubData(const gl::Context *context, gl::Error BufferVk::map(const gl::Context *context, GLenum access, void **mapPtr) { - ASSERT(mBuffer.getHandle() != VK_NULL_HANDLE); - ASSERT(mBufferMemory.getHandle() != VK_NULL_HANDLE); + ASSERT(mBuffer.valid()); ContextVk *contextVk = vk::GetImpl(context); ANGLE_TRY(mapImpl(contextVk, mapPtr)); @@ -125,8 +118,8 @@ gl::Error BufferVk::map(const gl::Context *context, GLenum access, void **mapPtr angle::Result BufferVk::mapImpl(ContextVk *contextVk, void **mapPtr) { - return mBufferMemory.map(contextVk, 0, mState.getSize(), 0, - reinterpret_cast(mapPtr)); + return mBuffer.getDeviceMemory().map(contextVk, 0, mState.getSize(), 0, + reinterpret_cast(mapPtr)); } GLint64 BufferVk::getSize() @@ -140,13 +133,12 @@ gl::Error BufferVk::mapRange(const gl::Context *context, GLbitfield access, void **mapPtr) { - ASSERT(mBuffer.getHandle() != VK_NULL_HANDLE); - ASSERT(mBufferMemory.getHandle() != VK_NULL_HANDLE); + ASSERT(mBuffer.valid()); ContextVk *contextVk = vk::GetImpl(context); - ANGLE_TRY( - mBufferMemory.map(contextVk, offset, length, 0, reinterpret_cast(mapPtr))); + ANGLE_TRY(mBuffer.getDeviceMemory().map(contextVk, offset, length, 0, + reinterpret_cast(mapPtr))); return gl::NoError(); } @@ -158,10 +150,9 @@ gl::Error BufferVk::unmap(const gl::Context *context, GLboolean *result) angle::Result BufferVk::unmapImpl(ContextVk *contextVk) { - ASSERT(mBuffer.getHandle() != VK_NULL_HANDLE); - ASSERT(mBufferMemory.getHandle() != VK_NULL_HANDLE); + ASSERT(mBuffer.valid()); - mBufferMemory.unmap(contextVk->getDevice()); + mBuffer.getDeviceMemory().unmap(contextVk->getDevice()); return angle::Result::Continue(); } @@ -184,11 +175,12 @@ gl::Error BufferVk::getIndexRange(const gl::Context *context, const gl::Type &typeInfo = gl::GetTypeInfo(type); uint8_t *mapPointer = nullptr; - ANGLE_TRY(mBufferMemory.map(contextVk, offset, typeInfo.bytes * count, 0, &mapPointer)); + ANGLE_TRY( + mBuffer.getDeviceMemory().map(contextVk, offset, typeInfo.bytes * count, 0, &mapPointer)); *outRange = gl::ComputeIndexRange(type, mapPointer, count, primitiveRestartEnabled); - mBufferMemory.unmap(contextVk->getDevice()); + mBuffer.getDeviceMemory().unmap(contextVk->getDevice()); return gl::NoError(); } @@ -201,7 +193,7 @@ angle::Result BufferVk::setDataImpl(ContextVk *contextVk, VkDevice device = contextVk->getDevice(); // Use map when available. - if (isResourceInUse(renderer)) + if (mBuffer.isResourceInUse(renderer)) { vk::StagingBuffer stagingBuffer; ANGLE_TRY(stagingBuffer.init(contextVk, static_cast(size), @@ -218,7 +210,7 @@ angle::Result BufferVk::setDataImpl(ContextVk *contextVk, // 'beginWriteResource' will stop any subsequent rendering from using the old buffer data, // by marking any current read operations / command buffers as 'finished'. vk::CommandBuffer *commandBuffer = nullptr; - ANGLE_TRY(recordCommands(contextVk, &commandBuffer)); + ANGLE_TRY(mBuffer.recordCommands(contextVk, &commandBuffer)); // Insert a barrier to ensure reads from the buffer are complete. // TODO(jmadill): Insert minimal barriers. @@ -229,7 +221,7 @@ angle::Result BufferVk::setDataImpl(ContextVk *contextVk, bufferBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; bufferBarrier.srcQueueFamilyIndex = 0; bufferBarrier.dstQueueFamilyIndex = 0; - bufferBarrier.buffer = mBuffer.getHandle(); + bufferBarrier.buffer = mBuffer.getBuffer().getHandle(); bufferBarrier.offset = offset; bufferBarrier.size = static_cast(size); @@ -237,7 +229,7 @@ angle::Result BufferVk::setDataImpl(ContextVk *contextVk, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, bufferBarrier); VkBufferCopy copyRegion = {0, offset, size}; - commandBuffer->copyBuffer(stagingBuffer.getBuffer(), mBuffer, 1, ©Region); + commandBuffer->copyBuffer(stagingBuffer.getBuffer(), mBuffer.getBuffer(), 1, ©Region); // Insert a barrier to ensure copy has done. // TODO(jie.a.chen@intel.com): Insert minimal barriers. @@ -253,44 +245,38 @@ angle::Result BufferVk::setDataImpl(ContextVk *contextVk, bufferBarrier.srcQueueFamilyIndex = 0; bufferBarrier.dstQueueFamilyIndex = 0; - bufferBarrier.buffer = mBuffer.getHandle(); + bufferBarrier.buffer = mBuffer.getBuffer().getHandle(); bufferBarrier.offset = offset; bufferBarrier.size = static_cast(size); commandBuffer->singleBufferBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, bufferBarrier); - // Immediately release staging buffer. - // TODO(jmadill): Staging buffer re-use. - renderer->releaseObject(getStoredQueueSerial(), &stagingBuffer); + // Immediately release staging buffer. We should probably be using a DynamicBuffer here. + renderer->releaseObject(renderer->getCurrentQueueSerial(), &stagingBuffer); } else { uint8_t *mapPointer = nullptr; - ANGLE_TRY(mBufferMemory.map(contextVk, offset, size, 0, &mapPointer)); + ANGLE_TRY(mBuffer.getDeviceMemory().map(contextVk, offset, size, 0, &mapPointer)); ASSERT(mapPointer); memcpy(mapPointer, data, size); - mBufferMemory.unmap(device); + mBuffer.getDeviceMemory().unmap(device); } return angle::Result::Continue(); } -const vk::Buffer &BufferVk::getVkBuffer() const -{ - return mBuffer; -} - angle::Result BufferVk::copyToBuffer(ContextVk *contextVk, VkBuffer destbuffer, uint32_t copyCount, const VkBufferCopy *copies) { vk::CommandBuffer *commandBuffer; - ANGLE_TRY(recordCommands(contextVk, &commandBuffer)); - commandBuffer->copyBuffer(mBuffer.getHandle(), destbuffer, copyCount, copies); + ANGLE_TRY(mBuffer.recordCommands(contextVk, &commandBuffer)); + commandBuffer->copyBuffer(mBuffer.getBuffer().getHandle(), destbuffer, copyCount, copies); return angle::Result::Continue(); } diff --git a/src/libANGLE/renderer/vulkan/BufferVk.h b/src/libANGLE/renderer/vulkan/BufferVk.h index 2d6115088..b6c02880f 100644 --- a/src/libANGLE/renderer/vulkan/BufferVk.h +++ b/src/libANGLE/renderer/vulkan/BufferVk.h @@ -18,7 +18,7 @@ namespace rx { class RendererVk; -class BufferVk : public BufferImpl, public vk::CommandGraphResource +class BufferVk : public BufferImpl { public: BufferVk(const gl::BufferState &state); @@ -56,7 +56,17 @@ class BufferVk : public BufferImpl, public vk::CommandGraphResource gl::IndexRange *outRange) override; GLint64 getSize(); - const vk::Buffer &getVkBuffer() const; + const vk::BufferHelper &getBuffer() const + { + ASSERT(mBuffer.valid()); + return mBuffer; + } + + vk::BufferHelper &getBuffer() + { + ASSERT(mBuffer.valid()); + return mBuffer; + } angle::Result mapImpl(ContextVk *contextVk, void **mapPtr); angle::Result unmapImpl(ContextVk *contextVk); @@ -74,9 +84,7 @@ class BufferVk : public BufferImpl, public vk::CommandGraphResource size_t offset); void release(RendererVk *renderer); - vk::Buffer mBuffer; - vk::DeviceMemory mBufferMemory; - VkMemoryPropertyFlags mAllocatedMemoryPropertyFlags; + vk::BufferHelper mBuffer; }; } // namespace rx diff --git a/src/libANGLE/renderer/vulkan/CommandGraph.h b/src/libANGLE/renderer/vulkan/CommandGraph.h index 2ac17ef18..447ddd15f 100644 --- a/src/libANGLE/renderer/vulkan/CommandGraph.h +++ b/src/libANGLE/renderer/vulkan/CommandGraph.h @@ -122,7 +122,6 @@ class CommandGraphResource // Sets up dependency relations. 'this' resource is the resource being read. void addReadDependency(CommandGraphResource *readingResource); - protected: // Allocates a write node via getNewWriteNode and returns a started command buffer. // The started command buffer will render outside of a RenderPass. // Will append to an existing command buffer/graph node if possible. @@ -147,6 +146,7 @@ class CommandGraphResource // Called when 'this' object changes, but we'd like to start a new command buffer later. void finishCurrentCommands(RendererVk *renderer); + protected: // Get the current queue serial for this resource. Only used to release resources. Serial getStoredQueueSerial() const; diff --git a/src/libANGLE/renderer/vulkan/ContextVk.cpp b/src/libANGLE/renderer/vulkan/ContextVk.cpp index 6299e8542..23b68cef6 100644 --- a/src/libANGLE/renderer/vulkan/ContextVk.cpp +++ b/src/libANGLE/renderer/vulkan/ContextVk.cpp @@ -397,7 +397,7 @@ angle::Result ContextVk::handleDirtyTextures(const gl::Context *context, // Ensure any writes to the textures are flushed before we read from them. TextureVk *textureVk = mActiveTextures[textureIndex]; ANGLE_TRY(textureVk->ensureImageInitialized(this)); - textureVk->addReadDependency(mDrawFramebuffer); + textureVk->getImage().addReadDependency(mDrawFramebuffer); } if (mProgram->hasTextures()) diff --git a/src/libANGLE/renderer/vulkan/RenderTargetVk.cpp b/src/libANGLE/renderer/vulkan/RenderTargetVk.cpp index 18dd86d5b..af826c4ed 100644 --- a/src/libANGLE/renderer/vulkan/RenderTargetVk.cpp +++ b/src/libANGLE/renderer/vulkan/RenderTargetVk.cpp @@ -15,11 +15,8 @@ namespace rx { -RenderTargetVk::RenderTargetVk(vk::ImageHelper *image, - vk::ImageView *imageView, - vk::CommandGraphResource *resource, - size_t layerIndex) - : mImage(image), mImageView(imageView), mResource(resource), mLayerIndex(layerIndex) +RenderTargetVk::RenderTargetVk(vk::ImageHelper *image, vk::ImageView *imageView, size_t layerIndex) + : mImage(image), mImageView(imageView), mLayerIndex(layerIndex) { } @@ -30,7 +27,6 @@ RenderTargetVk::~RenderTargetVk() RenderTargetVk::RenderTargetVk(RenderTargetVk &&other) : mImage(other.mImage), mImageView(other.mImageView), - mResource(other.mResource), mLayerIndex(other.mLayerIndex) { } @@ -52,7 +48,7 @@ void RenderTargetVk::onColorDraw(vk::CommandGraphResource *framebufferVk, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, commandBuffer); // Set up dependencies between the RT resource and the Framebuffer. - mResource->addWriteDependency(framebufferVk); + mImage->addWriteDependency(framebufferVk); } void RenderTargetVk::onDepthStencilDraw(vk::CommandGraphResource *framebufferVk, @@ -74,7 +70,7 @@ void RenderTargetVk::onDepthStencilDraw(vk::CommandGraphResource *framebufferVk, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, commandBuffer); // Set up dependencies between the RT resource and the Framebuffer. - mResource->addWriteDependency(framebufferVk); + mImage->addWriteDependency(framebufferVk); } const vk::ImageHelper &RenderTargetVk::getImage() const @@ -89,11 +85,6 @@ vk::ImageView *RenderTargetVk::getImageView() const return mImageView; } -vk::CommandGraphResource *RenderTargetVk::getResource() const -{ - return mResource; -} - const vk::Format &RenderTargetVk::getImageFormat() const { ASSERT(mImage && mImage->valid()); @@ -120,7 +111,7 @@ vk::ImageHelper *RenderTargetVk::getImageForRead(vk::CommandGraphResource *readi ASSERT(mImage && mImage->valid()); // TODO(jmadill): Better simultaneous resource access. http://anglebug.com/2679 - mResource->addWriteDependency(readingResource); + mImage->addWriteDependency(readingResource); mImage->changeLayoutWithStages(mImage->getAspectFlags(), layout, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, @@ -132,7 +123,7 @@ vk::ImageHelper *RenderTargetVk::getImageForRead(vk::CommandGraphResource *readi vk::ImageHelper *RenderTargetVk::getImageForWrite(vk::CommandGraphResource *writingResource) const { ASSERT(mImage && mImage->valid()); - mResource->addWriteDependency(writingResource); + mImage->addWriteDependency(writingResource); return mImage; } diff --git a/src/libANGLE/renderer/vulkan/RenderTargetVk.h b/src/libANGLE/renderer/vulkan/RenderTargetVk.h index 4eacad53b..6106f5f99 100644 --- a/src/libANGLE/renderer/vulkan/RenderTargetVk.h +++ b/src/libANGLE/renderer/vulkan/RenderTargetVk.h @@ -35,7 +35,6 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget public: RenderTargetVk(vk::ImageHelper *image, vk::ImageView *imageView, - vk::CommandGraphResource *resource, size_t layerIndex); ~RenderTargetVk(); @@ -58,7 +57,6 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget vk::CommandBuffer *commandBuffer); vk::ImageHelper *getImageForWrite(vk::CommandGraphResource *writingResource) const; vk::ImageView *getImageView() const; - vk::CommandGraphResource *getResource() const; const vk::Format &getImageFormat() const; const gl::Extents &getImageExtents() const; @@ -71,7 +69,6 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget private: vk::ImageHelper *mImage; vk::ImageView *mImageView; - vk::CommandGraphResource *mResource; size_t mLayerIndex; }; diff --git a/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp b/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp index 74bd4b837..40b529e82 100644 --- a/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp +++ b/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp @@ -24,7 +24,7 @@ constexpr VkClearColorValue kBlackClearColorValue = {{0}}; } // anonymous namespace RenderbufferVk::RenderbufferVk(const gl::RenderbufferState &state) - : RenderbufferImpl(state), mRenderTarget(&mImage, &mImageView, this, 0) + : RenderbufferImpl(state), mRenderTarget(&mImage, &mImageView, 0) { } @@ -37,8 +37,8 @@ gl::Error RenderbufferVk::onDestroy(const gl::Context *context) ContextVk *contextVk = vk::GetImpl(context); RendererVk *renderer = contextVk->getRenderer(); - mImage.release(renderer->getCurrentQueueSerial(), renderer); - renderer->releaseObject(getStoredQueueSerial(), &mImageView); + mImage.release(renderer); + renderer->releaseObject(renderer->getCurrentQueueSerial(), &mImageView); return gl::NoError(); } @@ -59,8 +59,8 @@ gl::Error RenderbufferVk::setStorage(const gl::Context *context, static_cast(width) != mState.getWidth() || static_cast(height) != mState.getHeight()) { - mImage.release(renderer->getCurrentQueueSerial(), renderer); - renderer->releaseObject(getStoredQueueSerial(), &mImageView); + mImage.release(renderer); + renderer->releaseObject(renderer->getCurrentQueueSerial(), &mImageView); } } @@ -87,7 +87,7 @@ gl::Error RenderbufferVk::setStorage(const gl::Context *context, // TODO(jmadill): Fold this into the RenderPass load/store ops. http://anglebug.com/2361 vk::CommandBuffer *commandBuffer = nullptr; - ANGLE_TRY(recordCommands(contextVk, &commandBuffer)); + ANGLE_TRY(mImage.recordCommands(contextVk, &commandBuffer)); if (isDepthOrStencilFormat) { diff --git a/src/libANGLE/renderer/vulkan/RenderbufferVk.h b/src/libANGLE/renderer/vulkan/RenderbufferVk.h index a6453c952..22bda025a 100644 --- a/src/libANGLE/renderer/vulkan/RenderbufferVk.h +++ b/src/libANGLE/renderer/vulkan/RenderbufferVk.h @@ -17,7 +17,7 @@ namespace rx { -class RenderbufferVk : public RenderbufferImpl, public vk::CommandGraphResource +class RenderbufferVk : public RenderbufferImpl { public: RenderbufferVk(const gl::RenderbufferState &state); diff --git a/src/libANGLE/renderer/vulkan/SurfaceVk.cpp b/src/libANGLE/renderer/vulkan/SurfaceVk.cpp index bd7a94bda..5f5220243 100644 --- a/src/libANGLE/renderer/vulkan/SurfaceVk.cpp +++ b/src/libANGLE/renderer/vulkan/SurfaceVk.cpp @@ -58,8 +58,7 @@ constexpr VkImageUsageFlags kSurfaceVKDepthStencilImageUsageFlags = } // namespace -OffscreenSurfaceVk::AttachmentImage::AttachmentImage(vk::CommandGraphResource *commandGraphResource) - : renderTarget(&image, &imageView, commandGraphResource, 0) +OffscreenSurfaceVk::AttachmentImage::AttachmentImage() : renderTarget(&image, &imageView, 0) { } @@ -91,24 +90,19 @@ angle::Result OffscreenSurfaceVk::AttachmentImage::initialize(DisplayVk *display return angle::Result::Continue(); } -void OffscreenSurfaceVk::AttachmentImage::destroy(const egl::Display *display, - Serial storedQueueSerial) +void OffscreenSurfaceVk::AttachmentImage::destroy(const egl::Display *display) { const DisplayVk *displayVk = vk::GetImpl(display); RendererVk *renderer = displayVk->getRenderer(); - image.release(renderer->getCurrentQueueSerial(), renderer); - renderer->releaseObject(storedQueueSerial, &imageView); + image.release(renderer); + renderer->releaseObject(renderer->getCurrentQueueSerial(), &imageView); } OffscreenSurfaceVk::OffscreenSurfaceVk(const egl::SurfaceState &surfaceState, EGLint width, EGLint height) - : SurfaceImpl(surfaceState), - mWidth(width), - mHeight(height), - mColorAttachment(this), - mDepthStencilAttachment(this) + : SurfaceImpl(surfaceState), mWidth(width), mHeight(height) { } @@ -145,8 +139,8 @@ angle::Result OffscreenSurfaceVk::initializeImpl(DisplayVk *displayVk) void OffscreenSurfaceVk::destroy(const egl::Display *display) { - mColorAttachment.destroy(display, getStoredQueueSerial()); - mDepthStencilAttachment.destroy(display, getStoredQueueSerial()); + mColorAttachment.destroy(display); + mDepthStencilAttachment.destroy(display); } FramebufferImpl *OffscreenSurfaceVk::createDefaultFramebuffer(const gl::Context *context, @@ -268,8 +262,8 @@ WindowSurfaceVk::WindowSurfaceVk(const egl::SurfaceState &surfaceState, mSurface(VK_NULL_HANDLE), mInstance(VK_NULL_HANDLE), mSwapchain(VK_NULL_HANDLE), - mColorRenderTarget(nullptr, nullptr, this, 0), - mDepthStencilRenderTarget(&mDepthStencilImage, &mDepthStencilImageView, this, 0), + mColorRenderTarget(nullptr, nullptr, 0), + mDepthStencilRenderTarget(&mDepthStencilImage, &mDepthStencilImageView, 0), mCurrentSwapchainImageIndex(0) { } @@ -292,7 +286,7 @@ void WindowSurfaceVk::destroy(const egl::Display *display) mAcquireNextImageSemaphore.destroy(device); - mDepthStencilImage.release(renderer->getCurrentQueueSerial(), renderer); + mDepthStencilImage.release(renderer); mDepthStencilImageView.destroy(device); for (SwapchainImage &swapchainImage : mSwapchainImages) @@ -478,10 +472,6 @@ angle::Result WindowSurfaceVk::initializeImpl(DisplayVk *displayVk) ANGLE_VK_TRY(displayVk, vkGetSwapchainImagesKHR(device, mSwapchain, &imageCount, swapchainImages.data())); - // Allocate a command buffer for clearing our images to black. - vk::CommandBuffer *commandBuffer = nullptr; - ANGLE_TRY(recordCommands(displayVk, &commandBuffer)); - VkClearColorValue transparentBlack; transparentBlack.float32[0] = 0.0f; transparentBlack.float32[1] = 0.0f; @@ -500,6 +490,10 @@ angle::Result WindowSurfaceVk::initializeImpl(DisplayVk *displayVk) VK_IMAGE_ASPECT_COLOR_BIT, gl::SwizzleState(), &member.imageView, 1)); + // Allocate a command buffer for clearing our images to black. + vk::CommandBuffer *commandBuffer = nullptr; + ANGLE_TRY(member.image.recordCommands(displayVk, &commandBuffer)); + // Set transfer dest layout, and clear the image to black. member.image.clearColor(transparentBlack, 0, 1, commandBuffer); @@ -525,13 +519,15 @@ angle::Result WindowSurfaceVk::initializeImpl(DisplayVk *displayVk) const VkImageAspectFlags aspect = vk::GetDepthStencilAspectFlags(dsFormat.textureFormat()); VkClearDepthStencilValue depthStencilClearValue = {1.0f, 0}; - // Set transfer dest layout, and clear the image. + // Clear the image. + vk::CommandBuffer *commandBuffer = nullptr; + ANGLE_TRY(mDepthStencilImage.recordCommands(displayVk, &commandBuffer)); mDepthStencilImage.clearDepthStencil(aspect, depthStencilClearValue, commandBuffer); ANGLE_TRY(mDepthStencilImage.initImageView(displayVk, gl::TextureType::_2D, aspect, gl::SwizzleState(), &mDepthStencilImageView, 1)); - // TODO(jmadill): Figure out how to pass depth/stencil image views to the RenderTargetVk. + // We will need to pass depth/stencil image views to the RenderTargetVk in the future. } return angle::Result::Continue(); @@ -565,7 +561,8 @@ angle::Result WindowSurfaceVk::swapImpl(DisplayVk *displayVk) RendererVk *renderer = displayVk->getRenderer(); vk::CommandBuffer *swapCommands = nullptr; - ANGLE_TRY(recordCommands(displayVk, &swapCommands)); + ANGLE_TRY(mSwapchainImages[mCurrentSwapchainImageIndex].image.recordCommands(displayVk, + &swapCommands)); SwapchainImage &image = mSwapchainImages[mCurrentSwapchainImageIndex]; diff --git a/src/libANGLE/renderer/vulkan/SurfaceVk.h b/src/libANGLE/renderer/vulkan/SurfaceVk.h index abdf07eaa..73a3cfc0b 100644 --- a/src/libANGLE/renderer/vulkan/SurfaceVk.h +++ b/src/libANGLE/renderer/vulkan/SurfaceVk.h @@ -20,7 +20,7 @@ namespace rx { class RendererVk; -class OffscreenSurfaceVk : public SurfaceImpl, public vk::CommandGraphResource +class OffscreenSurfaceVk : public SurfaceImpl { public: OffscreenSurfaceVk(const egl::SurfaceState &surfaceState, EGLint width, EGLint height); @@ -63,14 +63,14 @@ class OffscreenSurfaceVk : public SurfaceImpl, public vk::CommandGraphResource private: struct AttachmentImage final : angle::NonCopyable { - AttachmentImage(vk::CommandGraphResource *commandGraphResource); + AttachmentImage(); ~AttachmentImage(); angle::Result initialize(DisplayVk *displayVk, EGLint width, EGLint height, const vk::Format &vkFormat); - void destroy(const egl::Display *display, Serial storedQueueSerial); + void destroy(const egl::Display *display); vk::ImageHelper image; vk::ImageView imageView; @@ -86,7 +86,7 @@ class OffscreenSurfaceVk : public SurfaceImpl, public vk::CommandGraphResource AttachmentImage mDepthStencilAttachment; }; -class WindowSurfaceVk : public SurfaceImpl, public vk::CommandGraphResource +class WindowSurfaceVk : public SurfaceImpl { public: WindowSurfaceVk(const egl::SurfaceState &surfaceState, diff --git a/src/libANGLE/renderer/vulkan/TextureVk.cpp b/src/libANGLE/renderer/vulkan/TextureVk.cpp index 696028b91..a4446b37c 100644 --- a/src/libANGLE/renderer/vulkan/TextureVk.cpp +++ b/src/libANGLE/renderer/vulkan/TextureVk.cpp @@ -429,15 +429,11 @@ PixelBuffer::SubresourceUpdate::SubresourceUpdate(const SubresourceUpdate &other // TextureVk implementation. TextureVk::TextureVk(const gl::TextureState &state, RendererVk *renderer) - : TextureImpl(state), - mRenderTarget(&mImage, &mBaseLevelImageView, this, 0), - mPixelBuffer(renderer) + : TextureImpl(state), mRenderTarget(&mImage, &mBaseLevelImageView, 0), mPixelBuffer(renderer) { } -TextureVk::~TextureVk() -{ -} +TextureVk::~TextureVk() = default; gl::Error TextureVk::onDestroy(const gl::Context *context) { @@ -445,7 +441,7 @@ gl::Error TextureVk::onDestroy(const gl::Context *context) RendererVk *renderer = contextVk->getRenderer(); releaseImage(context, renderer); - renderer->releaseObject(getStoredQueueSerial(), &mSampler); + renderer->releaseObject(renderer->getCurrentQueueSerial(), &mSampler); mPixelBuffer.release(renderer); return gl::NoError(); @@ -475,7 +471,7 @@ gl::Error TextureVk::setImage(const gl::Context *context, } // Create a new graph node to store image initialization commands. - finishCurrentCommands(renderer); + mImage.finishCurrentCommands(renderer); // Handle initial data. if (pixels) @@ -503,7 +499,7 @@ gl::Error TextureVk::setSubImage(const gl::Context *context, gl::Offset(area.x, area.y, area.z), formatInfo, unpack, type, pixels)); // Create a new graph node to store image initialization commands. - finishCurrentCommands(contextVk->getRenderer()); + mImage.finishCurrentCommands(contextVk->getRenderer()); return gl::NoError(); } @@ -629,8 +625,8 @@ angle::Result TextureVk::copySubImageImpl(const gl::Context *context, gl::Extents(clippedSourceArea.width, clippedSourceArea.height, 1), internalFormat, framebufferVk)); - finishCurrentCommands(renderer); - framebufferVk->addReadDependency(this); + mImage.finishCurrentCommands(renderer); + framebufferVk->addReadDependency(&mImage); return angle::Result::Continue(); } @@ -679,7 +675,7 @@ gl::Error TextureVk::copySubTextureImpl(ContextVk *contextVk, unpackUnmultiplyAlpha); // Create a new graph node to store image initialization commands. - finishCurrentCommands(contextVk->getRenderer()); + mImage.finishCurrentCommands(contextVk->getRenderer()); return angle::Result::Continue(); } @@ -687,7 +683,7 @@ gl::Error TextureVk::copySubTextureImpl(ContextVk *contextVk, angle::Result TextureVk::getCommandBufferForWrite(ContextVk *contextVk, vk::CommandBuffer **commandBufferOut) { - ANGLE_TRY(recordCommands(contextVk, commandBufferOut)); + ANGLE_TRY(mImage.recordCommands(contextVk, commandBufferOut)); return angle::Result::Continue(); } @@ -997,7 +993,7 @@ gl::Error TextureVk::generateMipmap(const gl::Context *context) } // We're changing this textureVk content, make sure we let the graph know. - finishCurrentCommands(renderer); + mImage.finishCurrentCommands(renderer); return gl::NoError(); } @@ -1086,7 +1082,7 @@ angle::Result TextureVk::initCubeMapRenderTargets(ContextVk *contextVk) ANGLE_TRY(mImage.initLayerImageView(contextVk, gl::TextureType::CubeMap, VK_IMAGE_ASPECT_COLOR_BIT, gl::SwizzleState(), &imageView, 1, cubeMapFaceIndex, 1)); - mCubeMapRenderTargets.emplace_back(&mImage, &imageView, this, cubeMapFaceIndex); + mCubeMapRenderTargets.emplace_back(&mImage, &imageView, cubeMapFaceIndex); } return angle::Result::Continue(); } @@ -1102,7 +1098,7 @@ gl::Error TextureVk::syncState(const gl::Context *context, const gl::Texture::Di if (mSampler.valid()) { RendererVk *renderer = contextVk->getRenderer(); - renderer->releaseObject(getStoredQueueSerial(), &mSampler); + renderer->releaseObject(renderer->getCurrentQueueSerial(), &mSampler); } const gl::SamplerState &samplerState = mState.getSamplerState(); @@ -1149,12 +1145,6 @@ gl::Error TextureVk::initializeContents(const gl::Context *context, return gl::NoError(); } -const vk::ImageHelper &TextureVk::getImage() const -{ - ASSERT(mImage.valid()); - return mImage; -} - const vk::ImageView &TextureVk::getImageView() const { ASSERT(mImage.valid()); @@ -1213,13 +1203,16 @@ angle::Result TextureVk::initImage(ContextVk *contextVk, void TextureVk::releaseImage(const gl::Context *context, RendererVk *renderer) { - mImage.release(renderer->getCurrentQueueSerial(), renderer); - renderer->releaseObject(getStoredQueueSerial(), &mBaseLevelImageView); - renderer->releaseObject(getStoredQueueSerial(), &mMipmapImageView); + mImage.release(renderer); + + Serial currentSerial = renderer->getCurrentQueueSerial(); + + renderer->releaseObject(currentSerial, &mBaseLevelImageView); + renderer->releaseObject(currentSerial, &mMipmapImageView); for (vk::ImageView &imageView : mCubeMapFaceImageViews) { - renderer->releaseObject(getStoredQueueSerial(), &imageView); + renderer->releaseObject(currentSerial, &imageView); } mCubeMapFaceImageViews.clear(); mCubeMapRenderTargets.clear(); diff --git a/src/libANGLE/renderer/vulkan/TextureVk.h b/src/libANGLE/renderer/vulkan/TextureVk.h index 499437ef7..fbfcf4975 100644 --- a/src/libANGLE/renderer/vulkan/TextureVk.h +++ b/src/libANGLE/renderer/vulkan/TextureVk.h @@ -83,7 +83,7 @@ class PixelBuffer final : angle::NonCopyable std::vector mSubresourceUpdates; }; -class TextureVk : public TextureImpl, public vk::CommandGraphResource +class TextureVk : public TextureImpl { public: TextureVk(const gl::TextureState &state, RendererVk *renderer); @@ -192,7 +192,18 @@ class TextureVk : public TextureImpl, public vk::CommandGraphResource gl::Error initializeContents(const gl::Context *context, const gl::ImageIndex &imageIndex) override; - const vk::ImageHelper &getImage() const; + const vk::ImageHelper &getImage() const + { + ASSERT(mImage.valid()); + return mImage; + } + + vk::ImageHelper &getImage() + { + ASSERT(mImage.valid()); + return mImage; + } + const vk::ImageView &getImageView() const; const vk::Sampler &getSampler() const; diff --git a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp index 26f088f07..90d9ff219 100644 --- a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp +++ b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp @@ -251,8 +251,9 @@ gl::Error VertexArrayVk::syncState(const gl::Context *context, if (bufferGL) { BufferVk *bufferVk = vk::GetImpl(bufferGL); - mCurrentElementArrayBufferResource = bufferVk; - mCurrentElementArrayBufferHandle = bufferVk->getVkBuffer().getHandle(); + mCurrentElementArrayBufferResource = &bufferVk->getBuffer(); + mCurrentElementArrayBufferHandle = + bufferVk->getBuffer().getBuffer().getHandle(); } else { @@ -327,8 +328,9 @@ angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk, } else { - mCurrentArrayBufferResources[attribIndex] = bufferVk; - mCurrentArrayBufferHandles[attribIndex] = bufferVk->getVkBuffer().getHandle(); + mCurrentArrayBufferResources[attribIndex] = &bufferVk->getBuffer(); + mCurrentArrayBufferHandles[attribIndex] = + bufferVk->getBuffer().getBuffer().getHandle(); mCurrentArrayBufferOffsets[attribIndex] = binding.getOffset(); mCurrentArrayBufferStrides[attribIndex] = binding.getStride(); } diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.cpp b/src/libANGLE/renderer/vulkan/vk_helpers.cpp index 4e041a1ea..32b26d917 100644 --- a/src/libANGLE/renderer/vulkan/vk_helpers.cpp +++ b/src/libANGLE/renderer/vulkan/vk_helpers.cpp @@ -503,6 +503,28 @@ void LineLoopHelper::Draw(uint32_t count, CommandBuffer *commandBuffer) commandBuffer->drawIndexed(count + 1, 1, 0, 0, 0); } +// BufferHelper implementation. +BufferHelper::BufferHelper() : mMemoryPropertyFlags{} +{ +} + +BufferHelper::~BufferHelper() = default; + +angle::Result BufferHelper::init(ContextVk *contextVk, + const VkBufferCreateInfo &createInfo, + VkMemoryPropertyFlags memoryPropertyFlags) +{ + ANGLE_TRY(mBuffer.init(contextVk, createInfo)); + return vk::AllocateBufferMemory(contextVk, memoryPropertyFlags, &mMemoryPropertyFlags, &mBuffer, + &mDeviceMemory); +} + +void BufferHelper::release(RendererVk *renderer) +{ + renderer->releaseObject(getStoredQueueSerial(), &mBuffer); + renderer->releaseObject(getStoredQueueSerial(), &mDeviceMemory); +} + // ImageHelper implementation. ImageHelper::ImageHelper() : mFormat(nullptr), mSamples(0), mCurrentLayout(VK_IMAGE_LAYOUT_UNDEFINED), mLayerCount(0) @@ -527,11 +549,6 @@ ImageHelper::~ImageHelper() ASSERT(!valid()); } -bool ImageHelper::valid() const -{ - return mImage.valid(); -} - angle::Result ImageHelper::init(Context *context, gl::TextureType textureType, const gl::Extents &extents, @@ -572,10 +589,10 @@ angle::Result ImageHelper::init(Context *context, return angle::Result::Continue(); } -void ImageHelper::release(Serial serial, RendererVk *renderer) +void ImageHelper::release(RendererVk *renderer) { - renderer->releaseObject(serial, &mImage); - renderer->releaseObject(serial, &mDeviceMemory); + renderer->releaseObject(getStoredQueueSerial(), &mImage); + renderer->releaseObject(getStoredQueueSerial(), &mDeviceMemory); } void ImageHelper::resetImageWeakReference() diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.h b/src/libANGLE/renderer/vulkan/vk_helpers.h index 858e6fce0..ab20e72cd 100644 --- a/src/libANGLE/renderer/vulkan/vk_helpers.h +++ b/src/libANGLE/renderer/vulkan/vk_helpers.h @@ -166,15 +166,37 @@ class LineLoopHelper final : angle::NonCopyable DynamicBuffer mDynamicIndexBuffer; }; -class ImageHelper final : angle::NonCopyable +class BufferHelper final : public CommandGraphResource +{ + public: + BufferHelper(); + ~BufferHelper(); + + angle::Result init(ContextVk *contextVk, + const VkBufferCreateInfo &createInfo, + VkMemoryPropertyFlags memoryPropertyFlags); + void release(RendererVk *renderer); + + bool valid() const { return mBuffer.valid(); } + const Buffer &getBuffer() const { return mBuffer; } + const DeviceMemory &getDeviceMemory() const { return mDeviceMemory; } + + private: + // Vulkan objects. + Buffer mBuffer; + DeviceMemory mDeviceMemory; + + // Cached properties. + VkMemoryPropertyFlags mMemoryPropertyFlags; +}; + +class ImageHelper final : public CommandGraphResource { public: ImageHelper(); ImageHelper(ImageHelper &&other); ~ImageHelper(); - bool valid() const; - angle::Result init(Context *context, gl::TextureType textureType, const gl::Extents &extents, @@ -205,8 +227,11 @@ class ImageHelper final : angle::NonCopyable const gl::Extents &extent, StagingUsage usage); + void release(RendererVk *renderer); + + bool valid() const { return mImage.valid(); } + VkImageAspectFlags getAspectFlags() const; - void release(Serial serial, RendererVk *renderer); void destroy(VkDevice device); void dumpResources(Serial serial, std::vector *garbageQueue);