blob: 66e316af9fdef738bcc7fa3bf1141bfb40a0f92e [file] [log] [blame]
/*
* MVKCmdTransfer.h
*
* Copyright (c) 2015-2020 The Brenwill Workshop Ltd. (http://www.brenwill.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "MVKCommand.h"
#include "MVKMTLBufferAllocation.h"
#include "MVKCommandResourceFactory.h"
#include "MVKFoundation.h"
#include "MVKVector.h"
#import <Metal/Metal.h>
class MVKImage;
class MVKBuffer;
#pragma mark -
#pragma mark MVKCmdCopyImage
/** Vulkan command to copy image regions. */
class MVKCmdCopyImage : public MVKCommand {
public:
VkResult setContent(MVKCommandBuffer* cmdBuff,
VkImage srcImage,
VkImageLayout srcImageLayout,
VkImage dstImage,
VkImageLayout dstImageLayout,
uint32_t regionCount,
const VkImageCopy* pRegions,
MVKCommandUse commandUse = kMVKCommandUseCopyImage);
void encode(MVKCommandEncoder* cmdEncoder) override;
protected:
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
VkResult setContent(MVKCommandBuffer* cmdBuff,
VkImage srcImage,
VkImageLayout srcImageLayout,
VkImage dstImage,
VkImageLayout dstImageLayout,
bool formatsMustMatch,
MVKCommandUse commandUse);
void addImageCopyRegion(const VkImageCopy& region, MVKPixelFormats* pixFmts);
void addTempBufferImageCopyRegion(const VkImageCopy& region, MVKPixelFormats* pixFmts);
MVKImage* _srcImage;
VkImageLayout _srcLayout;
MVKImage* _dstImage;
VkImageLayout _dstLayout;
uint32_t _srcSampleCount;
uint32_t _dstSampleCount;
bool _isSrcCompressed;
bool _isDstCompressed;
bool _canCopyFormats;
bool _useTempBuffer;
MVKVectorInline<VkImageCopy, 4> _imageCopyRegions;
MVKVectorInline<VkBufferImageCopy, 4> _srcTmpBuffImgCopies;
MVKVectorInline<VkBufferImageCopy, 4> _dstTmpBuffImgCopies;
size_t _tmpBuffSize;
MVKCommandUse _commandUse;
};
#pragma mark -
#pragma mark MVKCmdBlitImage
/** Number of vertices in a BLIT rectangle. */
#define kMVKBlitVertexCount 4
/** Combines a VkImageBlit with vertices to render it. */
typedef struct {
VkImageBlit region;
MVKVertexPosTex vertices[kMVKBlitVertexCount];
} MVKImageBlitRender;
/** Vulkan command to BLIT image regions. */
class MVKCmdBlitImage : public MVKCmdCopyImage {
public:
VkResult setContent(MVKCommandBuffer* cmdBuff,
VkImage srcImage,
VkImageLayout srcImageLayout,
VkImage dstImage,
VkImageLayout dstImageLayout,
uint32_t regionCount,
const VkImageBlit* pRegions,
VkFilter filter,
MVKCommandUse commandUse = kMVKCommandUseBlitImage);
void encode(MVKCommandEncoder* cmdEncoder) override;
MVKCmdBlitImage();
~MVKCmdBlitImage() override;
protected:
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
bool canCopy(const VkImageBlit& region);
void addImageBlitRegion(const VkImageBlit& region, MVKPixelFormats* pixFmts);
void addImageCopyRegionFromBlitRegion(const VkImageBlit& region, MVKPixelFormats* pixFmts);
void populateVertices(MVKVertexPosTex* vertices, const VkImageBlit& region);
void initMTLRenderPassDescriptor();
MTLRenderPassDescriptor* _mtlRenderPassDescriptor;
MVKRPSKeyBlitImg _blitKey;
MVKVectorInline<MVKImageBlitRender, 4> _mvkImageBlitRenders;
};
#pragma mark -
#pragma mark MVKCmdResolveImage
/** Describes Metal texture resolve parameters. */
typedef struct {
uint32_t level;
uint32_t slice;
} MVKMetalResolveSlice;
/** Vulkan command to resolve image regions. */
class MVKCmdResolveImage : public MVKCommand {
public:
VkResult setContent(MVKCommandBuffer* cmdBuff,
VkImage srcImage,
VkImageLayout srcImageLayout,
VkImage dstImage,
VkImageLayout dstImageLayout,
uint32_t regionCount,
const VkImageResolve* pRegions);
void encode(MVKCommandEncoder* cmdEncoder) override;
MVKCmdResolveImage();
~MVKCmdResolveImage() override;
protected:
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
void addExpansionRegion(const VkImageResolve& resolveRegion);
void addCopyRegion(const VkImageResolve& resolveRegion);
void addResolveSlices(const VkImageResolve& resolveRegion);
void initMTLRenderPassDescriptor();
MVKImage* _srcImage;
VkImageLayout _srcLayout;
MVKImage* _dstImage;
VkImageLayout _dstLayout;
MVKImageDescriptorData _transferImageData;
MTLRenderPassDescriptor* _mtlRenderPassDescriptor;
MVKVectorInline<VkImageBlit, 4> _expansionRegions;
MVKVectorInline<VkImageCopy, 4> _copyRegions;
MVKVectorInline<MVKMetalResolveSlice, 4> _mtlResolveSlices;
};
#pragma mark -
#pragma mark MVKCmdCopyBuffer
/** Vulkan command to copy buffer regions. */
class MVKCmdCopyBuffer : public MVKCommand {
public:
VkResult setContent(MVKCommandBuffer* cmdBuff,
VkBuffer srcBuffer,
VkBuffer destBuffer,
uint32_t regionCount,
const VkBufferCopy* pRegions);
void encode(MVKCommandEncoder* cmdEncoder) override;
protected:
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
MVKBuffer* _srcBuffer;
MVKBuffer* _dstBuffer;
MVKVectorInline<VkBufferCopy, 4> _mtlBuffCopyRegions;
};
#pragma mark -
#pragma mark MVKCmdBufferImageCopy
/** Command to copy either from a buffer to an image, or from an image to a buffer. */
class MVKCmdBufferImageCopy : public MVKCommand {
public:
VkResult setContent(MVKCommandBuffer* cmdBuff,
VkBuffer buffer,
VkImage image,
VkImageLayout imageLayout,
uint32_t regionCount,
const VkBufferImageCopy* pRegions,
bool toImage);
void encode(MVKCommandEncoder* cmdEncoder) override;
protected:
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
bool isArrayTexture();
MVKBuffer* _buffer;
MVKImage* _image;
VkImageLayout _imageLayout;
MVKVectorInline<VkBufferImageCopy, 4> _bufferImageCopyRegions;
bool _toImage = false;
};
#pragma mark -
#pragma mark MVKCmdClearAttachments
/** Vulkan command to clear attachment regions. */
class MVKCmdClearAttachments : public MVKCommand {
public:
VkResult setContent(MVKCommandBuffer* cmdBuff,
uint32_t attachmentCount,
const VkClearAttachment* pAttachments,
uint32_t rectCount,
const VkClearRect* pRects);
void encode(MVKCommandEncoder* cmdEncoder) override;
protected:
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
void populateVertices(float attWidth, float attHeight);
void populateVertices(VkClearRect& clearRect, float attWidth, float attHeight);
MVKVectorInline<VkClearRect, 4> _clearRects;
MVKVectorInline<simd::float4, (4 * 6)> _vertices;
simd::float4 _clearColors[kMVKClearAttachmentCount];
VkClearValue _vkClearValues[kMVKClearAttachmentCount];
MVKRPSKeyClearAtt _rpsKey;
uint32_t _mtlStencilValue;
bool _isClearingDepth;
bool _isClearingStencil;
};
#pragma mark -
#pragma mark MVKCmdClearImage
/** Vulkan command to clear an image. */
class MVKCmdClearImage : public MVKCommand {
public:
VkResult setContent(MVKCommandBuffer* cmdBuff,
VkImage image,
VkImageLayout imageLayout,
const VkClearValue& clearValue,
uint32_t rangeCount,
const VkImageSubresourceRange* pRanges,
bool isDepthStencilClear);
void encode(MVKCommandEncoder* cmdEncoder) override;
protected:
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
uint32_t populateMetalCopyRegions(const VkImageBlit* pRegion, uint32_t cpyRgnIdx);
uint32_t populateMetalBlitRenders(const VkImageBlit* pRegion, uint32_t rendRgnIdx);
void populateVertices(MVKVertexPosTex* vertices, const VkImageBlit* pRegion);
MVKImage* _image;
VkImageLayout _imgLayout;
MVKVectorInline<VkImageSubresourceRange, 4> _subresourceRanges;
VkClearValue _clearValue;
bool _isDepthStencilClear;
};
#pragma mark -
#pragma mark MVKCmdFillBuffer
/** Vulkan command to fill a buffer. */
class MVKCmdFillBuffer : public MVKCommand {
public:
VkResult setContent(MVKCommandBuffer* cmdBuff,
VkBuffer dstBuffer,
VkDeviceSize dstOffset,
VkDeviceSize size,
uint32_t data);
void encode(MVKCommandEncoder* cmdEncoder) override;
protected:
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
MVKBuffer* _dstBuffer;
VkDeviceSize _dstOffset;
uint32_t _wordCount;
uint32_t _dataValue;
};
#pragma mark -
#pragma mark MVKCmdUpdateBuffer
/** Vulkan command to update the contents of a buffer. */
class MVKCmdUpdateBuffer : public MVKCommand {
public:
VkResult setContent(MVKCommandBuffer* cmdBuff,
VkBuffer dstBuffer,
VkDeviceSize dstOffset,
VkDeviceSize dataSize,
const void* pData);
void encode(MVKCommandEncoder* cmdEncoder) override;
protected:
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
MVKBuffer* _dstBuffer;
VkDeviceSize _dstOffset;
VkDeviceSize _dataSize;
MVKVectorDefault<uint8_t> _srcDataCache;
};