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
return true;
}
const ImageDesc &TextureState::getBaseLevelDesc() const
{
ASSERT(mType != TextureType::CubeMap || isCubeComplete());
return getImageDesc(getBaseImageTarget(), getEffectiveBaseLevel());
}
void TextureState::setCrop(const gl::Rectangle& rect)
{
mCropRect = rect;
......
......@@ -115,6 +115,9 @@ struct TextureState final : private angle::NonCopyable
GLenum getUsage() const { return mUsage; }
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
void setCrop(const gl::Rectangle& rect);
const gl::Rectangle& getCrop() const;
......
......@@ -41,6 +41,8 @@ struct Format final : private angle::NonCopyable
static const Format &Get(ID id);
static ID InternalFormatToID(GLenum internalFormat);
constexpr bool hasDepthOrStencilBits() const;
ID id;
// The closest matching GL internal format for the storage this format uses. Note that this
......@@ -108,6 +110,10 @@ constexpr Format::Format(ID id,
{
}
constexpr bool Format::hasDepthOrStencilBits() const
{
return depthBits > 0 || stencilBits > 0;
}
} // namespace angle
#include "libANGLE/renderer/Format_ID_autogen.inl"
......
......@@ -12,6 +12,7 @@
#include "libANGLE/renderer/vulkan/RenderTargetVk.h"
#include "libANGLE/renderer/vulkan/RendererVk.h"
#include "libANGLE/renderer/vulkan/vk_format_utils.h"
#include "libANGLE/renderer/vulkan/vk_helpers.h"
namespace rx
{
......@@ -142,7 +143,8 @@ void CommandGraphResource::onReadResource(CommandGraphNode *readingNode, Serial
bool CommandGraphResource::checkResourceInUseAndRefreshDeps(RendererVk *renderer)
{
if (!renderer->isResourceInUse(*this))
if (!renderer->isResourceInUse(*this) ||
(renderer->getCurrentQueueSerial() > mStoredQueueSerial))
{
mCurrentReadingNodes.clear();
mCurrentWritingNode = nullptr;
......@@ -243,6 +245,14 @@ void CommandGraphNode::storeRenderPassInfo(const Framebuffer &framebuffer,
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);
colorRenderTarget->resource->onWriteResource(this, serial);
}
......@@ -250,6 +260,19 @@ void CommandGraphNode::appendColorRenderTarget(Serial serial, RenderTargetVk *co
void CommandGraphNode::appendDepthStencilRenderTarget(Serial serial,
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);
depthStencilRenderTarget->resource->onWriteResource(this, serial);
}
......
......@@ -174,6 +174,7 @@ gl::Error ContextVk::setupDraw(const gl::Context *context,
ASSERT(texture);
TextureVk *textureVk = vk::GetImpl(texture);
ANGLE_TRY(textureVk->ensureImageInitialized(mRenderer));
textureVk->onReadResource(graphNode, mRenderer->getCurrentQueueSerial());
}
}
......
......@@ -568,11 +568,6 @@ gl::Error FramebufferVk::getCommandGraphNodeForDraw(const gl::Context *context,
RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex];
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);
attachmentClearValues.emplace_back(contextVk->getClearColorValue());
}
......@@ -580,15 +575,6 @@ gl::Error FramebufferVk::getCommandGraphNodeForDraw(const gl::Context *context,
RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil();
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);
attachmentClearValues.emplace_back(contextVk->getClearDepthStencilValue());
}
......
......@@ -25,19 +25,19 @@ void MapSwizzleState(GLenum internalFormat,
{
switch (internalFormat)
{
case GL_LUMINANCE:
case GL_LUMINANCE8_OES:
swizzleStateOut->swizzleRed = swizzleState.swizzleRed;
swizzleStateOut->swizzleGreen = swizzleState.swizzleRed;
swizzleStateOut->swizzleBlue = swizzleState.swizzleRed;
swizzleStateOut->swizzleAlpha = GL_ONE;
break;
case GL_LUMINANCE_ALPHA:
case GL_LUMINANCE8_ALPHA8_OES:
swizzleStateOut->swizzleRed = swizzleState.swizzleRed;
swizzleStateOut->swizzleGreen = swizzleState.swizzleRed;
swizzleStateOut->swizzleBlue = swizzleState.swizzleRed;
swizzleStateOut->swizzleAlpha = swizzleState.swizzleGreen;
break;
case GL_ALPHA:
case GL_ALPHA8_OES:
swizzleStateOut->swizzleRed = GL_ZERO;
swizzleStateOut->swizzleGreen = GL_ZERO;
swizzleStateOut->swizzleBlue = GL_ZERO;
......@@ -48,8 +48,110 @@ void MapSwizzleState(GLenum internalFormat,
break;
}
}
constexpr VkBufferUsageFlags kStagingBufferFlags =
(VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
constexpr size_t kStagingBufferSize = 1024 * 16;
} // anonymous namespace
// StagingStorage implementation.
StagingStorage::StagingStorage()
: mStagingBuffer(kStagingBufferFlags, kStagingBufferSize), mCurrentBufferHandle(VK_NULL_HANDLE)
{
mStagingBuffer.init(1);
}
StagingStorage::~StagingStorage()
{
}
void StagingStorage::release(RendererVk *renderer)
{
mStagingBuffer.release(renderer);
}
gl::Error StagingStorage::stageSubresourceUpdate(ContextVk *contextVk,
const gl::Extents &extents,
const gl::InternalFormat &formatInfo,
const gl::PixelUnpackState &unpack,
GLenum type,
const uint8_t *pixels)
{
GLuint inputRowPitch = 0;
ANGLE_TRY_RESULT(
formatInfo.computeRowPitch(type, extents.width, unpack.alignment, unpack.rowLength),
inputRowPitch);
GLuint inputDepthPitch = 0;
ANGLE_TRY_RESULT(
formatInfo.computeDepthPitch(extents.height, unpack.imageHeight, inputRowPitch),
inputDepthPitch);
// TODO(jmadill): skip images for 3D Textures.
bool applySkipImages = false;
GLuint inputSkipBytes = 0;
ANGLE_TRY_RESULT(
formatInfo.computeSkipBytes(inputRowPitch, inputDepthPitch, unpack, applySkipImages),
inputSkipBytes);
RendererVk *renderer = contextVk->getRenderer();
const vk::Format &vkFormat = renderer->getFormat(formatInfo.sizedInternalFormat);
const angle::Format &storageFormat = vkFormat.textureFormat();
size_t outputRowPitch = storageFormat.pixelBytes * extents.width;
size_t outputDepthPitch = outputRowPitch * extents.height;
uint8_t *stagingPointer = nullptr;
bool newBufferAllocated = false;
uint32_t stagingOffset = 0;
size_t allocationSize = outputDepthPitch * extents.depth;
mStagingBuffer.allocate(renderer, allocationSize, &stagingPointer, &mCurrentBufferHandle,
&stagingOffset, &newBufferAllocated);
const uint8_t *source = pixels + inputSkipBytes;
LoadImageFunctionInfo loadFunction = vkFormat.loadFunctions(type);
loadFunction.loadFunction(extents.width, extents.height, extents.depth, source, inputRowPitch,
inputDepthPitch, stagingPointer, outputRowPitch, outputDepthPitch);
mCurrentCopyRegion.bufferOffset = static_cast<VkDeviceSize>(stagingOffset);
mCurrentCopyRegion.bufferRowLength = extents.width;
mCurrentCopyRegion.bufferImageHeight = extents.height;
mCurrentCopyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
mCurrentCopyRegion.imageSubresource.mipLevel = 0;
mCurrentCopyRegion.imageSubresource.baseArrayLayer = 0;
mCurrentCopyRegion.imageSubresource.layerCount = 1;
gl_vk::GetOffset(gl::Offset(), &mCurrentCopyRegion.imageOffset);
gl_vk::GetExtent(extents, &mCurrentCopyRegion.imageExtent);
return gl::NoError();
}
vk::Error StagingStorage::flushUpdatesToImage(RendererVk *renderer,
vk::ImageHelper *image,
vk::CommandBuffer *commandBuffer)
{
if (mCurrentBufferHandle != VK_NULL_HANDLE)
{
// Conservatively flush all writes to the image. We could use a more restricted barrier.
image->changeLayoutWithStages(
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
ANGLE_TRY(mStagingBuffer.flush(renderer->getDevice()));
commandBuffer->copyBufferToImage(mCurrentBufferHandle, image->getImage(),
image->getCurrentLayout(), 1, &mCurrentCopyRegion);
mCurrentBufferHandle = VK_NULL_HANDLE;
}
return vk::NoError();
}
// TextureVk implementation.
TextureVk::TextureVk(const gl::TextureState &state) : TextureImpl(state)
{
mRenderTarget.image = &mImage;
......@@ -71,6 +173,8 @@ gl::Error TextureVk::onDestroy(const gl::Context *context)
renderer->releaseResource(*this, &mImageView);
renderer->releaseResource(*this, &mSampler);
mStagingStorage.release(renderer);
onStateChange(context, angle::SubjectMessage::DEPENDENT_DIRTY_BITS);
return gl::NoError();
......@@ -109,39 +213,16 @@ gl::Error TextureVk::setImage(const gl::Context *context,
}
// Early-out on empty textures, don't create a zero-sized storage.
if (size.width == 0 || size.height == 0 || size.depth == 0)
if (size.empty())
{
return gl::NoError();
}
// TODO(jmadill): support other types of textures.
ASSERT(target == gl::TextureTarget::_2D);
// Convert internalFormat to sized internal format.
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat, type);
const vk::Format &vkFormat = renderer->getFormat(formatInfo.sizedInternalFormat);
if (!mImage.valid())
// TODO(jmadill): Cube map textures. http://anglebug.com/2318
if (target != gl::TextureTarget::_2D)
{
VkImageUsageFlags usage =
(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
ANGLE_TRY(mImage.init2D(device, size, vkFormat, 1, usage));
VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
ANGLE_TRY(mImage.initMemory(device, renderer->getMemoryProperties(), flags));
gl::SwizzleState mappedSwizzle;
MapSwizzleState(formatInfo.internalFormat, mState.getSwizzleState(), &mappedSwizzle);
ANGLE_TRY(
mImage.initImageView(device, VK_IMAGE_ASPECT_COLOR_BIT, mappedSwizzle, &mImageView));
// TODO(jmadill): Fold this into the RenderPass load/store ops. http://anglebug.com/2361
vk::CommandBuffer *commandBuffer = nullptr;
ANGLE_TRY(beginWriteResource(renderer, &commandBuffer));
VkClearColorValue black = {{0}};
mImage.clearColor(black, commandBuffer);
UNIMPLEMENTED();
return gl::InternalError();
}
if (!mSampler.valid())
......@@ -171,10 +252,16 @@ gl::Error TextureVk::setImage(const gl::Context *context,
ANGLE_TRY(mSampler.init(device, samplerInfo));
}
// Create a new graph node to store image initialization commands.
getNewWritingNode(renderer);
// Handle initial data.
if (pixels)
{
ANGLE_TRY(setSubImageImpl(contextVk, formatInfo, unpack, type, pixels));
// Convert internalFormat to sized internal format.
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat, type);
ANGLE_TRY(mStagingStorage.stageSubresourceUpdate(contextVk, size, formatInfo, unpack, type,
pixels));
}
return gl::NoError();
......@@ -191,71 +278,9 @@ gl::Error TextureVk::setSubImage(const gl::Context *context,
{
ContextVk *contextVk = vk::GetImpl(context);
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(format, type);
ANGLE_TRY(setSubImageImpl(contextVk, formatInfo, unpack, type, pixels));
return gl::NoError();
}
gl::Error TextureVk::setSubImageImpl(ContextVk *contextVk,
const gl::InternalFormat &formatInfo,
const gl::PixelUnpackState &unpack,
GLenum type,
const uint8_t *pixels)
{
RendererVk *renderer = contextVk->getRenderer();
VkDevice device = renderer->getDevice();
const gl::Extents &size = mImage.getExtents();
const vk::Format &vkFormat = mImage.getFormat();
vk::ImageHelper stagingImage;
ANGLE_TRY(stagingImage.init2DStaging(device, renderer->getMemoryProperties(), vkFormat, size,
vk::StagingUsage::Write));
GLuint inputRowPitch = 0;
ANGLE_TRY_RESULT(
formatInfo.computeRowPitch(type, size.width, unpack.alignment, unpack.rowLength),
inputRowPitch);
GLuint inputDepthPitch = 0;
ANGLE_TRY_RESULT(formatInfo.computeDepthPitch(size.height, unpack.imageHeight, inputRowPitch),
inputDepthPitch);
// TODO(jmadill): skip images for 3D Textures.
bool applySkipImages = false;
GLuint inputSkipBytes = 0;
ANGLE_TRY_RESULT(
formatInfo.computeSkipBytes(inputRowPitch, inputDepthPitch, unpack, applySkipImages),
inputSkipBytes);
auto loadFunction = vkFormat.loadFunctions(type);
uint8_t *mapPointer = nullptr;
ANGLE_TRY(stagingImage.getDeviceMemory().map(device, 0, VK_WHOLE_SIZE, 0, &mapPointer));
const uint8_t *source = pixels + inputSkipBytes;
// Get the subresource layout. This has important parameters like row pitch.
// TODO(jmadill): Fill out these parameters based on input parameters.
VkSubresourceLayout subresourceLayout;
stagingImage.getImage().getSubresourceLayout(device, VK_IMAGE_ASPECT_COLOR_BIT, 0, 0,
&subresourceLayout);
loadFunction.loadFunction(size.width, size.height, size.depth, source, inputRowPitch,
inputDepthPitch, mapPointer,
static_cast<size_t>(subresourceLayout.rowPitch),
static_cast<size_t>(subresourceLayout.depthPitch));
stagingImage.getDeviceMemory().unmap(device);
vk::CommandBuffer *commandBuffer = nullptr;
ANGLE_TRY(beginWriteResource(renderer, &commandBuffer));
vk::ImageHelper::Copy(&stagingImage, &mImage, gl::Offset(), gl::Offset(), size,
VK_IMAGE_ASPECT_COLOR_BIT, commandBuffer);
// Immediately release staging image.
// TODO(jmadill): Staging image re-use.
renderer->releaseObject(renderer->getCurrentQueueSerial(), &stagingImage);
ANGLE_TRY(mStagingStorage.stageSubresourceUpdate(
contextVk, gl::Extents(area.width, area.height, area.depth), formatInfo, unpack, type,
pixels));
return gl::NoError();
}
......@@ -363,12 +388,73 @@ gl::Error TextureVk::getAttachmentRenderTarget(const gl::Context *context,
const gl::ImageIndex &imageIndex,
FramebufferAttachmentRenderTarget **rtOut)
{
// TODO(jmadill): Handle cube textures. http://anglebug.com/2318
ASSERT(imageIndex.type == gl::TextureType::_2D);
// Non-zero mip level attachments are an ES 3.0 feature.
ASSERT(imageIndex.mipIndex == 0 && imageIndex.layerIndex == gl::ImageIndex::ENTIRE_LEVEL);
ContextVk *contextVk = vk::GetImpl(context);
RendererVk *renderer = contextVk->getRenderer();
ANGLE_TRY(ensureImageInitialized(renderer));
*rtOut = &mRenderTarget;
return gl::NoError();
}
vk::Error TextureVk::ensureImageInitialized(RendererVk *renderer)
{
VkDevice device = renderer->getDevice();
vk::CommandBuffer *commandBuffer = nullptr;
updateQueueSerial(renderer->getCurrentQueueSerial());
if (!hasChildlessWritingNode())
{
beginWriteResource(renderer, &commandBuffer);
}
else
{
vk::CommandGraphNode *node = getCurrentWritingNode();
commandBuffer = node->getOutsideRenderPassCommands();
if (!commandBuffer->valid())
{
ANGLE_TRY(node->beginOutsideRenderPassRecording(device, renderer->getCommandPool(),
&commandBuffer));
}
}
if (!mImage.valid())
{
const gl::ImageDesc &baseLevelDesc = mState.getBaseLevelDesc();
const gl::Extents &extents = baseLevelDesc.size;
const vk::Format &format =
renderer->getFormat(baseLevelDesc.format.info->sizedInternalFormat);
VkImageUsageFlags usage =
(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
ANGLE_TRY(mImage.init2D(device, extents, format, 1, usage));
VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
ANGLE_TRY(mImage.initMemory(device, renderer->getMemoryProperties(), flags));
gl::SwizzleState mappedSwizzle;
MapSwizzleState(format.internalFormat, mState.getSwizzleState(), &mappedSwizzle);
ANGLE_TRY(
mImage.initImageView(device, VK_IMAGE_ASPECT_COLOR_BIT, mappedSwizzle, &mImageView));
// TODO(jmadill): Fold this into the RenderPass load/store ops. http://anglebug.com/2361
VkClearColorValue black = {{0}};
mImage.clearColor(black, commandBuffer);
}
ANGLE_TRY(mStagingStorage.flushUpdatesToImage(renderer, &mImage, commandBuffer));
return vk::NoError();
}
void TextureVk::syncState(const gl::Texture::DirtyBits &dirtyBits)
{
// TODO(jmadill): Texture sync state.
......
......@@ -18,6 +18,31 @@
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
{
public:
......@@ -116,18 +141,16 @@ class TextureVk : public TextureImpl, public vk::CommandGraphResource
const vk::ImageView &getImageView() const;
const vk::Sampler &getSampler() const;
private:
gl::Error setSubImageImpl(ContextVk *contextVk,
const gl::InternalFormat &formatInfo,
const gl::PixelUnpackState &unpack,
GLenum type,
const uint8_t *pixels);
vk::Error ensureImageInitialized(RendererVk *renderer);
private:
vk::ImageHelper mImage;
vk::ImageView mImageView;
vk::Sampler mSampler;
RenderTargetVk mRenderTarget;
StagingStorage mStagingStorage;
};
} // namespace rx
......
......@@ -141,7 +141,6 @@ gl::Error VertexArrayVk::streamIndexData(RendererVk *renderer,
ANGLE_TRY(mDynamicIndexData.flush(renderer->getDevice()));
mCurrentElementArrayBufferOffset = offset;
return gl::NoError();
}
......
......@@ -429,6 +429,19 @@ void CommandBuffer::copyBuffer(const VkBuffer &srcBuffer,
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,
VkImageLayout imageLayout,
const VkClearColorValue &color,
......@@ -1251,8 +1264,21 @@ VkIndexType GetIndexType(GLenum elementType)
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
std::ostream &operator<<(std::ostream &stream, const rx::vk::Error &error)
......
......@@ -356,6 +356,12 @@ class CommandBuffer : public WrappedObject<CommandBuffer, VkCommandBuffer>
uint32_t regionCount,
const VkBufferCopy *regions);
void copyBufferToImage(VkBuffer srcBuffer,
const Image &dstImage,
VkImageLayout dstImageLayout,
uint32_t regionCount,
const VkBufferImageCopy *regions);
void copyImage(const Image &srcImage,
VkImageLayout srcImageLayout,
const Image &dstImage,
......@@ -651,6 +657,8 @@ VkFrontFace GetFrontFace(GLenum frontFace);
VkSampleCountFlagBits GetSamples(GLint sampleCount);
VkComponentSwizzle GetSwizzle(const GLenum swizzle);
VkIndexType GetIndexType(GLenum elementType);
void GetOffset(const gl::Offset &glOffset, VkOffset3D *vkOffset);
void GetExtent(const gl::Extents &glExtent, VkExtent3D *vkExtent);
} // namespace gl_vk
} // 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