| /* |
| * MVKMTLResourceBindings.h |
| * |
| * Copyright (c) 2015-2022 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 "mvk_vulkan.h" |
| |
| #import <Metal/Metal.h> |
| |
| |
| class MVKResource; |
| class MVKBuffer; |
| class MVKImage; |
| |
| |
| /** Describes a MTLTexture resource binding. */ |
| typedef struct MVKMTLTextureBinding { |
| union { id<MTLTexture> mtlTexture = nil; id<MTLTexture> mtlResource; }; // aliases |
| uint32_t swizzle = 0; |
| uint16_t index = 0; |
| bool isDirty = true; |
| |
| inline void markDirty() { isDirty = true; } |
| |
| inline void update(const MVKMTLTextureBinding &other) { |
| if (mtlTexture != other.mtlTexture || swizzle != other.swizzle) { |
| mtlTexture = other.mtlTexture; |
| swizzle = other.swizzle; |
| markDirty(); |
| } |
| } |
| } MVKMTLTextureBinding; |
| |
| /** Describes a MTLSamplerState resource binding. */ |
| typedef struct MVKMTLSamplerStateBinding { |
| union { id<MTLSamplerState> mtlSamplerState = nil; id<MTLSamplerState> mtlResource; }; // aliases |
| uint16_t index = 0; |
| bool isDirty = true; |
| |
| inline void markDirty() { isDirty = true; } |
| |
| inline void update(const MVKMTLSamplerStateBinding &other) { |
| if (mtlSamplerState != other.mtlSamplerState) { |
| mtlSamplerState = other.mtlSamplerState; |
| markDirty(); |
| } |
| } |
| } MVKMTLSamplerStateBinding; |
| |
| /** Describes a MTLBuffer resource binding. */ |
| typedef struct MVKMTLBufferBinding { |
| union { id<MTLBuffer> mtlBuffer = nil; id<MTLBuffer> mtlResource; const void* mtlBytes; }; // aliases |
| VkDeviceSize offset = 0; |
| uint32_t size = 0; |
| uint16_t index = 0; |
| bool justOffset = false; |
| bool isDirty = true; |
| bool isInline = false; |
| |
| inline void markDirty() { justOffset = false; isDirty = true; } |
| |
| inline void update(const MVKMTLBufferBinding &other) { |
| if (mtlBuffer != other.mtlBuffer || size != other.size || isInline != other.isInline) { |
| mtlBuffer = other.mtlBuffer; |
| size = other.size; |
| isInline = other.isInline; |
| offset = other.offset; |
| |
| justOffset = false; |
| isDirty = true; |
| } else if (offset != other.offset) { |
| offset = other.offset; |
| justOffset = !isDirty || justOffset; |
| isDirty = true; |
| } |
| } |
| } MVKMTLBufferBinding; |
| |
| /** Describes a MTLBuffer resource binding as used for an index buffer. */ |
| typedef struct MVKIndexMTLBufferBinding { |
| union { id<MTLBuffer> mtlBuffer = nil; id<MTLBuffer> mtlResource; }; // aliases |
| VkDeviceSize offset = 0; |
| uint8_t mtlIndexType = 0; // MTLIndexType |
| bool isDirty = true; |
| } MVKIndexMTLBufferBinding; |
| |
| /** Concise and consistent structure for holding pipeline barrier info. */ |
| typedef struct MVKPipelineBarrier { |
| |
| typedef enum : uint8_t { |
| None, |
| Memory, |
| Buffer, |
| Image, |
| } MVKPipelineBarrierType; |
| |
| MVKPipelineBarrierType type = None; |
| VkAccessFlags srcAccessMask = 0; |
| VkAccessFlags dstAccessMask = 0; |
| uint8_t srcQueueFamilyIndex = 0; |
| uint8_t dstQueueFamilyIndex = 0; |
| union { MVKBuffer* mvkBuffer = nullptr; MVKImage* mvkImage; MVKResource* mvkResource; }; |
| union { |
| struct { |
| VkDeviceSize offset = 0; |
| VkDeviceSize size = 0; |
| }; |
| struct { |
| VkImageLayout newLayout; |
| VkImageAspectFlags aspectMask; |
| uint16_t baseArrayLayer; |
| uint16_t layerCount; |
| uint8_t baseMipLevel; |
| uint8_t levelCount; |
| }; |
| }; |
| |
| bool isMemoryBarrier() { return type == Memory; } |
| bool isBufferBarrier() { return type == Buffer; } |
| bool isImageBarrier() { return type == Image; } |
| |
| MVKPipelineBarrier(const VkMemoryBarrier& vkBarrier) : |
| type(Memory), |
| srcAccessMask(vkBarrier.srcAccessMask), |
| dstAccessMask(vkBarrier.dstAccessMask) |
| {} |
| |
| MVKPipelineBarrier(const VkBufferMemoryBarrier& vkBarrier) : |
| type(Buffer), |
| srcAccessMask(vkBarrier.srcAccessMask), |
| dstAccessMask(vkBarrier.dstAccessMask), |
| srcQueueFamilyIndex(vkBarrier.srcQueueFamilyIndex), |
| dstQueueFamilyIndex(vkBarrier.dstQueueFamilyIndex), |
| mvkBuffer((MVKBuffer*)vkBarrier.buffer), |
| offset(vkBarrier.offset), |
| size(vkBarrier.size) |
| {} |
| |
| MVKPipelineBarrier(const VkImageMemoryBarrier& vkBarrier) : |
| type(Image), |
| srcAccessMask(vkBarrier.srcAccessMask), |
| dstAccessMask(vkBarrier.dstAccessMask), |
| srcQueueFamilyIndex(vkBarrier.srcQueueFamilyIndex), |
| dstQueueFamilyIndex(vkBarrier.dstQueueFamilyIndex), |
| mvkImage((MVKImage*)vkBarrier.image), |
| newLayout(vkBarrier.newLayout), |
| aspectMask(vkBarrier.subresourceRange.aspectMask), |
| baseArrayLayer(vkBarrier.subresourceRange.baseArrayLayer), |
| layerCount(vkBarrier.subresourceRange.layerCount), |
| baseMipLevel(vkBarrier.subresourceRange.baseMipLevel), |
| levelCount(vkBarrier.subresourceRange.levelCount) |
| {} |
| |
| } MVKPipelineBarrier; |
| |