зеркало из https://github.com/AvaloniaUI/angle.git
Vulkan: Make Buffer/Image be CommandGraphResources.
Don't make TextureVk/RenderbufferVk/SurfaceVk/BufferVk own the manipulation of the command graph. Instead put the operations close to the buffers and images used to render. This will lead towards implementing implicit barriers on the command graph resources. Bug: angleproject:2828 Change-Id: I07b742b6792c60285b280d6454f90e963d667e0e Reviewed-on: https://chromium-review.googlesource.com/1246983 Reviewed-by: Frank Henigman <fjhenigman@chromium.org> Reviewed-by: Geoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
This commit is contained in:
Родитель
50e6eaaee6
Коммит
2d03ff4a1f
|
@ -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<const uint8_t *>(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<uint8_t **>(mapPtr));
|
||||
return mBuffer.getDeviceMemory().map(contextVk, 0, mState.getSize(), 0,
|
||||
reinterpret_cast<uint8_t **>(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<uint8_t **>(mapPtr)));
|
||||
ANGLE_TRY(mBuffer.getDeviceMemory().map(contextVk, offset, length, 0,
|
||||
reinterpret_cast<uint8_t **>(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<VkDeviceSize>(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<VkDeviceSize>(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<VkDeviceSize>(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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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<GLsizei>(width) != mState.getWidth() ||
|
||||
static_cast<GLsizei>(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)
|
||||
{
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
namespace rx
|
||||
{
|
||||
|
||||
class RenderbufferVk : public RenderbufferImpl, public vk::CommandGraphResource
|
||||
class RenderbufferVk : public RenderbufferImpl
|
||||
{
|
||||
public:
|
||||
RenderbufferVk(const gl::RenderbufferState &state);
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -83,7 +83,7 @@ class PixelBuffer final : angle::NonCopyable
|
|||
std::vector<SubresourceUpdate> 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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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<GarbageObject> *garbageQueue);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче