no message

This commit is contained in:
gem
2025-02-18 15:21:31 +08:00
commit 2d133e56d7
1980 changed files with 465595 additions and 0 deletions

View File

@@ -0,0 +1,121 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "VKBuffer.h"
#include "VKCommandBuffer.h"
#include "VKCommands.h"
#include "VKDevice.h"
#include "profiler/Profiler.h"
namespace cc {
namespace gfx {
CCVKBuffer::CCVKBuffer() {
_typedID = generateObjectID<decltype(this)>();
}
CCVKBuffer::~CCVKBuffer() {
destroy();
}
void CCVKBuffer::doInit(const BufferInfo & /*info*/) {
createBuffer(_size, _count);
createBufferView(_size);
}
void CCVKBuffer::doInit(const BufferViewInfo &info) {
auto *buffer = static_cast<CCVKBuffer *>(info.buffer);
_gpuBuffer = buffer->gpuBuffer();
createBufferView(_size);
}
void CCVKBuffer::createBuffer(uint32_t size, uint32_t count) {
_gpuBuffer = ccnew CCVKGPUBuffer;
_gpuBuffer->size = size;
_gpuBuffer->count = count;
_gpuBuffer->usage = _usage;
_gpuBuffer->memUsage = _memUsage;
_gpuBuffer->stride = _stride;
_gpuBuffer->init();
}
void CCVKBuffer::createBufferView(uint32_t range) {
_gpuBufferView = ccnew CCVKGPUBufferView;
_gpuBufferView->range = range;
_gpuBufferView->gpuBuffer = _gpuBuffer;
_gpuBufferView->offset = _offset;
}
void CCVKBuffer::doDestroy() {
_gpuBufferView = nullptr;
_gpuBuffer = nullptr;
}
void CCVKBuffer::doResize(uint32_t size, uint32_t count) {
createBuffer(size, count);
// Hold reference to keep the old bufferView alive during DescriptorHub::update and IAHub::update.
IntrusivePtr<CCVKGPUBufferView> oldBufferView = _gpuBufferView;
createBufferView(size);
CCVKDevice::getInstance()->gpuDescriptorHub()->update(oldBufferView, _gpuBufferView);
CCVKDevice::getInstance()->gpuIAHub()->update(oldBufferView, _gpuBufferView);
}
void CCVKBuffer::update(const void *buffer, uint32_t size) {
CC_PROFILE(CCVKBufferUpdate);
cmdFuncCCVKUpdateBuffer(CCVKDevice::getInstance(), _gpuBuffer, buffer, size, nullptr);
}
void CCVKGPUBuffer::shutdown() {
CCVKDevice::getInstance()->gpuBarrierManager()->cancel(this);
CCVKDevice::getInstance()->gpuRecycleBin()->collect(this);
CCVKDevice::getInstance()->gpuBufferHub()->erase(this);
CCVKDevice::getInstance()->getMemoryStatus().bufferSize -= size;
CC_PROFILE_MEMORY_DEC(Buffer, size);
}
void CCVKGPUBuffer::init() {
if (hasFlag(usage, BufferUsageBit::INDIRECT)) {
const size_t drawInfoCount = size / sizeof(DrawInfo);
indexedIndirectCmds.resize(drawInfoCount);
indirectCmds.resize(drawInfoCount);
}
cmdFuncCCVKCreateBuffer(CCVKDevice::getInstance(), this);
CCVKDevice::getInstance()->getMemoryStatus().bufferSize += size;
CC_PROFILE_MEMORY_INC(Buffer, size);
}
void CCVKGPUBufferView::shutdown() {
CCVKDevice::getInstance()->gpuDescriptorHub()->disengage(this);
CCVKDevice::getInstance()->gpuIAHub()->disengage(this);
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,58 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "VKStd.h"
#include "gfx-base/GFXBuffer.h"
#include "gfx-vulkan/VKGPUObjects.h"
namespace cc {
namespace gfx {
class CC_VULKAN_API CCVKBuffer final : public Buffer {
public:
CCVKBuffer();
~CCVKBuffer() override;
void update(const void *buffer, uint32_t size) override;
inline CCVKGPUBuffer *gpuBuffer() const { return _gpuBuffer; }
inline CCVKGPUBufferView *gpuBufferView() const { return _gpuBufferView; }
protected:
void doInit(const BufferInfo &info) override;
void doInit(const BufferViewInfo &info) override;
void doDestroy() override;
void doResize(uint32_t size, uint32_t count) override;
void createBuffer(uint32_t size, uint32_t count);
void createBufferView(uint32_t range);
IntrusivePtr<CCVKGPUBuffer> _gpuBuffer;
IntrusivePtr<CCVKGPUBufferView> _gpuBufferView;
};
} // namespace gfx
} // namespace cc

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,116 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "base/std/container/queue.h"
#include "gfx-base/GFXCommandBuffer.h"
#include "VKGPUObjects.h"
namespace cc {
namespace gfx {
class CC_VULKAN_API CCVKCommandBuffer final : public CommandBuffer {
public:
CCVKCommandBuffer();
~CCVKCommandBuffer() override;
void begin(RenderPass *renderPass, uint32_t subpass, Framebuffer *frameBuffer) override;
void end() override;
void beginRenderPass(RenderPass *renderPass, Framebuffer *fbo, const Rect &renderArea, const Color *colors, float depth, uint32_t stencil, CommandBuffer *const *secondaryCBs, uint32_t secondaryCBCount) override;
void endRenderPass() override;
void insertMarker(const MarkerInfo &marker) override;
void beginMarker(const MarkerInfo &marker) override;
void endMarker() override;
void bindPipelineState(PipelineState *pso) override;
void bindDescriptorSet(uint32_t set, DescriptorSet *descriptorSet, uint32_t dynamicOffsetCount, const uint32_t *dynamicOffsets) override;
void bindInputAssembler(InputAssembler *ia) override;
void setViewport(const Viewport &vp) override;
void setScissor(const Rect &rect) override;
void setLineWidth(float width) override;
void setDepthBias(float constant, float clamp, float slope) override;
void setBlendConstants(const Color &constants) override;
void setDepthBound(float minBounds, float maxBounds) override;
void setStencilWriteMask(StencilFace face, uint32_t mask) override;
void setStencilCompareMask(StencilFace face, uint32_t reference, uint32_t mask) override;
void nextSubpass() override;
void draw(const DrawInfo &info) override;
void updateBuffer(Buffer *buffer, const void *data, uint32_t size) override;
void copyBuffersToTexture(const uint8_t *const *buffers, Texture *texture, const BufferTextureCopy *regions, uint32_t count) override;
void blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) override;
void copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override;
void resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override;
void execute(CommandBuffer *const *cmdBuffs, uint32_t count) override;
void dispatch(const DispatchInfo &info) override;
void pipelineBarrier(const GeneralBarrier *barrier, const BufferBarrier *const *bufferBarriers, const Buffer *const *buffers, uint32_t bufferBarrierCount, const TextureBarrier *const *textureBarriers, const Texture *const *textures, uint32_t textureBarrierCount) override;
void beginQuery(QueryPool *queryPool, uint32_t id) override;
void endQuery(QueryPool *queryPool, uint32_t id) override;
void resetQueryPool(QueryPool *queryPool) override;
void customCommand(CustomCommand &&cmd) override;
protected:
friend class CCVKQueue;
using ImageBarrierList = ccstd::vector<VkImageMemoryBarrier>;
using BufferBarrierList = ccstd::vector<VkBufferMemoryBarrier>;
void doInit(const CommandBufferInfo &info) override;
void doDestroy() override;
void bindDescriptorSets(VkPipelineBindPoint bindPoint);
void selfDependency();
IntrusivePtr<CCVKGPUCommandBuffer> _gpuCommandBuffer;
ConstPtr<CCVKGPUPipelineState> _curGPUPipelineState;
ccstd::vector<ConstPtr<CCVKGPUDescriptorSet>> _curGPUDescriptorSets;
ccstd::vector<VkDescriptorSet> _curVkDescriptorSets;
ccstd::vector<uint32_t> _curDynamicOffsets;
ccstd::vector<ccstd::vector<uint32_t>> _curDynamicOffsetsArray;
uint32_t _firstDirtyDescriptorSet = UINT_MAX;
ConstPtr<CCVKGPUInputAssembler> _curGPUInputAssembler;
ConstPtr<CCVKGPUFramebuffer> _curGPUFBO;
IntrusivePtr<CCVKGPURenderPass> _curGPURenderPass;
bool _secondaryRP = false;
bool _hasSubPassSelfDependency = false;
uint32_t _currentSubPass = 0;
DynamicStates _curDynamicStates;
// temp storage
ccstd::vector<VkImageBlit> _blitRegions;
ccstd::vector<VkCommandBuffer> _vkCommandBuffers;
ccstd::queue<VkEvent> _availableEvents;
ccstd::unordered_map<const GFXObject *, VkEvent> _barrierEvents;
ccstd::queue<VkCommandBuffer> _pendingQueue;
VkDebugMarkerMarkerInfoEXT _markerInfo = {VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT, nullptr};
VkDebugUtilsLabelEXT _utilLabelInfo = {VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, nullptr};
};
} // namespace gfx
} // namespace cc

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,65 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "VKGPUObjects.h"
namespace cc {
namespace gfx {
class CCVKDevice;
void cmdFuncCCVKGetDeviceQueue(CCVKDevice *device, CCVKGPUQueue *gpuQueue);
void cmdFuncCCVKCreateQueryPool(CCVKDevice *device, CCVKGPUQueryPool *gpuQueryPool);
void cmdFuncCCVKCreateTexture(CCVKDevice *device, CCVKGPUTexture *gpuTexture);
void cmdFuncCCVKCreateTextureView(CCVKDevice *device, CCVKGPUTextureView *gpuTextureView);
void cmdFuncCCVKCreateSampler(CCVKDevice *device, CCVKGPUSampler *gpuSampler);
void cmdFuncCCVKCreateBuffer(CCVKDevice *device, CCVKGPUBuffer *gpuBuffer);
void cmdFuncCCVKCreateRenderPass(CCVKDevice *device, CCVKGPURenderPass *gpuRenderPass);
void cmdFuncCCVKCreateFramebuffer(CCVKDevice *device, CCVKGPUFramebuffer *gpuFramebuffer);
void cmdFuncCCVKCreateShader(CCVKDevice *device, CCVKGPUShader *gpuShader);
void cmdFuncCCVKCreateDescriptorSetLayout(CCVKDevice *device, CCVKGPUDescriptorSetLayout *gpuDescriptorSetLayout);
void cmdFuncCCVKCreatePipelineLayout(CCVKDevice *device, CCVKGPUPipelineLayout *gpuPipelineLayout);
void cmdFuncCCVKCreateGraphicsPipelineState(CCVKDevice *device, CCVKGPUPipelineState *gpuPipelineState);
void cmdFuncCCVKCreateComputePipelineState(CCVKDevice *device, CCVKGPUPipelineState *gpuPipelineState);
void cmdFuncCCVKCreateGeneralBarrier(CCVKDevice *device, CCVKGPUGeneralBarrier *gpuGeneralBarrier);
void cmdFuncCCVKUpdateBuffer(CCVKDevice *device, CCVKGPUBuffer *gpuBuffer, const void *buffer, uint32_t size, const CCVKGPUCommandBuffer *cmdBuffer = nullptr);
void cmdFuncCCVKCopyBuffersToTexture(CCVKDevice *device, const uint8_t *const *buffers, CCVKGPUTexture *gpuTexture, const BufferTextureCopy *regions, uint32_t count, const CCVKGPUCommandBuffer *gpuCommandBuffer);
void cmdFuncCCVKCopyTextureToBuffers(CCVKDevice *device, CCVKGPUTexture *srcTexture, CCVKGPUBufferView *destBuffer, const BufferTextureCopy *regions, uint32_t count, const CCVKGPUCommandBuffer *gpuCommandBuffer);
void cmdFuncCCVKDestroyQueryPool(CCVKGPUDevice *device, CCVKGPUQueryPool *gpuQueryPool);
void cmdFuncCCVKDestroyRenderPass(CCVKGPUDevice *device, CCVKGPURenderPass *gpuRenderPass);
void cmdFuncCCVKDestroySampler(CCVKGPUDevice *device, CCVKGPUSampler *gpuSampler);
void cmdFuncCCVKDestroyShader(CCVKGPUDevice *device, CCVKGPUShader *gpuShader);
void cmdFuncCCVKDestroyFramebuffer(CCVKGPUDevice *device, CCVKGPUFramebuffer *gpuFramebuffer);
void cmdFuncCCVKDestroyDescriptorSetLayout(CCVKGPUDevice *device, CCVKGPUDescriptorSetLayout *gpuDescriptorSetLayout);
void cmdFuncCCVKDestroyPipelineLayout(CCVKGPUDevice *device, CCVKGPUPipelineLayout *gpuPipelineLayout);
void cmdFuncCCVKDestroyPipelineState(CCVKGPUDevice *device, CCVKGPUPipelineState *gpuPipelineState);
void cmdFuncCCVKImageMemoryBarrier(const CCVKGPUCommandBuffer *gpuCommandBuffer, const ThsvsImageBarrier &imageBarrier);
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,301 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "VKDescriptorSet.h"
#include "VKBuffer.h"
#include "VKCommands.h"
#include "VKDescriptorSetLayout.h"
#include "VKDevice.h"
#include "VKPipelineLayout.h"
#include "VKShader.h"
#include "VKTexture.h"
#include "states/VKSampler.h"
namespace cc {
namespace gfx {
CCVKDescriptorSet::CCVKDescriptorSet() {
_typedID = generateObjectID<decltype(this)>();
}
CCVKDescriptorSet::~CCVKDescriptorSet() {
destroy();
}
void CCVKDescriptorSet::doInit(const DescriptorSetInfo & /*info*/) {
CCVKGPUDescriptorSetLayout *gpuDescriptorSetLayout = static_cast<const CCVKDescriptorSetLayout *>(_layout)->gpuDescriptorSetLayout();
uint32_t bindingCount = utils::toUint(gpuDescriptorSetLayout->bindings.size());
uint32_t descriptorCount = gpuDescriptorSetLayout->descriptorCount;
_gpuDescriptorSet = ccnew CCVKGPUDescriptorSet;
_gpuDescriptorSet->gpuDescriptors.resize(descriptorCount, {});
_gpuDescriptorSet->layoutID = gpuDescriptorSetLayout->id;
for (size_t i = 0U, k = 0U; i < bindingCount; ++i) {
const DescriptorSetLayoutBinding &binding = gpuDescriptorSetLayout->bindings[i];
for (uint32_t j = 0; j < binding.count; ++j, ++k) {
CCVKGPUDescriptor &gpuDescriptor = _gpuDescriptorSet->gpuDescriptors[k];
gpuDescriptor.type = binding.descriptorType;
switch (binding.descriptorType) {
case DescriptorType::UNIFORM_BUFFER:
case DescriptorType::DYNAMIC_UNIFORM_BUFFER:
if (hasFlag(binding.stageFlags, ShaderStageFlags::COMPUTE)) gpuDescriptor.accessTypes.push_back(THSVS_ACCESS_COMPUTE_SHADER_READ_UNIFORM_BUFFER);
if (hasFlag(binding.stageFlags, ShaderStageFlags::VERTEX)) gpuDescriptor.accessTypes.push_back(THSVS_ACCESS_VERTEX_SHADER_READ_UNIFORM_BUFFER);
if (hasFlag(binding.stageFlags, ShaderStageFlags::FRAGMENT)) gpuDescriptor.accessTypes.push_back(THSVS_ACCESS_FRAGMENT_SHADER_READ_UNIFORM_BUFFER);
break;
case DescriptorType::STORAGE_BUFFER:
case DescriptorType::DYNAMIC_STORAGE_BUFFER:
case DescriptorType::STORAGE_IMAGE:
// write accesses should be handled manually
if (hasFlag(binding.stageFlags, ShaderStageFlags::COMPUTE)) gpuDescriptor.accessTypes.push_back(THSVS_ACCESS_COMPUTE_SHADER_READ_OTHER);
if (hasFlag(binding.stageFlags, ShaderStageFlags::VERTEX)) gpuDescriptor.accessTypes.push_back(THSVS_ACCESS_VERTEX_SHADER_READ_OTHER);
if (hasFlag(binding.stageFlags, ShaderStageFlags::FRAGMENT)) gpuDescriptor.accessTypes.push_back(THSVS_ACCESS_FRAGMENT_SHADER_READ_OTHER);
break;
case DescriptorType::SAMPLER_TEXTURE:
case DescriptorType::TEXTURE:
if (hasFlag(binding.stageFlags, ShaderStageFlags::COMPUTE)) gpuDescriptor.accessTypes.push_back(THSVS_ACCESS_COMPUTE_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER);
if (hasFlag(binding.stageFlags, ShaderStageFlags::VERTEX)) gpuDescriptor.accessTypes.push_back(THSVS_ACCESS_VERTEX_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER);
if (hasFlag(binding.stageFlags, ShaderStageFlags::FRAGMENT)) gpuDescriptor.accessTypes.push_back(THSVS_ACCESS_FRAGMENT_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER);
break;
case DescriptorType::INPUT_ATTACHMENT:
gpuDescriptor.accessTypes.push_back(THSVS_ACCESS_FRAGMENT_SHADER_READ_COLOR_INPUT_ATTACHMENT);
break;
case DescriptorType::SAMPLER:
default:
break;
}
}
}
CCVKGPUDevice *gpuDevice = CCVKDevice::getInstance()->gpuDevice();
_gpuDescriptorSet->gpuLayout = gpuDescriptorSetLayout;
_gpuDescriptorSet->instances.resize(gpuDevice->backBufferCount);
for (uint32_t t = 0U; t < gpuDevice->backBufferCount; ++t) {
CCVKGPUDescriptorSet::Instance &instance = _gpuDescriptorSet->instances[t];
instance.vkDescriptorSet = gpuDevice->getDescriptorSetPool(_gpuDescriptorSet->layoutID)->request();
instance.descriptorInfos.resize(descriptorCount, {});
for (uint32_t i = 0U, k = 0U; i < bindingCount; ++i) {
const DescriptorSetLayoutBinding &binding = gpuDescriptorSetLayout->bindings[i];
for (uint32_t j = 0; j < binding.count; ++j, ++k) {
if (hasFlag(DESCRIPTOR_BUFFER_TYPE, binding.descriptorType)) {
instance.descriptorInfos[k].buffer.buffer = gpuDevice->defaultBuffer->vkBuffer;
instance.descriptorInfos[k].buffer.offset = gpuDevice->defaultBuffer->getStartOffset(t);
instance.descriptorInfos[k].buffer.range = gpuDevice->defaultBuffer->size;
} else if (hasFlag(DESCRIPTOR_TEXTURE_TYPE, binding.descriptorType)) {
instance.descriptorInfos[k].image.sampler = gpuDevice->defaultSampler->vkSampler;
instance.descriptorInfos[k].image.imageView = gpuDevice->defaultTextureView->vkImageView;
instance.descriptorInfos[k].image.imageLayout = hasFlag(binding.descriptorType, DescriptorType::STORAGE_IMAGE)
? VK_IMAGE_LAYOUT_GENERAL
: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
}
}
}
if (!gpuDevice->useDescriptorUpdateTemplate) {
ccstd::vector<VkWriteDescriptorSet> &entries = instance.descriptorUpdateEntries;
entries.resize(descriptorCount, {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET});
for (uint32_t i = 0U, j = 0U; i < bindingCount; i++) {
const VkDescriptorSetLayoutBinding &descriptor = gpuDescriptorSetLayout->vkBindings[i];
for (uint32_t k = 0U; k < descriptor.descriptorCount; k++, j++) {
entries[j].dstSet = instance.vkDescriptorSet;
entries[j].dstBinding = descriptor.binding;
entries[j].dstArrayElement = k;
entries[j].descriptorCount = 1; // better not to assume that the descriptor infos would be contiguous
entries[j].descriptorType = descriptor.descriptorType;
switch (entries[j].descriptorType) {
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
entries[j].pBufferInfo = &instance.descriptorInfos[j].buffer;
break;
case VK_DESCRIPTOR_TYPE_SAMPLER:
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
entries[j].pImageInfo = &instance.descriptorInfos[j].image;
break;
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
entries[j].pTexelBufferView = &instance.descriptorInfos[j].texelBufferView;
break;
default: break;
}
}
}
}
}
}
void CCVKDescriptorSet::doDestroy() {
_gpuDescriptorSet = nullptr;
}
void CCVKDescriptorSet::update() {
if (_isDirty && _gpuDescriptorSet) {
CCVKGPUDescriptorHub *descriptorHub = CCVKDevice::getInstance()->gpuDescriptorHub();
CCVKGPUBarrierManager *layoutMgr = CCVKDevice::getInstance()->gpuBarrierManager();
uint32_t descriptorCount = utils::toUint(_gpuDescriptorSet->gpuDescriptors.size());
uint32_t instanceCount = utils::toUint(_gpuDescriptorSet->instances.size());
for (size_t i = 0U; i < descriptorCount; i++) {
CCVKGPUDescriptor &binding = _gpuDescriptorSet->gpuDescriptors[i];
if (hasFlag(DESCRIPTOR_BUFFER_TYPE, binding.type)) {
if (_buffers[i].ptr) {
CCVKGPUBufferView *bufferView = static_cast<CCVKBuffer *>(_buffers[i].ptr)->gpuBufferView();
for (uint32_t t = 0U; t < instanceCount; ++t) {
CCVKDescriptorInfo &descriptorInfo = _gpuDescriptorSet->instances[t].descriptorInfos[i];
if (binding.gpuBufferView) {
descriptorHub->disengage(_gpuDescriptorSet, binding.gpuBufferView, &descriptorInfo.buffer);
}
if (bufferView) {
descriptorHub->connect(_gpuDescriptorSet, bufferView, &descriptorInfo.buffer, t);
descriptorHub->update(bufferView, &descriptorInfo.buffer);
}
binding.gpuBufferView = bufferView;
}
}
} else if (hasFlag(DESCRIPTOR_TEXTURE_TYPE, binding.type)) {
if (_textures[i].ptr) {
CCVKGPUTextureView *textureView = static_cast<CCVKTexture *>(_textures[i].ptr)->gpuTextureView();
for (auto &instance : _gpuDescriptorSet->instances) {
CCVKDescriptorInfo &descriptorInfo = instance.descriptorInfos[i];
if (binding.gpuTextureView) {
descriptorHub->disengage(_gpuDescriptorSet, binding.gpuTextureView, &descriptorInfo.image);
}
if (textureView) {
descriptorHub->connect(_gpuDescriptorSet, textureView, &descriptorInfo.image);
descriptorHub->update(textureView, &descriptorInfo.image, _textures[i].flags);
layoutMgr->checkIn(textureView->gpuTexture, binding.accessTypes.data(), utils::toUint(binding.accessTypes.size()));
}
}
binding.gpuTextureView = textureView;
}
if (_samplers[i].ptr) {
CCVKGPUSampler *sampler = static_cast<CCVKSampler *>(_samplers[i].ptr)->gpuSampler();
for (auto &instance : _gpuDescriptorSet->instances) {
CCVKDescriptorInfo &descriptorInfo = instance.descriptorInfos[i];
if (binding.gpuSampler) {
descriptorHub->disengage(binding.gpuSampler, &descriptorInfo.image);
}
if (sampler) {
descriptorHub->connect(sampler, &descriptorInfo.image);
descriptorHub->update(sampler, &descriptorInfo.image);
}
}
binding.gpuSampler = sampler;
}
}
}
CCVKDevice::getInstance()->gpuDescriptorSetHub()->record(_gpuDescriptorSet);
_isDirty = false;
}
}
void CCVKDescriptorSet::forceUpdate() {
_isDirty = true;
update();
}
void CCVKGPUDescriptorSet::shutdown() {
CCVKDevice *device = CCVKDevice::getInstance();
CCVKGPUDescriptorHub *descriptorHub = CCVKDevice::getInstance()->gpuDescriptorHub();
uint32_t instanceCount = utils::toUint(instances.size());
for (uint32_t t = 0U; t < instanceCount; ++t) {
CCVKGPUDescriptorSet::Instance &instance = instances[t];
for (uint32_t i = 0U; i < gpuDescriptors.size(); i++) {
CCVKGPUDescriptor &binding = gpuDescriptors[i];
CCVKDescriptorInfo &descriptorInfo = instance.descriptorInfos[i];
if (binding.gpuBufferView) {
descriptorHub->disengage(this, binding.gpuBufferView, &descriptorInfo.buffer);
}
if (binding.gpuTextureView) {
descriptorHub->disengage(this, binding.gpuTextureView, &descriptorInfo.image);
}
if (binding.gpuSampler) {
descriptorHub->disengage(binding.gpuSampler, &descriptorInfo.image);
}
}
if (instance.vkDescriptorSet) {
device->gpuRecycleBin()->collect(layoutID, instance.vkDescriptorSet);
}
}
CCVKDevice::getInstance()->gpuDescriptorSetHub()->erase(this);
}
void CCVKGPUDescriptorSet::update(const CCVKGPUBufferView *oldView, const CCVKGPUBufferView *newView) {
CCVKGPUDescriptorHub *descriptorHub = CCVKDevice::getInstance()->gpuDescriptorHub();
uint32_t instanceCount = utils::toUint(instances.size());
for (size_t i = 0U; i < gpuDescriptors.size(); i++) {
CCVKGPUDescriptor &binding = gpuDescriptors[i];
if (hasFlag(DESCRIPTOR_BUFFER_TYPE, binding.type) && (binding.gpuBufferView == oldView)) {
for (uint32_t t = 0U; t < instanceCount; ++t) {
CCVKDescriptorInfo &descriptorInfo = instances[t].descriptorInfos[i];
if (newView != nullptr) {
descriptorHub->connect(this, newView, &descriptorInfo.buffer, t);
descriptorHub->update(newView, &descriptorInfo.buffer);
}
}
binding.gpuBufferView = newView;
}
}
CCVKDevice::getInstance()->gpuDescriptorSetHub()->record(this);
}
void CCVKGPUDescriptorSet::update(const CCVKGPUTextureView *oldView, const CCVKGPUTextureView *newView) {
CCVKGPUDescriptorHub *descriptorHub = CCVKDevice::getInstance()->gpuDescriptorHub();
uint32_t instanceCount = utils::toUint(instances.size());
for (size_t i = 0U; i < gpuDescriptors.size(); i++) {
CCVKGPUDescriptor &binding = gpuDescriptors[i];
if (hasFlag(DESCRIPTOR_TEXTURE_TYPE, binding.type) && (binding.gpuTextureView == oldView)) {
for (uint32_t t = 0U; t < instanceCount; ++t) {
CCVKDescriptorInfo &descriptorInfo = instances[t].descriptorInfos[i];
if (newView != nullptr) {
descriptorHub->connect(this, newView, &descriptorInfo.image);
descriptorHub->update(newView, &descriptorInfo.image);
}
}
binding.gpuTextureView = newView;
}
}
CCVKDevice::getInstance()->gpuDescriptorSetHub()->record(this);
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,54 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "VKStd.h"
#include "gfx-base/GFXDescriptorSet.h"
#include "gfx-vulkan/VKGPUObjects.h"
namespace cc {
namespace gfx {
struct CCVKGPUDescriptorSet;
class CC_VULKAN_API CCVKDescriptorSet final : public DescriptorSet {
public:
CCVKDescriptorSet();
~CCVKDescriptorSet() override;
void update() override;
void forceUpdate() override;
inline CCVKGPUDescriptorSet *gpuDescriptorSet() const { return _gpuDescriptorSet; }
protected:
void doInit(const DescriptorSetInfo &info) override;
void doDestroy() override;
IntrusivePtr<CCVKGPUDescriptorSet> _gpuDescriptorSet;
};
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,72 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "VKDescriptorSetLayout.h"
#include "VKCommands.h"
#include "VKDevice.h"
namespace cc {
namespace gfx {
CCVKDescriptorSetLayout::CCVKDescriptorSetLayout() {
_typedID = generateObjectID<decltype(this)>();
}
CCVKDescriptorSetLayout::~CCVKDescriptorSetLayout() {
destroy();
}
void CCVKDescriptorSetLayout::doInit(const DescriptorSetLayoutInfo & /*info*/) {
_gpuDescriptorSetLayout = ccnew CCVKGPUDescriptorSetLayout;
_gpuDescriptorSetLayout->id = generateID();
_gpuDescriptorSetLayout->descriptorCount = _descriptorCount;
_gpuDescriptorSetLayout->bindingIndices = _bindingIndices;
_gpuDescriptorSetLayout->descriptorIndices = _descriptorIndices;
_gpuDescriptorSetLayout->bindings = _bindings;
for (auto &binding : _bindings) {
if (hasAnyFlags(binding.descriptorType, DESCRIPTOR_DYNAMIC_TYPE)) {
for (uint32_t j = 0U; j < binding.count; j++) {
_gpuDescriptorSetLayout->dynamicBindings.push_back(binding.binding);
}
}
}
cmdFuncCCVKCreateDescriptorSetLayout(CCVKDevice::getInstance(), _gpuDescriptorSetLayout);
}
void CCVKDescriptorSetLayout::doDestroy() {
_gpuDescriptorSetLayout = nullptr;
}
void CCVKGPUDescriptorSetLayout::shutdown() {
if (defaultDescriptorSet != VK_NULL_HANDLE) {
CCVKDevice::getInstance()->gpuRecycleBin()->collect(id, defaultDescriptorSet);
}
cmdFuncCCVKDestroyDescriptorSetLayout(CCVKDevice::getInstance()->gpuDevice(), this);
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,54 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "VKStd.h"
#include "gfx-base/GFXDescriptorSetLayout.h"
#include "gfx-vulkan/VKGPUObjects.h"
namespace cc {
namespace gfx {
class CC_VULKAN_API CCVKDescriptorSetLayout final : public DescriptorSetLayout {
public:
CCVKDescriptorSetLayout();
~CCVKDescriptorSetLayout() override;
inline CCVKGPUDescriptorSetLayout *gpuDescriptorSetLayout() const { return _gpuDescriptorSetLayout; }
protected:
static uint32_t generateID() noexcept {
static uint32_t idGen = 10000;
return idGen++;
}
void doInit(const DescriptorSetLayoutInfo &info) override;
void doDestroy() override;
IntrusivePtr<CCVKGPUDescriptorSetLayout> _gpuDescriptorSetLayout;
};
} // namespace gfx
} // namespace cc

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,169 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include <cstring>
#include <memory>
#include "VKStd.h"
#include "gfx-base/GFXDevice.h"
namespace cc {
class IXRInterface;
namespace gfx {
class CCVKTexture;
class CCVKGPUDevice;
class CCVKGPUContext;
class CCVKGPUBufferHub;
class CCVKGPUTransportHub;
class CCVKGPUDescriptorHub;
class CCVKGPUSemaphorePool;
class CCVKGPUBarrierManager;
class CCVKGPUDescriptorSetHub;
class CCVKGPUInputAssemblerHub;
class CCVKPipelineCache;
class CCVKGPUFencePool;
class CCVKGPURecycleBin;
class CCVKGPUStagingBufferPool;
class CC_VULKAN_API CCVKDevice final : public Device {
public:
static CCVKDevice *getInstance();
~CCVKDevice() override;
friend class CCVKContext;
using Device::copyBuffersToTexture;
using Device::createBuffer;
using Device::createBufferBarrier;
using Device::createCommandBuffer;
using Device::createDescriptorSet;
using Device::createDescriptorSetLayout;
using Device::createFramebuffer;
using Device::createGeneralBarrier;
using Device::createInputAssembler;
using Device::createPipelineLayout;
using Device::createPipelineState;
using Device::createQueryPool;
using Device::createQueue;
using Device::createRenderPass;
using Device::createSampler;
using Device::createShader;
using Device::createTexture;
using Device::createTextureBarrier;
void frameSync() override;
void acquire(Swapchain *const *swapchains, uint32_t count) override;
void present() override;
inline bool checkExtension(const ccstd::string &extension) const {
return std::any_of(_extensions.begin(), _extensions.end(), [&extension](auto &ext) {
return std::strcmp(ext, extension.c_str()) == 0;
});
}
inline CCVKGPUDevice *gpuDevice() const { return _gpuDevice.get(); }
inline CCVKGPUContext *gpuContext() { return _gpuContext.get(); }
inline CCVKGPUBufferHub *gpuBufferHub() const { return _gpuBufferHub.get(); }
inline CCVKGPUTransportHub *gpuTransportHub() const { return _gpuTransportHub.get(); }
inline CCVKGPUDescriptorHub *gpuDescriptorHub() const { return _gpuDescriptorHub.get(); }
inline CCVKGPUSemaphorePool *gpuSemaphorePool() const { return _gpuSemaphorePool.get(); }
inline CCVKGPUBarrierManager *gpuBarrierManager() const { return _gpuBarrierManager.get(); }
inline CCVKGPUDescriptorSetHub *gpuDescriptorSetHub() const { return _gpuDescriptorSetHub.get(); }
inline CCVKGPUInputAssemblerHub *gpuIAHub() const { return _gpuIAHub.get(); }
inline CCVKPipelineCache *pipelineCache() const { return _pipelineCache.get(); }
CCVKGPUFencePool *gpuFencePool();
CCVKGPURecycleBin *gpuRecycleBin();
CCVKGPUStagingBufferPool *gpuStagingBufferPool();
void waitAllFences();
void updateBackBufferCount(uint32_t backBufferCount);
SampleCount getMaxSampleCount(Format format, TextureUsage usage, TextureFlags flags) const override;
protected:
static CCVKDevice *instance;
friend class DeviceManager;
CCVKDevice();
bool doInit(const DeviceInfo &info) override;
void doDestroy() override;
CommandBuffer *createCommandBuffer(const CommandBufferInfo &info, bool hasAgent) override;
Queue *createQueue() override;
QueryPool *createQueryPool() override;
Swapchain *createSwapchain() override;
Buffer *createBuffer() override;
Texture *createTexture() override;
Shader *createShader() override;
InputAssembler *createInputAssembler() override;
RenderPass *createRenderPass() override;
Framebuffer *createFramebuffer() override;
DescriptorSet *createDescriptorSet() override;
DescriptorSetLayout *createDescriptorSetLayout() override;
PipelineLayout *createPipelineLayout() override;
PipelineState *createPipelineState() override;
Sampler *createSampler(const SamplerInfo &info) override;
GeneralBarrier *createGeneralBarrier(const GeneralBarrierInfo &info) override;
TextureBarrier *createTextureBarrier(const TextureBarrierInfo &info) override;
BufferBarrier *createBufferBarrier(const BufferBarrierInfo &info) override;
void copyBuffersToTexture(const uint8_t *const *buffers, Texture *dst, const BufferTextureCopy *regions, uint32_t count) override;
void copyTextureToBuffers(Texture *src, uint8_t *const *buffers, const BufferTextureCopy *region, uint32_t count) override;
void getQueryPoolResults(QueryPool *queryPool) override;
void initFormatFeature();
void initDeviceFeature();
void initExtensionCapability();
std::unique_ptr<CCVKGPUDevice> _gpuDevice;
std::unique_ptr<CCVKGPUContext> _gpuContext;
ccstd::vector<std::unique_ptr<CCVKGPUFencePool>> _gpuFencePools;
ccstd::vector<std::unique_ptr<CCVKGPURecycleBin>> _gpuRecycleBins;
ccstd::vector<std::unique_ptr<CCVKGPUStagingBufferPool>> _gpuStagingBufferPools;
std::unique_ptr<CCVKGPUBufferHub> _gpuBufferHub;
std::unique_ptr<CCVKGPUTransportHub> _gpuTransportHub;
std::unique_ptr<CCVKGPUDescriptorHub> _gpuDescriptorHub;
std::unique_ptr<CCVKGPUSemaphorePool> _gpuSemaphorePool;
std::unique_ptr<CCVKGPUBarrierManager> _gpuBarrierManager;
std::unique_ptr<CCVKGPUDescriptorSetHub> _gpuDescriptorSetHub;
std::unique_ptr<CCVKGPUInputAssemblerHub> _gpuIAHub;
std::unique_ptr<CCVKPipelineCache> _pipelineCache;
ccstd::vector<const char *> _layers;
ccstd::vector<const char *> _extensions;
IXRInterface *_xr{nullptr};
};
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,74 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "VKFramebuffer.h"
#include "VKCommands.h"
#include "VKDevice.h"
#include "VKRenderPass.h"
#include "VKTexture.h"
namespace cc {
namespace gfx {
CCVKFramebuffer::CCVKFramebuffer() {
_typedID = generateObjectID<decltype(this)>();
}
CCVKFramebuffer::~CCVKFramebuffer() {
destroy();
}
void CCVKFramebuffer::doInit(const FramebufferInfo & /*info*/) {
_gpuFBO = ccnew CCVKGPUFramebuffer;
_gpuFBO->gpuRenderPass = static_cast<CCVKRenderPass *>(_renderPass)->gpuRenderPass();
_gpuFBO->gpuColorViews.resize(_colorTextures.size());
for (size_t i = 0; i < _colorTextures.size(); ++i) {
auto *colorTex = static_cast<CCVKTexture *>(_colorTextures.at(i));
_gpuFBO->gpuColorViews[i] = colorTex->gpuTextureView();
}
if (_depthStencilTexture) {
auto *depthTex = static_cast<CCVKTexture *>(_depthStencilTexture);
_gpuFBO->gpuDepthStencilView = depthTex->gpuTextureView();
}
if (_depthStencilResolveTexture) {
auto *depthTex = static_cast<CCVKTexture *>(_depthStencilResolveTexture);
_gpuFBO->gpuDepthStencilResolveView = depthTex->gpuTextureView();
}
cmdFuncCCVKCreateFramebuffer(CCVKDevice::getInstance(), _gpuFBO);
}
void CCVKFramebuffer::doDestroy() {
_gpuFBO = nullptr;
}
void CCVKGPUFramebuffer::shutdown() {
CCVKDevice::getInstance()->gpuRecycleBin()->collect(this);
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,49 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "VKStd.h"
#include "gfx-base/GFXFramebuffer.h"
#include "gfx-vulkan/VKGPUObjects.h"
namespace cc {
namespace gfx {
class CC_VULKAN_API CCVKFramebuffer final : public Framebuffer {
public:
CCVKFramebuffer();
~CCVKFramebuffer() override;
inline CCVKGPUFramebuffer *gpuFBO() const { return _gpuFBO; }
protected:
void doInit(const FramebufferInfo &info) override;
void doDestroy() override;
IntrusivePtr<CCVKGPUFramebuffer> _gpuFBO;
};
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,365 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "VKGPUObjects.h"
#include "application/ApplicationManager.h"
#include "platform/interfaces/modules/IXRInterface.h"
namespace cc {
namespace gfx {
namespace {
constexpr uint32_t FORCE_MINOR_VERSION = 0; // 0 for default version, otherwise minorVersion = (FORCE_MINOR_VERSION - 1)
#define FORCE_ENABLE_VALIDATION 0
#define FORCE_DISABLE_VALIDATION 1
using ccstd::vector;
#if CC_DEBUG > 0 && !FORCE_DISABLE_VALIDATION || FORCE_ENABLE_VALIDATION
constexpr uint32_t DISABLE_VALIDATION_ASSERTIONS = 1; // 0 for default behavior, otherwise assertions will be disabled
VKAPI_ATTR VkBool32 VKAPI_CALL debugUtilsMessengerCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT /*messageType*/,
const VkDebugUtilsMessengerCallbackDataEXT *callbackData,
void * /*userData*/) {
if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) {
CC_LOG_ERROR("%s: %s", callbackData->pMessageIdName, callbackData->pMessage);
CC_ASSERT(DISABLE_VALIDATION_ASSERTIONS);
return VK_FALSE;
}
if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) {
CC_LOG_WARNING("%s: %s", callbackData->pMessageIdName, callbackData->pMessage);
return VK_FALSE;
}
if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) {
// CC_LOG_INFO("%s: %s", callbackData->pMessageIdName, callbackData->pMessage);
return VK_FALSE;
}
if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) {
// CC_LOG_DEBUG("%s: %s", callbackData->pMessageIdName, callbackData->pMessage);
return VK_FALSE;
}
CC_LOG_ERROR("%s: %s", callbackData->pMessageIdName, callbackData->pMessage);
return VK_FALSE;
}
VKAPI_ATTR VkBool32 VKAPI_CALL debugReportCallback(VkDebugReportFlagsEXT flags,
VkDebugReportObjectTypeEXT /*type*/,
uint64_t /*object*/,
size_t /*location*/,
int32_t /*messageCode*/,
const char *layerPrefix,
const char *message,
void * /*userData*/) {
if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
CC_LOG_ERROR("%s: %s", layerPrefix, message);
CC_ASSERT(DISABLE_VALIDATION_ASSERTIONS);
return VK_FALSE;
}
if (flags & (VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT)) {
CC_LOG_WARNING("%s: %s", layerPrefix, message);
return VK_FALSE;
}
if (flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) {
// CC_LOG_INFO("%s: %s", layerPrefix, message);
return VK_FALSE;
}
if (flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) {
// CC_LOG_DEBUG("%s: %s", layerPrefix, message);
return VK_FALSE;
}
CC_LOG_ERROR("%s: %s", layerPrefix, message);
return VK_FALSE;
}
#endif
} // namespace
bool CCVKGPUContext::initialize() {
// only enable the absolute essentials
ccstd::vector<const char *> requestedLayers{
//"VK_LAYER_KHRONOS_synchronization2",
};
ccstd::vector<const char *> requestedExtensions{
VK_KHR_SURFACE_EXTENSION_NAME,
};
///////////////////// Instance Creation /////////////////////
if (volkInitialize()) {
return false;
}
uint32_t apiVersion = VK_API_VERSION_1_0;
if (vkEnumerateInstanceVersion) {
vkEnumerateInstanceVersion(&apiVersion);
if (FORCE_MINOR_VERSION) {
apiVersion = VK_MAKE_VERSION(1, FORCE_MINOR_VERSION - 1, 0);
}
}
IXRInterface *xr = CC_GET_XR_INTERFACE();
if (xr) apiVersion = xr->getXRVkApiVersion(apiVersion);
minorVersion = VK_VERSION_MINOR(apiVersion);
if (minorVersion < 1) {
requestedExtensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
}
uint32_t availableLayerCount;
VK_CHECK(vkEnumerateInstanceLayerProperties(&availableLayerCount, nullptr));
ccstd::vector<VkLayerProperties> supportedLayers(availableLayerCount);
VK_CHECK(vkEnumerateInstanceLayerProperties(&availableLayerCount, supportedLayers.data()));
uint32_t availableExtensionCount;
VK_CHECK(vkEnumerateInstanceExtensionProperties(nullptr, &availableExtensionCount, nullptr));
ccstd::vector<VkExtensionProperties> supportedExtensions(availableExtensionCount);
VK_CHECK(vkEnumerateInstanceExtensionProperties(nullptr, &availableExtensionCount, supportedExtensions.data()));
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
requestedExtensions.push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME);
#elif defined(VK_USE_PLATFORM_WIN32_KHR)
requestedExtensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
#elif defined(VK_USE_PLATFORM_VI_NN)
requestedExtensions.push_back(VK_NN_VI_SURFACE_EXTENSION_NAME);
#elif defined(VK_USE_PLATFORM_MACOS_MVK)
requestedExtensions.push_back(VK_MVK_MACOS_SURFACE_EXTENSION_NAME);
if (minorVersion >= 3) {
requestedExtensions.push_back("VK_KHR_portability_enumeration");
requestedExtensions.push_back("VK_KHR_portability_subset");
}
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
requestedExtensions.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
#elif defined(VK_USE_PLATFORM_XCB_KHR)
requestedExtensions.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
#else
#pragma error Platform not supported
#endif
#if CC_DEBUG > 0 && !FORCE_DISABLE_VALIDATION || FORCE_ENABLE_VALIDATION
// Determine the optimal validation layers to enable that are necessary for useful debugging
ccstd::vector<ccstd::vector<const char *>> validationLayerPriorityList{
// The preferred validation layer is "VK_LAYER_KHRONOS_validation"
{"VK_LAYER_KHRONOS_validation"},
// Otherwise we fallback to using the LunarG meta layer
{"VK_LAYER_LUNARG_standard_validation"},
// Otherwise we attempt to enable the individual layers that compose the LunarG meta layer since it doesn't exist
{
"VK_LAYER_GOOGLE_threading",
"VK_LAYER_LUNARG_parameter_validation",
"VK_LAYER_LUNARG_object_tracker",
"VK_LAYER_LUNARG_core_validation",
"VK_LAYER_GOOGLE_unique_objects",
},
// Otherwise as a last resort we fallback to attempting to enable the LunarG core layer
{"VK_LAYER_LUNARG_core_validation"},
};
for (ccstd::vector<const char *> &validationLayers : validationLayerPriorityList) {
bool found = true;
for (const char *layer : validationLayers) {
if (!isLayerSupported(layer, supportedLayers)) {
found = false;
break;
}
}
if (found) {
requestedLayers.insert(requestedLayers.end(), validationLayers.begin(), validationLayers.end());
break;
}
}
#endif
#if CC_DEBUG
// Check if VK_EXT_debug_utils is supported, which supersedes VK_EXT_Debug_Report
bool debugUtils = false;
if (isExtensionSupported(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, supportedExtensions)) {
debugUtils = true;
requestedExtensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
} else {
requestedExtensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
}
#endif
// just filter out the unsupported layers & extensions
for (const char *layer : requestedLayers) {
if (isLayerSupported(layer, supportedLayers)) {
layers.push_back(layer);
}
}
for (const char *extension : requestedExtensions) {
if (isExtensionSupported(extension, supportedExtensions)) {
extensions.push_back(extension);
}
}
VkApplicationInfo app{VK_STRUCTURE_TYPE_APPLICATION_INFO};
app.pEngineName = "Cocos Creator";
app.apiVersion = apiVersion;
VkInstanceCreateInfo instanceInfo{VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO};
#if defined(VK_USE_PLATFORM_MACOS_MVK)
if (minorVersion >= 3) {
instanceInfo.flags |= 0x01; // VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
}
#endif
instanceInfo.pApplicationInfo = &app;
instanceInfo.enabledExtensionCount = utils::toUint(extensions.size());
instanceInfo.ppEnabledExtensionNames = extensions.data();
instanceInfo.enabledLayerCount = utils::toUint(layers.size());
instanceInfo.ppEnabledLayerNames = layers.data();
#if CC_DEBUG > 0 && !FORCE_DISABLE_VALIDATION || FORCE_ENABLE_VALIDATION
VkDebugUtilsMessengerCreateInfoEXT debugUtilsCreateInfo{VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT};
VkDebugReportCallbackCreateInfoEXT debugReportCreateInfo{VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT};
if (debugUtils) {
debugUtilsCreateInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT;
debugUtilsCreateInfo.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
debugUtilsCreateInfo.pfnUserCallback = debugUtilsMessengerCallback;
instanceInfo.pNext = &debugUtilsCreateInfo;
} else {
debugReportCreateInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT |
VK_DEBUG_REPORT_WARNING_BIT_EXT |
VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT |
VK_DEBUG_REPORT_INFORMATION_BIT_EXT |
VK_DEBUG_REPORT_DEBUG_BIT_EXT;
debugReportCreateInfo.pfnCallback = debugReportCallback;
instanceInfo.pNext = &debugReportCreateInfo;
}
#endif
// Create the Vulkan instance
if (xr) {
xr->initializeVulkanData(vkGetInstanceProcAddr);
vkInstance = xr->createXRVulkanInstance(instanceInfo);
} else {
VkResult res = vkCreateInstance(&instanceInfo, nullptr, &vkInstance);
if (res == VK_ERROR_LAYER_NOT_PRESENT) {
CC_LOG_ERROR("Create Vulkan instance failed due to missing layers, aborting...");
return false;
}
}
volkLoadInstanceOnly(vkInstance);
#if CC_DEBUG > 0 && !FORCE_DISABLE_VALIDATION || FORCE_ENABLE_VALIDATION
if (debugUtils) {
VK_CHECK(vkCreateDebugUtilsMessengerEXT(vkInstance, &debugUtilsCreateInfo, nullptr, &vkDebugUtilsMessenger));
} else {
VK_CHECK(vkCreateDebugReportCallbackEXT(vkInstance, &debugReportCreateInfo, nullptr, &vkDebugReport));
}
validationEnabled = true;
#endif
///////////////////// Physical Device Selection /////////////////////
// Querying valid physical devices on the machine
uint32_t physicalDeviceCount{0};
VkResult res = vkEnumeratePhysicalDevices(vkInstance, &physicalDeviceCount, nullptr);
if (res || physicalDeviceCount < 1) {
return false;
}
ccstd::vector<VkPhysicalDevice> physicalDeviceHandles(physicalDeviceCount);
if (xr) {
physicalDeviceHandles[0] = xr->getXRVulkanGraphicsDevice();
} else {
VK_CHECK(vkEnumeratePhysicalDevices(vkInstance, &physicalDeviceCount, physicalDeviceHandles.data()));
}
ccstd::vector<VkPhysicalDeviceProperties> physicalDevicePropertiesList(physicalDeviceCount);
uint32_t deviceIndex;
for (deviceIndex = 0U; deviceIndex < physicalDeviceCount; ++deviceIndex) {
VkPhysicalDeviceProperties &properties = physicalDevicePropertiesList[deviceIndex];
vkGetPhysicalDeviceProperties(physicalDeviceHandles[deviceIndex], &properties);
}
for (deviceIndex = 0U; deviceIndex < physicalDeviceCount; ++deviceIndex) {
VkPhysicalDeviceProperties &properties = physicalDevicePropertiesList[deviceIndex];
if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) {
break;
}
}
if (deviceIndex == physicalDeviceCount) {
deviceIndex = 0;
}
physicalDevice = physicalDeviceHandles[deviceIndex];
physicalDeviceProperties = physicalDevicePropertiesList[deviceIndex];
vkGetPhysicalDeviceFeatures(physicalDevice, &physicalDeviceFeatures);
majorVersion = VK_VERSION_MAJOR(physicalDeviceProperties.apiVersion);
minorVersion = VK_VERSION_MINOR(physicalDeviceProperties.apiVersion);
if (minorVersion >= 1 || checkExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
physicalDeviceFeatures2.pNext = &physicalDeviceVulkan11Features;
physicalDeviceVulkan11Features.pNext = &physicalDeviceVulkan12Features;
physicalDeviceVulkan12Features.pNext = &physicalDeviceFragmentShadingRateFeatures;
physicalDeviceProperties2.pNext = &physicalDeviceDepthStencilResolveProperties;
if (minorVersion >= 1) {
vkGetPhysicalDeviceProperties2(physicalDevice, &physicalDeviceProperties2);
vkGetPhysicalDeviceFeatures2(physicalDevice, &physicalDeviceFeatures2);
} else {
vkGetPhysicalDeviceProperties2KHR(physicalDevice, &physicalDeviceProperties2);
vkGetPhysicalDeviceFeatures2KHR(physicalDevice, &physicalDeviceFeatures2);
}
}
vkGetPhysicalDeviceMemoryProperties(physicalDevice, &physicalDeviceMemoryProperties);
uint32_t queueFamilyPropertiesCount = 0;
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyPropertiesCount, nullptr);
queueFamilyProperties.resize(queueFamilyPropertiesCount);
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyPropertiesCount, queueFamilyProperties.data());
return true;
}
void CCVKGPUContext::destroy() {
#if CC_DEBUG > 0 && !FORCE_DISABLE_VALIDATION || FORCE_ENABLE_VALIDATION
if (vkDebugUtilsMessenger != VK_NULL_HANDLE) {
vkDestroyDebugUtilsMessengerEXT(vkInstance, vkDebugUtilsMessenger, nullptr);
vkDebugUtilsMessenger = VK_NULL_HANDLE;
}
if (vkDebugReport != VK_NULL_HANDLE) {
vkDestroyDebugReportCallbackEXT(vkInstance, vkDebugReport, nullptr);
vkDebugReport = VK_NULL_HANDLE;
}
#endif
if (vkInstance != VK_NULL_HANDLE) {
vkDestroyInstance(vkInstance, nullptr);
vkInstance = VK_NULL_HANDLE;
}
}
} // namespace gfx
} // namespace cc

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,151 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "VKDevice.h"
#include "VKGPUObjects.h"
namespace cc {
namespace gfx {
void CCVKGPURecycleBin::collect(const cc::gfx::CCVKGPUTexture *texture) {
auto collectHandleFn = [this](VkImage image, VmaAllocation allocation) {
Resource &res = emplaceBack();
res.type = RecycledType::TEXTURE;
res.image.vkImage = image;
res.image.vmaAllocation = allocation;
};
collectHandleFn(texture->vkImage, texture->vmaAllocation);
if (texture->swapchain != nullptr) {
for (uint32_t i = 0; i < texture->swapchainVkImages.size() && i < texture->swapchainVmaAllocations.size(); ++i) {
collectHandleFn(texture->swapchainVkImages[i], texture->swapchainVmaAllocations[i]);
}
}
}
void CCVKGPURecycleBin::collect(const cc::gfx::CCVKGPUTextureView *textureView) {
auto collectHandleFn = [this](VkImageView view) {
Resource &res = emplaceBack();
res.type = RecycledType::TEXTURE_VIEW;
res.vkImageView = view;
};
collectHandleFn(textureView->vkImageView);
for (const auto &swapChainView : textureView->swapchainVkImageViews) {
collectHandleFn(swapChainView);
}
}
void CCVKGPURecycleBin::collect(const CCVKGPUFramebuffer *frameBuffer) {
auto collectHandleFn = [this](VkFramebuffer fbo) {
Resource &res = emplaceBack();
res.type = RecycledType::FRAMEBUFFER;
res.vkFramebuffer = fbo;
};
collectHandleFn(frameBuffer->vkFramebuffer);
for (const auto &fbo : frameBuffer->vkFrameBuffers) {
collectHandleFn(fbo);
}
}
void CCVKGPURecycleBin::collect(const CCVKGPUDescriptorSet *set) {
for (const auto &instance : set->instances) {
collect(set->layoutID, instance.vkDescriptorSet);
}
}
void CCVKGPURecycleBin::collect(uint32_t layoutId, VkDescriptorSet set) {
Resource &res = emplaceBack();
res.type = RecycledType::DESCRIPTOR_SET;
res.set.layoutId = layoutId;
res.set.vkSet = set;
}
void CCVKGPURecycleBin::collect(const CCVKGPUBuffer *buffer) {
Resource &res = emplaceBack();
res.type = RecycledType::BUFFER;
res.buffer.vkBuffer = buffer->vkBuffer;
res.buffer.vmaAllocation = buffer->vmaAllocation;
}
void CCVKGPURecycleBin::clear() {
for (uint32_t i = 0U; i < _count; ++i) {
Resource &res = _resources[i];
switch (res.type) {
case RecycledType::BUFFER:
if (res.buffer.vkBuffer != VK_NULL_HANDLE && res.buffer.vmaAllocation != VK_NULL_HANDLE) {
vmaDestroyBuffer(_device->memoryAllocator, res.buffer.vkBuffer, res.buffer.vmaAllocation);
res.buffer.vkBuffer = VK_NULL_HANDLE;
res.buffer.vmaAllocation = VK_NULL_HANDLE;
}
break;
case RecycledType::TEXTURE:
if (res.image.vkImage != VK_NULL_HANDLE && res.image.vmaAllocation != VK_NULL_HANDLE) {
vmaDestroyImage(_device->memoryAllocator, res.image.vkImage, res.image.vmaAllocation);
res.image.vkImage = VK_NULL_HANDLE;
res.image.vmaAllocation = VK_NULL_HANDLE;
}
break;
case RecycledType::TEXTURE_VIEW:
if (res.vkImageView != VK_NULL_HANDLE) {
vkDestroyImageView(_device->vkDevice, res.vkImageView, nullptr);
res.vkImageView = VK_NULL_HANDLE;
}
break;
case RecycledType::FRAMEBUFFER:
if (res.vkFramebuffer != VK_NULL_HANDLE) {
vkDestroyFramebuffer(_device->vkDevice, res.vkFramebuffer, nullptr);
res.vkFramebuffer = VK_NULL_HANDLE;
}
break;
case RecycledType::QUERY_POOL:
if (res.vkQueryPool != VK_NULL_HANDLE) {
vkDestroyQueryPool(_device->vkDevice, res.vkQueryPool, nullptr);
}
break;
case RecycledType::RENDER_PASS:
if (res.vkRenderPass != VK_NULL_HANDLE) {
vkDestroyRenderPass(_device->vkDevice, res.vkRenderPass, nullptr);
}
break;
case RecycledType::SAMPLER:
if (res.vkSampler != VK_NULL_HANDLE) {
vkDestroySampler(_device->vkDevice, res.vkSampler, nullptr);
}
break;
case RecycledType::PIPELINE_STATE:
if (res.vkPipeline != VK_NULL_HANDLE) {
vkDestroyPipeline(_device->vkDevice, res.vkPipeline, nullptr);
}
break;
case RecycledType::DESCRIPTOR_SET:
if (res.set.vkSet != VK_NULL_HANDLE) {
CCVKDevice::getInstance()->gpuDevice()->getDescriptorSetPool(res.set.layoutId)->yield(res.set.vkSet);
}
break;
default: break;
}
res.type = RecycledType::UNKNOWN;
}
_count = 0;
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,108 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "VKInputAssembler.h"
#include "VKBuffer.h"
#include "VKCommands.h"
#include "VKDevice.h"
namespace cc {
namespace gfx {
CCVKInputAssembler::CCVKInputAssembler() {
_typedID = generateObjectID<decltype(this)>();
}
CCVKInputAssembler::~CCVKInputAssembler() {
destroy();
}
void CCVKInputAssembler::doInit(const InputAssemblerInfo &info) {
size_t vbCount = _vertexBuffers.size();
_gpuInputAssembler = ccnew CCVKGPUInputAssembler;
_gpuInputAssembler->attributes = _attributes;
_gpuInputAssembler->gpuVertexBuffers.resize(vbCount);
auto *hub = CCVKDevice::getInstance()->gpuIAHub();
for (size_t i = 0U; i < vbCount; ++i) {
auto *vb = static_cast<CCVKBuffer *>(_vertexBuffers[i]);
_gpuInputAssembler->gpuVertexBuffers[i] = vb->gpuBufferView();
hub->connect(_gpuInputAssembler, _gpuInputAssembler->gpuVertexBuffers[i].get());
}
if (info.indexBuffer) {
_gpuInputAssembler->gpuIndexBuffer = static_cast<CCVKBuffer *>(info.indexBuffer)->gpuBufferView();
hub->connect(_gpuInputAssembler, _gpuInputAssembler->gpuIndexBuffer.get());
}
if (info.indirectBuffer) {
_gpuInputAssembler->gpuIndirectBuffer = static_cast<CCVKBuffer *>(info.indirectBuffer)->gpuBufferView();
hub->connect(_gpuInputAssembler, _gpuInputAssembler->gpuIndirectBuffer.get());
}
_gpuInputAssembler->vertexBuffers.resize(vbCount);
_gpuInputAssembler->vertexBufferOffsets.resize(vbCount);
CCVKGPUDevice *gpuDevice = CCVKDevice::getInstance()->gpuDevice();
for (size_t i = 0U; i < vbCount; i++) {
_gpuInputAssembler->vertexBuffers[i] = _gpuInputAssembler->gpuVertexBuffers[i]->gpuBuffer->vkBuffer;
_gpuInputAssembler->vertexBufferOffsets[i] = _gpuInputAssembler->gpuVertexBuffers[i]->getStartOffset(gpuDevice->curBackBufferIndex);
}
}
void CCVKInputAssembler::doDestroy() {
_gpuInputAssembler = nullptr;
}
void CCVKGPUInputAssembler::shutdown() {
auto *hub = CCVKDevice::getInstance()->gpuIAHub();
for (auto &vb : gpuVertexBuffers) {
hub->disengage(this, vb);
}
if (gpuIndexBuffer) {
hub->disengage(this, gpuIndexBuffer);
}
if (gpuIndirectBuffer) {
hub->disengage(this, gpuIndirectBuffer);
}
}
void CCVKGPUInputAssembler::update(const CCVKGPUBufferView *oldBuffer, const CCVKGPUBufferView *newBuffer) {
for (uint32_t i = 0; i < gpuVertexBuffers.size(); ++i) {
if (gpuVertexBuffers[i].get() == oldBuffer) {
gpuVertexBuffers[i] = newBuffer;
vertexBuffers[i] = newBuffer->gpuBuffer->vkBuffer;
}
}
if (gpuIndexBuffer.get() == oldBuffer) {
gpuIndexBuffer = newBuffer;
}
if (gpuIndirectBuffer.get() == oldBuffer) {
gpuIndirectBuffer = newBuffer;
}
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,51 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "VKStd.h"
#include "gfx-base/GFXInputAssembler.h"
#include "gfx-vulkan/VKGPUObjects.h"
namespace cc {
namespace gfx {
struct CCVKGPUInputAssembler;
class CC_VULKAN_API CCVKInputAssembler final : public InputAssembler {
public:
CCVKInputAssembler();
~CCVKInputAssembler() override;
inline CCVKGPUInputAssembler *gpuInputAssembler() const { return _gpuInputAssembler; }
protected:
void doInit(const InputAssemblerInfo &info) override;
void doDestroy() override;
IntrusivePtr<CCVKGPUInputAssembler> _gpuInputAssembler;
};
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,129 @@
/****************************************************************************
Copyright (c) 2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "VKPipelineCache.h"
#include <fstream>
#include "base/BinaryArchive.h"
#include "gfx-base/GFXUtil.h"
namespace {
const char *fileName = "/pipeline_cache_vk.bin";
const uint32_t MAGIC = 0x4343564B; // "CCVK"
const uint32_t VERSION = 1;
void loadData(const ccstd::string &path, ccstd::vector<char> &data) {
std::ifstream stream(path, std::ios::binary);
if (!stream.is_open()) {
CC_LOG_INFO("Load program cache, no cached files.");
return;
}
uint32_t magic = 0;
uint32_t version = 0;
cc::BinaryInputArchive archive(stream);
auto loadResult = archive.load(magic);
loadResult &= archive.load(version);
uint32_t size = 0;
if (loadResult && magic == MAGIC && version >= VERSION) {
loadResult &= archive.load(size);
data.resize(size);
loadResult &= archive.load(data.data(), size);
}
if (loadResult) {
CC_LOG_INFO("Load pipeline cache success.");
}
}
} // namespace
namespace cc::gfx {
CCVKPipelineCache::CCVKPipelineCache() {
_savePath = getPipelineCacheFolder() + fileName;
}
CCVKPipelineCache::~CCVKPipelineCache() {
if (_pipelineCache != VK_NULL_HANDLE) {
#if CC_USE_PIPELINE_CACHE
saveCache();
#endif
vkDestroyPipelineCache(_device, _pipelineCache, nullptr);
}
}
void CCVKPipelineCache::init(VkDevice dev) {
_device = dev;
loadCache();
}
void CCVKPipelineCache::loadCache() {
ccstd::vector<char> data;
#if CC_USE_PIPELINE_CACHE
loadData(_savePath, data);
#endif
VkPipelineCacheCreateInfo cacheInfo = {};
cacheInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
cacheInfo.pNext = nullptr;
cacheInfo.initialDataSize = static_cast<uint32_t>(data.size());
cacheInfo.pInitialData = data.data();
VK_CHECK(vkCreatePipelineCache(_device, &cacheInfo, nullptr, &_pipelineCache));
}
void CCVKPipelineCache::saveCache() {
if (!_dirty) {
return;
}
std::ofstream stream(_savePath, std::ios::binary);
if (!stream.is_open()) {
CC_LOG_INFO("Save program cache failed.");
return;
}
BinaryOutputArchive archive(stream);
archive.save(MAGIC);
archive.save(VERSION);
size_t size = 0;
vkGetPipelineCacheData(_device, _pipelineCache, &size, nullptr);
ccstd::vector<char> data(size);
vkGetPipelineCacheData(_device, _pipelineCache, &size, data.data());
archive.save(static_cast<uint32_t>(size));
archive.save(data.data(), static_cast<uint32_t>(size));
_dirty = false;
}
void CCVKPipelineCache::setDirty() {
_dirty = true;
}
VkPipelineCache CCVKPipelineCache::getHandle() const {
return _pipelineCache;
}
} // namespace cc::gfx

View File

@@ -0,0 +1,55 @@
/****************************************************************************
Copyright (c) 2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "VKGPUObjects.h"
#include "base/Ptr.h"
#include "base/RefCounted.h"
#include "base/std/container/string.h"
#include "base/std/container/unordered_map.h"
#include "base/std/container/vector.h"
namespace cc::gfx {
class CCVKPipelineCache : public RefCounted {
public:
CCVKPipelineCache();
~CCVKPipelineCache() override;
void init(VkDevice dev);
void loadCache();
void saveCache();
void setDirty();
VkPipelineCache getHandle() const;
private:
VkDevice _device = VK_NULL_HANDLE;
VkPipelineCache _pipelineCache = VK_NULL_HANDLE;
ccstd::string _savePath;
bool _dirty = false;
};
} // namespace cc::gfx

View File

@@ -0,0 +1,67 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "VKPipelineLayout.h"
#include "VKCommands.h"
#include "VKDescriptorSetLayout.h"
#include "VKDevice.h"
namespace cc {
namespace gfx {
CCVKPipelineLayout::CCVKPipelineLayout() {
_typedID = generateObjectID<decltype(this)>();
}
CCVKPipelineLayout::~CCVKPipelineLayout() {
destroy();
}
void CCVKPipelineLayout::doInit(const PipelineLayoutInfo & /*info*/) {
_gpuPipelineLayout = ccnew CCVKGPUPipelineLayout;
uint32_t offset = 0U;
for (auto *setLayout : _setLayouts) {
CCVKGPUDescriptorSetLayout *gpuSetLayout = static_cast<CCVKDescriptorSetLayout *>(setLayout)->gpuDescriptorSetLayout();
uint32_t dynamicCount = utils::toUint(gpuSetLayout->dynamicBindings.size());
_gpuPipelineLayout->dynamicOffsetOffsets.push_back(offset);
_gpuPipelineLayout->setLayouts.emplace_back(gpuSetLayout);
offset += dynamicCount;
}
_gpuPipelineLayout->dynamicOffsetOffsets.push_back(offset);
_gpuPipelineLayout->dynamicOffsetCount = offset;
cmdFuncCCVKCreatePipelineLayout(CCVKDevice::getInstance(), _gpuPipelineLayout);
}
void CCVKPipelineLayout::doDestroy() {
_gpuPipelineLayout = nullptr;
}
void CCVKGPUPipelineLayout::shutdown() {
cmdFuncCCVKDestroyPipelineLayout(CCVKDevice::getInstance()->gpuDevice(), this);
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,49 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "VKStd.h"
#include "gfx-base/GFXPipelineLayout.h"
#include "gfx-vulkan/VKGPUObjects.h"
namespace cc {
namespace gfx {
class CC_VULKAN_API CCVKPipelineLayout final : public PipelineLayout {
public:
CCVKPipelineLayout();
~CCVKPipelineLayout() override;
inline CCVKGPUPipelineLayout *gpuPipelineLayout() const { return _gpuPipelineLayout; }
protected:
void doInit(const PipelineLayoutInfo &info) override;
void doDestroy() override;
IntrusivePtr<CCVKGPUPipelineLayout> _gpuPipelineLayout;
};
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,78 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "VKPipelineState.h"
#include "VKCommands.h"
#include "VKDevice.h"
#include "VKPipelineLayout.h"
#include "VKRenderPass.h"
#include "VKShader.h"
namespace cc {
namespace gfx {
CCVKPipelineState::CCVKPipelineState() {
_typedID = generateObjectID<decltype(this)>();
}
CCVKPipelineState::~CCVKPipelineState() {
destroy();
}
void CCVKPipelineState::doInit(const PipelineStateInfo & /*info*/) {
_gpuPipelineState = ccnew CCVKGPUPipelineState;
_gpuPipelineState->bindPoint = _bindPoint;
_gpuPipelineState->primitive = _primitive;
_gpuPipelineState->gpuShader = static_cast<CCVKShader *>(_shader)->gpuShader();
_gpuPipelineState->inputState = _inputState;
_gpuPipelineState->rs = _rasterizerState;
_gpuPipelineState->dss = _depthStencilState;
_gpuPipelineState->bs = _blendState;
_gpuPipelineState->subpass = _subpass;
_gpuPipelineState->gpuPipelineLayout = static_cast<CCVKPipelineLayout *>(_pipelineLayout)->gpuPipelineLayout();
if (_renderPass) _gpuPipelineState->gpuRenderPass = static_cast<CCVKRenderPass *>(_renderPass)->gpuRenderPass();
for (uint32_t i = 0; i < 31; i++) {
if (static_cast<uint32_t>(_dynamicStates) & (1 << i)) {
_gpuPipelineState->dynamicStates.push_back(static_cast<DynamicStateFlagBit>(1 << i));
}
}
if (_bindPoint == PipelineBindPoint::GRAPHICS) {
cmdFuncCCVKCreateGraphicsPipelineState(CCVKDevice::getInstance(), _gpuPipelineState);
} else {
cmdFuncCCVKCreateComputePipelineState(CCVKDevice::getInstance(), _gpuPipelineState);
}
}
void CCVKPipelineState::doDestroy() {
_gpuPipelineState = nullptr;
}
void CCVKGPUPipelineState::shutdown() {
CCVKDevice::getInstance()->gpuRecycleBin()->collect(this);
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,49 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "VKStd.h"
#include "gfx-base/GFXPipelineState.h"
#include "gfx-vulkan/VKGPUObjects.h"
namespace cc {
namespace gfx {
class CC_VULKAN_API CCVKPipelineState final : public PipelineState {
public:
CCVKPipelineState();
~CCVKPipelineState() override;
inline CCVKGPUPipelineState *gpuPipelineState() const { return _gpuPipelineState; }
protected:
void doInit(const PipelineStateInfo &info) override;
void doDestroy() override;
IntrusivePtr<CCVKGPUPipelineState> _gpuPipelineState;
};
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,59 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "VKQueryPool.h"
#include "VKCommandBuffer.h"
#include "VKCommands.h"
#include "VKDevice.h"
namespace cc {
namespace gfx {
CCVKQueryPool::CCVKQueryPool() {
_typedID = generateObjectID<decltype(this)>();
}
CCVKQueryPool::~CCVKQueryPool() {
destroy();
}
void CCVKQueryPool::doInit(const QueryPoolInfo & /*info*/) {
CCVKDevice *device = CCVKDevice::getInstance();
_gpuQueryPool = ccnew CCVKGPUQueryPool;
_gpuQueryPool->type = _type;
_gpuQueryPool->maxQueryObjects = _maxQueryObjects;
_gpuQueryPool->forceWait = _forceWait;
cmdFuncCCVKCreateQueryPool(device, _gpuQueryPool);
}
void CCVKQueryPool::doDestroy() {
_gpuQueryPool = nullptr;
}
void CCVKGPUQueryPool::shutdown() {
CCVKDevice::getInstance()->gpuRecycleBin()->collect(this);
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,54 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include <mutex>
#include "VKStd.h"
#include "gfx-base/GFXQueryPool.h"
#include "gfx-vulkan/VKGPUObjects.h"
namespace cc {
namespace gfx {
class CC_VULKAN_API CCVKQueryPool final : public QueryPool {
public:
CCVKQueryPool();
~CCVKQueryPool() override;
inline CCVKGPUQueryPool *gpuQueryPool() const { return _gpuQueryPool; }
protected:
friend class CCVKCommandBuffer;
friend class CCVKDevice;
void doInit(const QueryPoolInfo &info) override;
void doDestroy() override;
IntrusivePtr<CCVKGPUQueryPool> _gpuQueryPool;
ccstd::vector<uint32_t> _ids;
};
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,102 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "VKStd.h"
#include "VKCommandBuffer.h"
#include "VKCommands.h"
#include "VKDevice.h"
#include "VKQueue.h"
namespace cc {
namespace gfx {
CCVKQueue::CCVKQueue() {
_typedID = generateObjectID<decltype(this)>();
}
CCVKQueue::~CCVKQueue() {
destroy();
}
void CCVKQueue::doInit(const QueueInfo & /*info*/) {
_gpuQueue = std::make_unique<CCVKGPUQueue>();
_gpuQueue->type = _type;
cmdFuncCCVKGetDeviceQueue(CCVKDevice::getInstance(), _gpuQueue.get());
}
void CCVKQueue::doDestroy() {
_gpuQueue = nullptr;
}
void CCVKQueue::submit(CommandBuffer *const *cmdBuffs, uint32_t count) {
CCVKDevice *device = CCVKDevice::getInstance();
_gpuQueue->commandBuffers.clear();
#if BARRIER_DEDUCTION_LEVEL >= BARRIER_DEDUCTION_LEVEL_BASIC
device->gpuBarrierManager()->update(device->gpuTransportHub());
#endif
device->gpuBufferHub()->flush(device->gpuTransportHub());
if (!device->gpuTransportHub()->empty(false)) {
_gpuQueue->commandBuffers.push_back(device->gpuTransportHub()->packageForFlight(false));
}
for (uint32_t i = 0U; i < count; ++i) {
auto *cmdBuff = static_cast<CCVKCommandBuffer *>(cmdBuffs[i]);
if (!cmdBuff->_pendingQueue.empty()) {
_gpuQueue->commandBuffers.push_back(cmdBuff->_pendingQueue.front());
cmdBuff->_pendingQueue.pop();
_numDrawCalls += cmdBuff->_numDrawCalls;
_numInstances += cmdBuff->_numInstances;
_numTriangles += cmdBuff->_numTriangles;
}
}
if (!device->gpuTransportHub()->empty(true)) {
_gpuQueue->commandBuffers.push_back(device->gpuTransportHub()->packageForFlight(true));
}
size_t waitSemaphoreCount = _gpuQueue->lastSignaledSemaphores.size();
VkSemaphore signal = waitSemaphoreCount ? device->gpuSemaphorePool()->alloc() : VK_NULL_HANDLE;
_gpuQueue->submitStageMasks.resize(waitSemaphoreCount, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
VkSubmitInfo submitInfo{VK_STRUCTURE_TYPE_SUBMIT_INFO};
submitInfo.waitSemaphoreCount = utils::toUint(waitSemaphoreCount);
submitInfo.pWaitSemaphores = _gpuQueue->lastSignaledSemaphores.data();
submitInfo.pWaitDstStageMask = _gpuQueue->submitStageMasks.data();
submitInfo.commandBufferCount = utils::toUint(_gpuQueue->commandBuffers.size());
submitInfo.pCommandBuffers = &_gpuQueue->commandBuffers[0];
submitInfo.signalSemaphoreCount = waitSemaphoreCount ? 1 : 0;
submitInfo.pSignalSemaphores = &signal;
VkFence vkFence = device->gpuFencePool()->alloc();
VK_CHECK(vkQueueSubmit(_gpuQueue->vkQueue, 1, &submitInfo, vkFence));
_gpuQueue->lastSignaledSemaphores.assign(1, signal);
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,59 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include <memory>
#include "VKStd.h"
#include "gfx-base/GFXQueue.h"
namespace cc {
namespace gfx {
struct CCVKGPUQueue;
class CC_VULKAN_API CCVKQueue final : public Queue {
public:
CCVKQueue();
~CCVKQueue() override;
void submit(CommandBuffer *const *cmdBuffs, uint32_t count) override;
inline CCVKGPUQueue *gpuQueue() const { return _gpuQueue.get(); }
protected:
friend class CCVKDevice;
void doInit(const QueueInfo &info) override;
void doDestroy() override;
std::unique_ptr<CCVKGPUQueue> _gpuQueue;
uint32_t _numDrawCalls = 0;
uint32_t _numInstances = 0;
uint32_t _numTriangles = 0;
};
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,87 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "VKRenderPass.h"
#include "VKCommands.h"
#include "VKDevice.h"
namespace cc {
namespace gfx {
CCVKRenderPass::CCVKRenderPass() {
_typedID = generateObjectID<decltype(this)>();
}
CCVKRenderPass::~CCVKRenderPass() {
destroy();
}
void CCVKRenderPass::doInit(const RenderPassInfo & /*info*/) {
_gpuRenderPass = ccnew CCVKGPURenderPass;
_gpuRenderPass->colorAttachments = _colorAttachments;
_gpuRenderPass->depthStencilAttachment = _depthStencilAttachment;
_gpuRenderPass->depthStencilResolveAttachment = _depthStencilResolveAttachment;
_gpuRenderPass->subpasses = _subpasses;
_gpuRenderPass->dependencies = _dependencies;
// assign a dummy subpass if not specified
uint32_t colorCount = utils::toUint(_gpuRenderPass->colorAttachments.size());
if (_gpuRenderPass->subpasses.empty()) {
_gpuRenderPass->subpasses.emplace_back();
auto &subpass = _gpuRenderPass->subpasses.back();
subpass.colors.resize(_colorAttachments.size());
for (uint32_t i = 0U; i < _colorAttachments.size(); ++i) {
subpass.colors[i] = i;
}
if (_depthStencilAttachment.format != Format::UNKNOWN) {
subpass.depthStencil = colorCount;
}
if (_depthStencilResolveAttachment.format != Format::UNKNOWN) {
subpass.depthStencilResolve = colorCount + 1;
}
} else {
// unify depth stencil index
for (auto &subpass : _gpuRenderPass->subpasses) {
if (subpass.depthStencil != INVALID_BINDING && subpass.depthStencil >= colorCount) {
subpass.depthStencil = colorCount;
}
if (subpass.depthStencilResolve != INVALID_BINDING && subpass.depthStencilResolve >= colorCount) {
subpass.depthStencilResolve = colorCount + 1;
}
}
}
cmdFuncCCVKCreateRenderPass(CCVKDevice::getInstance(), _gpuRenderPass);
}
void CCVKRenderPass::doDestroy() {
_gpuRenderPass = nullptr;
}
void CCVKGPURenderPass::shutdown() {
CCVKDevice::getInstance()->gpuRecycleBin()->collect(this);
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,49 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "VKStd.h"
#include "gfx-base/GFXRenderPass.h"
#include "gfx-vulkan/VKGPUObjects.h"
namespace cc {
namespace gfx {
class CC_VULKAN_API CCVKRenderPass final : public RenderPass {
public:
CCVKRenderPass();
~CCVKRenderPass() override;
inline CCVKGPURenderPass *gpuRenderPass() const { return _gpuRenderPass; }
protected:
void doInit(const RenderPassInfo &info) override;
void doDestroy() override;
IntrusivePtr<CCVKGPURenderPass> _gpuRenderPass;
};
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,87 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "VKStd.h"
#include "VKCommands.h"
#include "VKDevice.h"
#include "VKShader.h"
namespace cc {
namespace gfx {
CCVKShader::CCVKShader() {
_typedID = generateObjectID<decltype(this)>();
}
CCVKShader::~CCVKShader() {
destroy();
}
namespace {
void initGpuShader(CCVKGPUShader *gpuShader) {
cmdFuncCCVKCreateShader(CCVKDevice::getInstance(), gpuShader);
// Clear shader source after they're uploaded to GPU
for (auto &stage : gpuShader->gpuStages) {
stage.source.clear();
stage.source.shrink_to_fit();
}
gpuShader->initialized = true;
}
} // namespace
CCVKGPUShader *CCVKShader::gpuShader() const {
if (!_gpuShader->initialized) {
initGpuShader(_gpuShader);
}
return _gpuShader;
}
void CCVKShader::doInit(const ShaderInfo & /*info*/) {
_gpuShader = ccnew CCVKGPUShader;
_gpuShader->name = _name;
_gpuShader->attributes = _attributes;
for (ShaderStage &stage : _stages) {
_gpuShader->gpuStages.emplace_back(CCVKGPUShaderStage{stage.stage, stage.source});
}
for (auto &stage : _stages) {
stage.source.clear();
stage.source.shrink_to_fit();
}
}
void CCVKShader::doDestroy() {
_gpuShader = nullptr;
}
void CCVKGPUShader::shutdown() {
cmdFuncCCVKDestroyShader(CCVKDevice::getInstance()->gpuDevice(), this);
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,49 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "VKStd.h"
#include "gfx-base/GFXShader.h"
#include "gfx-vulkan/VKGPUObjects.h"
namespace cc {
namespace gfx {
class CC_VULKAN_API CCVKShader final : public Shader {
public:
CCVKShader();
~CCVKShader() override;
CCVKGPUShader *gpuShader() const;
protected:
void doInit(const ShaderInfo &info) override;
void doDestroy() override;
IntrusivePtr<CCVKGPUShader> _gpuShader;
};
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,25 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "VKStd.h"

View File

@@ -0,0 +1,55 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "base/Log.h"
#if (CC_PLATFORM == CC_PLATFORM_WINDOWS)
#if defined(CC_STATIC)
#define CC_VULKAN_API
#else
#ifdef CC_VK_EXPORTS
#define CC_VULKAN_API __declspec(dllexport)
#else
#define CC_VULKAN_API __declspec(dllimport)
#endif
#endif
#else
#define CC_VULKAN_API
#endif
#if CC_DEBUG > 0
#define VK_CHECK(x) \
do { \
VkResult err = x; \
if (err) { \
CC_LOG_ERROR("%s returned Vulkan error: %d", #x, err); \
CC_ABORT(); \
} \
} while (0)
#else
#define VK_CHECK(x) x
#endif

View File

@@ -0,0 +1,505 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "VKSwapchain.h"
#include "VKCommands.h"
#include "VKDevice.h"
#include "VKGPUObjects.h"
#include "VKQueue.h"
#include "VKRenderPass.h"
#include "VKTexture.h"
#include "VKUtils.h"
#include "application/ApplicationManager.h"
#include "platform/interfaces/modules/ISystemWindow.h"
#include "platform/interfaces/modules/ISystemWindowManager.h"
#include "platform/interfaces/modules/IXRInterface.h"
#if CC_SWAPPY_ENABLED
#include "platform/android/AndroidPlatform.h"
#include "swappy/swappyVk.h"
#include "swappy/swappy_common.h"
#endif
namespace cc {
namespace gfx {
CCVKSwapchain::CCVKSwapchain() {
_typedID = generateObjectID<decltype(this)>();
_preRotationEnabled = ENABLE_PRE_ROTATION;
}
CCVKSwapchain::~CCVKSwapchain() {
destroy();
}
void CCVKSwapchain::doInit(const SwapchainInfo &info) {
_xr = CC_GET_XR_INTERFACE();
if (_xr) {
_xr->updateXRSwapchainTypedID(getTypedID());
}
auto *gpuDevice = CCVKDevice::getInstance()->gpuDevice();
const auto *gpuContext = CCVKDevice::getInstance()->gpuContext();
_gpuSwapchain = ccnew CCVKGPUSwapchain;
gpuDevice->swapchains.insert(_gpuSwapchain);
createVkSurface();
///////////////////// Parameter Selection /////////////////////
uint32_t queueFamilyPropertiesCount = utils::toUint(gpuContext->queueFamilyProperties.size());
_gpuSwapchain->queueFamilyPresentables.resize(queueFamilyPropertiesCount);
for (uint32_t propertyIndex = 0U; propertyIndex < queueFamilyPropertiesCount; propertyIndex++) {
if (_xr) {
_gpuSwapchain->queueFamilyPresentables[propertyIndex] = true;
} else {
vkGetPhysicalDeviceSurfaceSupportKHR(gpuContext->physicalDevice, propertyIndex,
_gpuSwapchain->vkSurface, &_gpuSwapchain->queueFamilyPresentables[propertyIndex]);
}
}
// find other possible queues if not presentable
auto *queue = static_cast<CCVKQueue *>(CCVKDevice::getInstance()->getQueue());
if (!_gpuSwapchain->queueFamilyPresentables[queue->gpuQueue()->queueFamilyIndex]) {
auto &indices = queue->gpuQueue()->possibleQueueFamilyIndices;
indices.erase(std::remove_if(indices.begin(), indices.end(), [this](uint32_t i) {
return !_gpuSwapchain->queueFamilyPresentables[i];
}),
indices.end());
CC_ASSERT(!_gpuSwapchain->queueFamilyPresentables.empty());
cmdFuncCCVKGetDeviceQueue(CCVKDevice::getInstance(), queue->gpuQueue());
}
Format colorFmt = Format::BGRA8;
Format depthStencilFmt = Format::DEPTH_STENCIL;
if (_gpuSwapchain->vkSurface != VK_NULL_HANDLE) {
VkSurfaceCapabilitiesKHR surfaceCapabilities{};
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(gpuContext->physicalDevice, _gpuSwapchain->vkSurface, &surfaceCapabilities);
uint32_t surfaceFormatCount = 0U;
VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(gpuContext->physicalDevice, _gpuSwapchain->vkSurface, &surfaceFormatCount, nullptr));
ccstd::vector<VkSurfaceFormatKHR> surfaceFormats(surfaceFormatCount);
VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(gpuContext->physicalDevice, _gpuSwapchain->vkSurface, &surfaceFormatCount, surfaceFormats.data()));
uint32_t presentModeCount = 0U;
VK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(gpuContext->physicalDevice, _gpuSwapchain->vkSurface, &presentModeCount, nullptr));
ccstd::vector<VkPresentModeKHR> presentModes(presentModeCount);
VK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(gpuContext->physicalDevice, _gpuSwapchain->vkSurface, &presentModeCount, presentModes.data()));
VkFormat colorFormat = VK_FORMAT_B8G8R8A8_UNORM;
VkColorSpaceKHR colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
// If the surface format list only includes one entry with VK_FORMAT_UNDEFINED,
// there is no preferred format, so we assume VK_FORMAT_B8G8R8A8_UNORM
if ((surfaceFormatCount == 1) && (surfaceFormats[0].format == VK_FORMAT_UNDEFINED)) {
colorFormat = VK_FORMAT_B8G8R8A8_UNORM;
colorSpace = surfaceFormats[0].colorSpace;
} else {
// iterate over the list of available surface format and
// check for the presence of VK_FORMAT_B8G8R8A8_UNORM
bool imageFormatFound = false;
for (VkSurfaceFormatKHR &surfaceFormat : surfaceFormats) {
if (surfaceFormat.format == VK_FORMAT_B8G8R8A8_UNORM) {
colorFormat = surfaceFormat.format;
colorSpace = surfaceFormat.colorSpace;
imageFormatFound = true;
break;
}
}
// in case VK_FORMAT_B8G8R8A8_UNORM is not available
// select the first available color format
if (!imageFormatFound) {
colorFormat = surfaceFormats[0].format;
colorSpace = surfaceFormats[0].colorSpace;
switch (colorFormat) {
case VK_FORMAT_R8G8B8A8_UNORM: colorFmt = Format::RGBA8; break;
case VK_FORMAT_R8G8B8A8_SRGB: colorFmt = Format::SRGB8_A8; break;
case VK_FORMAT_R5G6B5_UNORM_PACK16: colorFmt = Format::R5G6B5; break;
default: CC_ABORT(); break;
}
}
}
// Select a present mode for the swapchain
ccstd::vector<VkPresentModeKHR> presentModePriorityList;
switch (_vsyncMode) {
case VsyncMode::OFF: presentModePriorityList.insert(presentModePriorityList.end(), {VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_FIFO_KHR}); break;
case VsyncMode::ON: presentModePriorityList.insert(presentModePriorityList.end(), {VK_PRESENT_MODE_FIFO_KHR}); break;
case VsyncMode::RELAXED: presentModePriorityList.insert(presentModePriorityList.end(), {VK_PRESENT_MODE_FIFO_RELAXED_KHR, VK_PRESENT_MODE_FIFO_KHR}); break;
case VsyncMode::MAILBOX: presentModePriorityList.insert(presentModePriorityList.end(), {VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_FIFO_KHR}); break;
case VsyncMode::HALF: presentModePriorityList.insert(presentModePriorityList.end(), {VK_PRESENT_MODE_FIFO_KHR}); break; // no easy fallback
}
VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR;
// UNASSIGNED-BestPractices-vkCreateSwapchainKHR-swapchain-presentmode-not-fifo
#if !defined(VK_USE_PLATFORM_ANDROID_KHR)
for (VkPresentModeKHR presentMode : presentModePriorityList) {
if (std::find(presentModes.begin(), presentModes.end(), presentMode) != presentModes.end()) {
swapchainPresentMode = presentMode;
break;
}
}
#endif
// Determine the number of images
uint32_t desiredNumberOfSwapchainImages = std::max(gpuDevice->backBufferCount, surfaceCapabilities.minImageCount);
VkExtent2D imageExtent = {1U, 1U};
// Find a supported composite alpha format (not all devices support alpha opaque)
VkCompositeAlphaFlagBitsKHR compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
// Simply select the first composite alpha format available
ccstd::vector<VkCompositeAlphaFlagBitsKHR> compositeAlphaFlags = {
VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR,
VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR,
VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR,
};
for (VkCompositeAlphaFlagBitsKHR compositeAlphaFlag : compositeAlphaFlags) {
if (surfaceCapabilities.supportedCompositeAlpha & compositeAlphaFlag) {
compositeAlpha = compositeAlphaFlag;
break;
};
}
VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
// Enable transfer source on swap chain images if supported
if (surfaceCapabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
imageUsage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
}
// Enable transfer destination on swap chain images if supported
if (surfaceCapabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
imageUsage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
}
_gpuSwapchain->createInfo.surface = _gpuSwapchain->vkSurface;
_gpuSwapchain->createInfo.minImageCount = desiredNumberOfSwapchainImages;
_gpuSwapchain->createInfo.imageFormat = colorFormat;
_gpuSwapchain->createInfo.imageColorSpace = colorSpace;
_gpuSwapchain->createInfo.imageExtent = imageExtent;
_gpuSwapchain->createInfo.imageUsage = imageUsage;
_gpuSwapchain->createInfo.imageArrayLayers = 1;
_gpuSwapchain->createInfo.preTransform = VkSurfaceTransformFlagBitsKHR::VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
_gpuSwapchain->createInfo.compositeAlpha = compositeAlpha;
_gpuSwapchain->createInfo.presentMode = swapchainPresentMode;
_gpuSwapchain->createInfo.clipped = VK_TRUE; // Setting clipped to VK_TRUE allows the implementation to discard rendering outside of the surface area
}
///////////////////// Texture Creation /////////////////////
auto width = static_cast<int32_t>(info.width);
auto height = static_cast<int32_t>(info.height);
if (_xr) {
colorFmt = _xr->getXRSwapchainFormat();
width = _xr->getXRConfig(xr::XRConfigKey::SWAPCHAIN_WIDTH).getInt();
height = _xr->getXRConfig(xr::XRConfigKey::SWAPCHAIN_HEIGHT).getInt();
}
_colorTexture = ccnew CCVKTexture;
_depthStencilTexture = ccnew CCVKTexture;
SwapchainTextureInfo textureInfo;
textureInfo.swapchain = this;
textureInfo.format = colorFmt;
textureInfo.width = width;
textureInfo.height = height;
initTexture(textureInfo, _colorTexture);
textureInfo.format = depthStencilFmt;
initTexture(textureInfo, _depthStencilTexture);
#if CC_PLATFORM == CC_PLATFORM_ANDROID
auto *window = CC_GET_SYSTEM_WINDOW(_windowId);
auto viewSize = window->getViewSize();
checkSwapchainStatus(viewSize.width, viewSize.height);
#else
checkSwapchainStatus();
#endif
}
void CCVKSwapchain::doDestroy() {
if (!_gpuSwapchain) return;
CCVKDevice::getInstance()->waitAllFences();
_depthStencilTexture = nullptr;
_colorTexture = nullptr;
auto *gpuDevice = CCVKDevice::getInstance()->gpuDevice();
const auto *gpuContext = CCVKDevice::getInstance()->gpuContext();
destroySwapchain(gpuDevice);
if (_gpuSwapchain->vkSurface != VK_NULL_HANDLE) {
vkDestroySurfaceKHR(gpuContext->vkInstance, _gpuSwapchain->vkSurface, nullptr);
_gpuSwapchain->vkSurface = VK_NULL_HANDLE;
}
gpuDevice->swapchains.erase(_gpuSwapchain);
_gpuSwapchain = nullptr;
}
void CCVKSwapchain::doResize(uint32_t width, uint32_t height, SurfaceTransform /*transform*/) {
checkSwapchainStatus(width, height); // the orientation info from system event is not reliable
}
bool CCVKSwapchain::checkSwapchainStatus(uint32_t width, uint32_t height) {
uint32_t newWidth = width;
uint32_t newHeight = height;
uint32_t imageCount = 0;
if (_xr) {
newWidth = static_cast<CCVKTexture *>(_colorTexture.get())->_info.width;
newHeight = static_cast<CCVKTexture *>(_colorTexture.get())->_info.height;
// xr double eyes need six images
std::vector<VkImage> vkImagesLeft;
std::vector<VkImage> vkImagesRight;
_xr->getXRSwapchainVkImages(vkImagesLeft, static_cast<uint32_t>(cc::xr::XREye::LEFT));
_xr->getXRSwapchainVkImages(vkImagesRight, static_cast<uint32_t>(cc::xr::XREye::RIGHT));
_gpuSwapchain->swapchainImages.resize(vkImagesLeft.size() + vkImagesRight.size());
_gpuSwapchain->swapchainImages.clear();
// 0-1-2
_gpuSwapchain->swapchainImages.insert(_gpuSwapchain->swapchainImages.end(), vkImagesLeft.begin(), vkImagesLeft.end());
// 3-4-5
_gpuSwapchain->swapchainImages.insert(_gpuSwapchain->swapchainImages.end(), vkImagesRight.begin(), vkImagesRight.end());
imageCount = _gpuSwapchain->swapchainImages.size();
_gpuSwapchain->createInfo.imageExtent.width = newWidth;
_gpuSwapchain->createInfo.imageExtent.height = newHeight;
auto *gpuDevice = CCVKDevice::getInstance()->gpuDevice();
gpuDevice->curBackBufferIndex = 0;
_gpuSwapchain->curImageIndex = 0;
CCVKDevice::getInstance()->updateBackBufferCount(imageCount);
CCVKDevice::getInstance()->waitAllFences();
CC_LOG_INFO("Resizing surface: %dx%d, surface rotation: %d degrees", newWidth, newHeight, static_cast<uint32_t>(_transform) * 90);
} else {
if (_gpuSwapchain->vkSurface == VK_NULL_HANDLE) { // vkSurface will be set to VK_NULL_HANDLE after call doDestroySurface
return false;
}
auto *gpuDevice = CCVKDevice::getInstance()->gpuDevice();
const auto *gpuContext = CCVKDevice::getInstance()->gpuContext();
VkSurfaceCapabilitiesKHR surfaceCapabilities;
VK_CHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(gpuContext->physicalDevice, _gpuSwapchain->vkSurface, &surfaceCapabilities));
// surfaceCapabilities.currentExtent seems to remain the same
// during any size/orientation change events on android devices
// so we prefer the system input (oriented size) here
newWidth = width ? width : surfaceCapabilities.currentExtent.width;
newHeight = height ? height : surfaceCapabilities.currentExtent.height;
if (_gpuSwapchain->createInfo.imageExtent.width == newWidth &&
_gpuSwapchain->createInfo.imageExtent.height == newHeight && _gpuSwapchain->lastPresentResult == VK_SUCCESS) {
return true;
}
if (newWidth == static_cast<uint32_t>(-1)) {
_gpuSwapchain->createInfo.imageExtent.width = _colorTexture->getWidth();
_gpuSwapchain->createInfo.imageExtent.height = _colorTexture->getHeight();
} else {
_gpuSwapchain->createInfo.imageExtent.width = newWidth;
_gpuSwapchain->createInfo.imageExtent.height = newHeight;
}
if (newWidth == 0 || newHeight == 0) {
_gpuSwapchain->lastPresentResult = VK_NOT_READY;
return false;
}
_gpuSwapchain->createInfo.surface = _gpuSwapchain->vkSurface;
_gpuSwapchain->createInfo.oldSwapchain = _gpuSwapchain->vkSwapchain;
CC_LOG_INFO("Resizing surface: %dx%d", newWidth, newHeight);
CCVKDevice::getInstance()->waitAllFences();
VkSwapchainKHR vkSwapchain = VK_NULL_HANDLE;
VK_CHECK(vkCreateSwapchainKHR(gpuDevice->vkDevice, &_gpuSwapchain->createInfo, nullptr, &vkSwapchain));
destroySwapchain(gpuDevice);
_gpuSwapchain->vkSwapchain = vkSwapchain;
VK_CHECK(vkGetSwapchainImagesKHR(gpuDevice->vkDevice, _gpuSwapchain->vkSwapchain, &imageCount, nullptr));
CCVKDevice::getInstance()->updateBackBufferCount(imageCount);
_gpuSwapchain->swapchainImages.resize(imageCount);
VK_CHECK(vkGetSwapchainImagesKHR(gpuDevice->vkDevice, _gpuSwapchain->vkSwapchain, &imageCount, _gpuSwapchain->swapchainImages.data()));
}
++_generation;
// should skip size check, since the old swapchain has already been destroyed
static_cast<CCVKTexture *>(_colorTexture.get())->_info.width = 1;
static_cast<CCVKTexture *>(_depthStencilTexture.get())->_info.width = 1;
_colorTexture->resize(newWidth, newHeight);
_depthStencilTexture->resize(newWidth, newHeight);
bool hasStencil = GFX_FORMAT_INFOS[toNumber(_depthStencilTexture->getFormat())].hasStencil;
ccstd::vector<VkImageMemoryBarrier> barriers(imageCount * 2, VkImageMemoryBarrier{});
VkPipelineStageFlags srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
ThsvsImageBarrier tempBarrier{};
tempBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
tempBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
tempBarrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
tempBarrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
VkPipelineStageFlags tempSrcStageMask = 0;
VkPipelineStageFlags tempDstStageMask = 0;
auto *colorGPUTexture = static_cast<CCVKTexture *>(_colorTexture.get())->gpuTexture();
auto *depthStencilGPUTexture = static_cast<CCVKTexture *>(_depthStencilTexture.get())->gpuTexture();
for (uint32_t i = 0U; i < imageCount; i++) {
tempBarrier.nextAccessCount = 1;
tempBarrier.pNextAccesses = getAccessType(AccessFlagBit::PRESENT);
tempBarrier.image = _gpuSwapchain->swapchainImages[i];
tempBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
thsvsGetVulkanImageMemoryBarrier(tempBarrier, &tempSrcStageMask, &tempDstStageMask, &barriers[i]);
srcStageMask |= tempSrcStageMask;
dstStageMask |= tempDstStageMask;
tempBarrier.nextAccessCount = 1;
tempBarrier.pNextAccesses = getAccessType(AccessFlagBit::DEPTH_STENCIL_ATTACHMENT_WRITE);
tempBarrier.image = depthStencilGPUTexture->swapchainVkImages[i];
tempBarrier.subresourceRange.aspectMask = hasStencil ? VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_DEPTH_BIT;
thsvsGetVulkanImageMemoryBarrier(tempBarrier, &tempSrcStageMask, &tempDstStageMask, &barriers[imageCount + i]);
srcStageMask |= tempSrcStageMask;
dstStageMask |= tempDstStageMask;
}
CCVKDevice::getInstance()->gpuTransportHub()->checkIn(
[&](const CCVKGPUCommandBuffer *gpuCommandBuffer) {
vkCmdPipelineBarrier(gpuCommandBuffer->vkCommandBuffer, srcStageMask, dstStageMask, 0, 0, nullptr, 0, nullptr,
utils::toUint(barriers.size()), barriers.data());
},
true); // submit immediately
colorGPUTexture->currentAccessTypes.assign(1, THSVS_ACCESS_PRESENT);
depthStencilGPUTexture->currentAccessTypes.assign(1, THSVS_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ);
_gpuSwapchain->lastPresentResult = VK_SUCCESS;
// Android Game Frame Pacing:swappy
#if CC_SWAPPY_ENABLED
auto *gpuDevice = CCVKDevice::getInstance()->gpuDevice();
const auto *gpuContext = CCVKDevice::getInstance()->gpuContext();
int32_t fps = cc::BasePlatform::getPlatform()->getFps();
uint64_t frameRefreshIntervalNS;
auto *platform = static_cast<AndroidPlatform *>(cc::BasePlatform::getPlatform());
auto *window = CC_GET_SYSTEM_WINDOW(_windowId);
void *windowHandle = reinterpret_cast<void *>(window->getWindowHandle());
SwappyVk_initAndGetRefreshCycleDuration(static_cast<JNIEnv *>(platform->getEnv()),
static_cast<jobject>(platform->getActivity()),
gpuContext->physicalDevice,
gpuDevice->vkDevice,
_gpuSwapchain->vkSwapchain,
&frameRefreshIntervalNS);
SwappyVk_setSwapIntervalNS(gpuDevice->vkDevice, _gpuSwapchain->vkSwapchain, fps ? 1000000000L / fps : frameRefreshIntervalNS);
SwappyVk_setWindow(gpuDevice->vkDevice, _gpuSwapchain->vkSwapchain, static_cast<ANativeWindow *>(windowHandle));
#endif
return true;
}
void CCVKSwapchain::destroySwapchain(CCVKGPUDevice *gpuDevice) {
if (_gpuSwapchain->vkSwapchain != VK_NULL_HANDLE) {
_gpuSwapchain->swapchainImages.clear();
#if CC_SWAPPY_ENABLED
SwappyVk_destroySwapchain(gpuDevice->vkDevice, _gpuSwapchain->vkSwapchain);
#endif
vkDestroySwapchainKHR(gpuDevice->vkDevice, _gpuSwapchain->vkSwapchain, nullptr);
_gpuSwapchain->vkSwapchain = VK_NULL_HANDLE;
// reset index only after device not ready
_gpuSwapchain->curImageIndex = 0;
gpuDevice->curBackBufferIndex = 0;
}
}
void CCVKSwapchain::doDestroySurface() {
if (!_gpuSwapchain || _gpuSwapchain->vkSurface == VK_NULL_HANDLE) return;
auto *gpuDevice = CCVKDevice::getInstance()->gpuDevice();
const auto *gpuContext = CCVKDevice::getInstance()->gpuContext();
CCVKDevice::getInstance()->waitAllFences();
destroySwapchain(gpuDevice);
_gpuSwapchain->lastPresentResult = VK_NOT_READY;
vkDestroySurfaceKHR(gpuContext->vkInstance, _gpuSwapchain->vkSurface, nullptr);
_gpuSwapchain->vkSurface = VK_NULL_HANDLE;
}
void CCVKSwapchain::doCreateSurface(void *windowHandle) { // NOLINT
if (!_gpuSwapchain || _gpuSwapchain->vkSurface != VK_NULL_HANDLE) return;
createVkSurface();
#if CC_PLATFORM == CC_PLATFORM_ANDROID
auto *window = CC_GET_SYSTEM_WINDOW(_windowId);
auto viewSize = window->getViewSize();
checkSwapchainStatus(viewSize.width, viewSize.height);
#else
checkSwapchainStatus();
#endif
}
void CCVKSwapchain::createVkSurface() {
if (_xr) {
// xr do not need VkSurface
_gpuSwapchain->vkSurface = VK_NULL_HANDLE;
return;
}
const auto *gpuContext = CCVKDevice::getInstance()->gpuContext();
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
VkAndroidSurfaceCreateInfoKHR surfaceCreateInfo{VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR};
surfaceCreateInfo.window = reinterpret_cast<ANativeWindow *>(_windowHandle);
VK_CHECK(vkCreateAndroidSurfaceKHR(gpuContext->vkInstance, &surfaceCreateInfo, nullptr, &_gpuSwapchain->vkSurface));
#elif defined(VK_USE_PLATFORM_WIN32_KHR)
VkWin32SurfaceCreateInfoKHR surfaceCreateInfo{VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR};
surfaceCreateInfo.hinstance = static_cast<HINSTANCE>(GetModuleHandle(nullptr));
surfaceCreateInfo.hwnd = reinterpret_cast<HWND>(_windowHandle);
VK_CHECK(vkCreateWin32SurfaceKHR(gpuContext->vkInstance, &surfaceCreateInfo, nullptr, &_gpuSwapchain->vkSurface));
#elif defined(VK_USE_PLATFORM_VI_NN)
VkViSurfaceCreateInfoNN surfaceCreateInfo{VK_STRUCTURE_TYPE_VI_SURFACE_CREATE_INFO_NN};
surfaceCreateInfo.window = _windowHandle;
VK_CHECK(vkCreateViSurfaceNN(gpuContext->vkInstance, &surfaceCreateInfo, nullptr, &_gpuSwapchain->vkSurface));
#elif defined(VK_USE_PLATFORM_MACOS_MVK)
VkMacOSSurfaceCreateInfoMVK surfaceCreateInfo{VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK};
surfaceCreateInfo.pView = _windowHandle;
VK_CHECK(vkCreateMacOSSurfaceMVK(gpuContext->vkInstance, &surfaceCreateInfo, nullptr, &_gpuSwapchain->vkSurface));
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
VkWaylandSurfaceCreateInfoKHR surfaceCreateInfo{VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR};
surfaceCreateInfo.display = nullptr; // TODO
surfaceCreateInfo.surface = reinterpret_cast<wl_surface *>(_windowHandle);
VK_CHECK(vkCreateWaylandSurfaceKHR(gpuContext->vkInstance, &surfaceCreateInfo, nullptr, &_gpuSwapchain->vkSurface));
#elif defined(VK_USE_PLATFORM_XCB_KHR)
VkXcbSurfaceCreateInfoKHR surfaceCreateInfo{VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR};
surfaceCreateInfo.connection = nullptr; // TODO
surfaceCreateInfo.window = reinterpret_cast<uint64_t>(_windowHandle);
VK_CHECK(vkCreateXcbSurfaceKHR(gpuContext->vkInstance, &surfaceCreateInfo, nullptr, &_gpuSwapchain->vkSurface));
#else
#pragma error Platform not supported
#endif
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,64 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "VKStd.h"
#include "gfx-base/GFXSwapchain.h"
#include "gfx-vulkan/VKGPUObjects.h"
namespace cc {
class IXRInterface;
namespace gfx {
class CCVKDevice;
class CCVKGPUDevice;
class CC_VULKAN_API CCVKSwapchain final : public Swapchain {
public:
static constexpr bool ENABLE_PRE_ROTATION = true;
CCVKSwapchain();
~CCVKSwapchain() override;
inline CCVKGPUSwapchain *gpuSwapchain() { return _gpuSwapchain; }
bool checkSwapchainStatus(uint32_t width = 0, uint32_t height = 0);
protected:
void doInit(const SwapchainInfo &info) override;
void doDestroy() override;
void doResize(uint32_t width, uint32_t height, SurfaceTransform transform) override;
void doDestroySurface() override;
void doCreateSurface(void *windowHandle) override;
void createVkSurface();
void destroySwapchain(CCVKGPUDevice *gpuDevice);
IntrusivePtr<CCVKGPUSwapchain> _gpuSwapchain;
IXRInterface *_xr = nullptr;
};
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,156 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "VKTexture.h"
#include "VKCommandBuffer.h"
#include "VKCommands.h"
#include "VKDevice.h"
#include "VKSwapchain.h"
#include "profiler/Profiler.h"
namespace cc {
namespace gfx {
CCVKTexture::CCVKTexture() {
_typedID = generateObjectID<decltype(this)>();
}
CCVKTexture::~CCVKTexture() {
destroy();
}
void CCVKTexture::doInit(const TextureInfo & /*info*/) {
createTexture(_info.width, _info.height, _size);
_viewInfo.planeCount = _info.format == Format::DEPTH_STENCIL ? 2 : 1;
createTextureView();
}
void CCVKTexture::doInit(const TextureViewInfo &info) {
_gpuTexture = static_cast<CCVKTexture *>(info.texture)->gpuTexture();
createTextureView();
}
void CCVKTexture::createTexture(uint32_t width, uint32_t height, uint32_t size, bool initGPUTexture) {
_gpuTexture = ccnew CCVKGPUTexture;
_gpuTexture->width = width;
_gpuTexture->height = height;
_gpuTexture->size = size;
if (_swapchain != nullptr) {
_gpuTexture->swapchain = static_cast<CCVKSwapchain *>(_swapchain)->gpuSwapchain();
_gpuTexture->memoryAllocated = false;
}
_gpuTexture->type = _info.type;
_gpuTexture->format = _info.format;
_gpuTexture->usage = _info.usage;
_gpuTexture->depth = _info.depth;
_gpuTexture->arrayLayers = _info.layerCount;
_gpuTexture->mipLevels = _info.levelCount;
_gpuTexture->samples = _info.samples;
_gpuTexture->flags = _info.flags;
bool hasExternalFlag = hasFlag(_gpuTexture->flags, TextureFlagBit::EXTERNAL_NORMAL);
if (hasExternalFlag) {
_gpuTexture->externalVKImage = reinterpret_cast<VkImage>(_info.externalRes);
}
if (initGPUTexture) {
_gpuTexture->init();
}
}
void CCVKTexture::createTextureView(bool initGPUTextureView) {
_gpuTextureView = ccnew CCVKGPUTextureView;
_gpuTextureView->gpuTexture = _gpuTexture;
_gpuTextureView->type = _viewInfo.type;
_gpuTextureView->format = _viewInfo.format;
_gpuTextureView->baseLevel = _viewInfo.baseLevel;
_gpuTextureView->levelCount = _viewInfo.levelCount;
_gpuTextureView->baseLayer = _viewInfo.baseLayer;
_gpuTextureView->layerCount = _viewInfo.layerCount;
_gpuTextureView->basePlane = _viewInfo.basePlane;
_gpuTextureView->planeCount = _viewInfo.planeCount;
if (initGPUTextureView) {
_gpuTextureView->init();
}
}
void CCVKTexture::doDestroy() {
_gpuTexture = nullptr;
_gpuTextureView = nullptr;
}
void CCVKTexture::doResize(uint32_t width, uint32_t height, uint32_t size) {
if (!width || !height) return;
createTexture(width, height, size);
// Hold reference to keep the old textureView alive during DescriptorHub::update.
IntrusivePtr<CCVKGPUTextureView> oldTextureView = _gpuTextureView;
createTextureView();
CCVKDevice::getInstance()->gpuDescriptorHub()->update(oldTextureView, _gpuTextureView);
}
///////////////////////////// Swapchain Specific /////////////////////////////
void CCVKTexture::doInit(const SwapchainTextureInfo & /*info*/) {
createTexture(_info.width, _info.height, _size, false);
createTextureView(false);
}
void CCVKGPUTexture::init() {
cmdFuncCCVKCreateTexture(CCVKDevice::getInstance(), this);
if (memoryAllocated) {
CCVKDevice::getInstance()->getMemoryStatus().textureSize += size;
CC_PROFILE_MEMORY_INC(Texture, size);
}
}
void CCVKGPUTexture::shutdown() {
if (memoryAllocated) {
CCVKDevice::getInstance()->getMemoryStatus().textureSize -= size;
CC_PROFILE_MEMORY_DEC(Texture, size);
}
CCVKDevice::getInstance()->gpuBarrierManager()->cancel(this);
if (!hasFlag(flags, TextureFlagBit::EXTERNAL_NORMAL)) {
CCVKDevice::getInstance()->gpuRecycleBin()->collect(this);
}
}
void CCVKGPUTextureView::init() {
cmdFuncCCVKCreateTextureView(CCVKDevice::getInstance(), this);
}
void CCVKGPUTextureView::shutdown() {
CCVKDevice::getInstance()->gpuDescriptorHub()->disengage(this);
CCVKDevice::getInstance()->gpuRecycleBin()->collect(this);
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,59 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "VKStd.h"
#include "gfx-base/GFXTexture.h"
#include "gfx-vulkan/VKGPUObjects.h"
namespace cc {
namespace gfx {
class CC_VULKAN_API CCVKTexture final : public Texture {
public:
CCVKTexture();
~CCVKTexture() override;
inline CCVKGPUTexture *gpuTexture() const { return _gpuTexture; }
inline CCVKGPUTextureView *gpuTextureView() const { return _gpuTextureView; }
protected:
friend class CCVKSwapchain;
void doInit(const TextureInfo &info) override;
void doInit(const TextureViewInfo &info) override;
void doInit(const SwapchainTextureInfo &info) override;
void doDestroy() override;
void doResize(uint32_t width, uint32_t height, uint32_t size) override;
void createTexture(uint32_t width, uint32_t height, uint32_t size, bool initGPUTexture = true);
void createTextureView(bool initGPUTextureView = true);
IntrusivePtr<CCVKGPUTexture> _gpuTexture;
IntrusivePtr<CCVKGPUTextureView> _gpuTextureView;
};
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,609 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "VKUtils.h"
#include "VKGPUObjects.h"
namespace cc {
namespace gfx {
VkQueryType mapVkQueryType(QueryType type) {
switch (type) {
case QueryType::OCCLUSION: return VK_QUERY_TYPE_OCCLUSION;
case QueryType::PIPELINE_STATISTICS: return VK_QUERY_TYPE_PIPELINE_STATISTICS;
case QueryType::TIMESTAMP: return VK_QUERY_TYPE_TIMESTAMP;
default: {
CC_ABORT();
return VK_QUERY_TYPE_OCCLUSION;
}
}
}
VkFormat mapVkFormat(Format format, const CCVKGPUDevice *gpuDevice) {
switch (format) {
case Format::R8: return VK_FORMAT_R8_UNORM;
case Format::R8SN: return VK_FORMAT_R8_SNORM;
case Format::R8UI: return VK_FORMAT_R8_UINT;
case Format::R8I: return VK_FORMAT_R8_SINT;
case Format::RG8: return VK_FORMAT_R8G8_UNORM;
case Format::RG8SN: return VK_FORMAT_R8G8_SNORM;
case Format::RG8UI: return VK_FORMAT_R8G8_UINT;
case Format::RG8I: return VK_FORMAT_R8G8_SINT;
case Format::RGB8: return VK_FORMAT_R8G8B8_UNORM;
case Format::SRGB8: return VK_FORMAT_R8G8B8_SRGB;
case Format::RGB8SN: return VK_FORMAT_R8G8B8_SNORM;
case Format::RGB8UI: return VK_FORMAT_R8G8B8_UINT;
case Format::RGB8I: return VK_FORMAT_R8G8B8_SINT;
case Format::RGBA8: return VK_FORMAT_R8G8B8A8_UNORM;
case Format::BGRA8: return VK_FORMAT_B8G8R8A8_UNORM;
case Format::SRGB8_A8: return VK_FORMAT_R8G8B8A8_SRGB;
case Format::RGBA8SN: return VK_FORMAT_R8G8B8A8_SNORM;
case Format::RGBA8UI: return VK_FORMAT_R8G8B8A8_UINT;
case Format::RGBA8I: return VK_FORMAT_R8G8B8A8_SINT;
case Format::R16I: return VK_FORMAT_R16_SINT;
case Format::R16UI: return VK_FORMAT_R16_UINT;
case Format::R16F: return VK_FORMAT_R16_SFLOAT;
case Format::RG16I: return VK_FORMAT_R16G16_SINT;
case Format::RG16UI: return VK_FORMAT_R16G16_UINT;
case Format::RG16F: return VK_FORMAT_R16G16_SFLOAT;
case Format::RGB16I: return VK_FORMAT_R16G16B16_SINT;
case Format::RGB16UI: return VK_FORMAT_R16G16B16_UINT;
case Format::RGB16F: return VK_FORMAT_R16G16B16_SFLOAT;
case Format::RGBA16I: return VK_FORMAT_R16G16B16A16_SINT;
case Format::RGBA16UI: return VK_FORMAT_R16G16B16A16_UINT;
case Format::RGBA16F: return VK_FORMAT_R16G16B16A16_SFLOAT;
case Format::R32I: return VK_FORMAT_R32_SINT;
case Format::R32UI: return VK_FORMAT_R32_UINT;
case Format::R32F: return VK_FORMAT_R32_SFLOAT;
case Format::RG32I: return VK_FORMAT_R32G32_SINT;
case Format::RG32UI: return VK_FORMAT_R32G32_UINT;
case Format::RG32F: return VK_FORMAT_R32G32_SFLOAT;
case Format::RGB32I: return VK_FORMAT_R32G32B32_SINT;
case Format::RGB32UI: return VK_FORMAT_R32G32B32_UINT;
case Format::RGB32F: return VK_FORMAT_R32G32B32_SFLOAT;
case Format::RGBA32I: return VK_FORMAT_R32G32B32A32_SINT;
case Format::RGBA32UI: return VK_FORMAT_R32G32B32A32_UINT;
case Format::RGBA32F: return VK_FORMAT_R32G32B32A32_SFLOAT;
case Format::R5G6B5: return VK_FORMAT_R5G6B5_UNORM_PACK16;
case Format::R11G11B10F: return VK_FORMAT_B10G11R11_UFLOAT_PACK32;
case Format::RGB5A1: return VK_FORMAT_R5G5B5A1_UNORM_PACK16;
case Format::RGBA4: return VK_FORMAT_R4G4B4A4_UNORM_PACK16;
case Format::RGB10A2: return VK_FORMAT_A2B10G10R10_UNORM_PACK32;
case Format::RGB10A2UI: return VK_FORMAT_A2B10G10R10_UINT_PACK32;
case Format::RGB9E5: return VK_FORMAT_E5B9G9R9_UFLOAT_PACK32;
case Format::DEPTH: return gpuDevice->depthFormat;
case Format::DEPTH_STENCIL: return gpuDevice->depthStencilFormat;
case Format::BC1: return VK_FORMAT_BC1_RGB_UNORM_BLOCK;
case Format::BC1_ALPHA: return VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
case Format::BC1_SRGB: return VK_FORMAT_BC1_RGB_SRGB_BLOCK;
case Format::BC1_SRGB_ALPHA: return VK_FORMAT_BC1_RGBA_SRGB_BLOCK;
case Format::BC2: return VK_FORMAT_BC2_UNORM_BLOCK;
case Format::BC2_SRGB: return VK_FORMAT_BC2_SRGB_BLOCK;
case Format::BC3: return VK_FORMAT_BC3_UNORM_BLOCK;
case Format::BC3_SRGB: return VK_FORMAT_BC3_SRGB_BLOCK;
case Format::BC4: return VK_FORMAT_BC4_UNORM_BLOCK;
case Format::BC4_SNORM: return VK_FORMAT_BC4_SNORM_BLOCK;
case Format::BC5: return VK_FORMAT_BC5_UNORM_BLOCK;
case Format::BC5_SNORM: return VK_FORMAT_BC5_SNORM_BLOCK;
case Format::BC6H_UF16: return VK_FORMAT_BC6H_UFLOAT_BLOCK;
case Format::BC6H_SF16: return VK_FORMAT_BC6H_SFLOAT_BLOCK;
case Format::BC7: return VK_FORMAT_BC7_UNORM_BLOCK;
case Format::BC7_SRGB: return VK_FORMAT_BC7_SRGB_BLOCK;
case Format::ETC2_RGB8: return VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;
case Format::ETC2_SRGB8: return VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK;
case Format::ETC2_RGB8_A1: return VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK;
case Format::ETC2_SRGB8_A1: return VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK;
case Format::ETC2_RGBA8: return VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
case Format::ETC2_SRGB8_A8: return VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK;
case Format::EAC_R11: return VK_FORMAT_EAC_R11_UNORM_BLOCK;
case Format::EAC_R11SN: return VK_FORMAT_EAC_R11_SNORM_BLOCK;
case Format::EAC_RG11: return VK_FORMAT_EAC_R11G11_UNORM_BLOCK;
case Format::EAC_RG11SN: return VK_FORMAT_EAC_R11G11_SNORM_BLOCK;
case Format::PVRTC_RGB2:
case Format::PVRTC_RGBA2: return VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG;
case Format::PVRTC_RGB4:
case Format::PVRTC_RGBA4: return VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG;
case Format::PVRTC2_2BPP: return VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG;
case Format::PVRTC2_4BPP: return VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG;
case Format::ASTC_RGBA_4X4: return VK_FORMAT_ASTC_4x4_UNORM_BLOCK;
case Format::ASTC_RGBA_5X4: return VK_FORMAT_ASTC_5x4_UNORM_BLOCK;
case Format::ASTC_RGBA_5X5: return VK_FORMAT_ASTC_5x5_UNORM_BLOCK;
case Format::ASTC_RGBA_6X5: return VK_FORMAT_ASTC_6x5_UNORM_BLOCK;
case Format::ASTC_RGBA_6X6: return VK_FORMAT_ASTC_6x6_UNORM_BLOCK;
case Format::ASTC_RGBA_8X5: return VK_FORMAT_ASTC_8x5_UNORM_BLOCK;
case Format::ASTC_RGBA_8X6: return VK_FORMAT_ASTC_8x6_UNORM_BLOCK;
case Format::ASTC_RGBA_8X8: return VK_FORMAT_ASTC_8x8_UNORM_BLOCK;
case Format::ASTC_RGBA_10X5: return VK_FORMAT_ASTC_10x5_UNORM_BLOCK;
case Format::ASTC_RGBA_10X6: return VK_FORMAT_ASTC_10x6_UNORM_BLOCK;
case Format::ASTC_RGBA_10X8: return VK_FORMAT_ASTC_10x8_UNORM_BLOCK;
case Format::ASTC_RGBA_10X10: return VK_FORMAT_ASTC_10x10_UNORM_BLOCK;
case Format::ASTC_RGBA_12X10: return VK_FORMAT_ASTC_12x10_UNORM_BLOCK;
case Format::ASTC_RGBA_12X12: return VK_FORMAT_ASTC_12x12_UNORM_BLOCK;
case Format::ASTC_SRGBA_4X4: return VK_FORMAT_ASTC_4x4_SRGB_BLOCK;
case Format::ASTC_SRGBA_5X4: return VK_FORMAT_ASTC_5x4_SRGB_BLOCK;
case Format::ASTC_SRGBA_5X5: return VK_FORMAT_ASTC_5x5_SRGB_BLOCK;
case Format::ASTC_SRGBA_6X5: return VK_FORMAT_ASTC_6x5_SRGB_BLOCK;
case Format::ASTC_SRGBA_6X6: return VK_FORMAT_ASTC_6x6_SRGB_BLOCK;
case Format::ASTC_SRGBA_8X5: return VK_FORMAT_ASTC_8x5_SRGB_BLOCK;
case Format::ASTC_SRGBA_8X6: return VK_FORMAT_ASTC_8x6_SRGB_BLOCK;
case Format::ASTC_SRGBA_8X8: return VK_FORMAT_ASTC_8x8_SRGB_BLOCK;
case Format::ASTC_SRGBA_10X5: return VK_FORMAT_ASTC_10x5_SRGB_BLOCK;
case Format::ASTC_SRGBA_10X6: return VK_FORMAT_ASTC_10x6_SRGB_BLOCK;
case Format::ASTC_SRGBA_10X8: return VK_FORMAT_ASTC_10x8_SRGB_BLOCK;
case Format::ASTC_SRGBA_10X10: return VK_FORMAT_ASTC_10x10_SRGB_BLOCK;
case Format::ASTC_SRGBA_12X10: return VK_FORMAT_ASTC_12x10_SRGB_BLOCK;
case Format::ASTC_SRGBA_12X12: return VK_FORMAT_ASTC_12x12_SRGB_BLOCK;
default: {
CC_ABORT();
return VK_FORMAT_B8G8R8A8_UNORM;
}
}
}
VkAttachmentLoadOp mapVkLoadOp(LoadOp loadOp) {
switch (loadOp) {
case LoadOp::CLEAR: return VK_ATTACHMENT_LOAD_OP_CLEAR;
case LoadOp::LOAD: return VK_ATTACHMENT_LOAD_OP_LOAD;
case LoadOp::DISCARD: return VK_ATTACHMENT_LOAD_OP_DONT_CARE;
default: {
CC_ABORT();
return VK_ATTACHMENT_LOAD_OP_LOAD;
}
}
}
VkAttachmentStoreOp mapVkStoreOp(StoreOp storeOp) {
switch (storeOp) {
case StoreOp::STORE: return VK_ATTACHMENT_STORE_OP_STORE;
case StoreOp::DISCARD: return VK_ATTACHMENT_STORE_OP_DONT_CARE;
default: {
CC_ABORT();
return VK_ATTACHMENT_STORE_OP_STORE;
}
}
}
VkBufferUsageFlagBits mapVkBufferUsageFlagBits(BufferUsage usage) {
uint32_t flags = 0U;
if (hasFlag(usage, BufferUsage::TRANSFER_SRC)) flags |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
if (hasFlag(usage, BufferUsage::TRANSFER_DST)) flags |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
if (hasFlag(usage, BufferUsage::INDEX)) flags |= VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
if (hasFlag(usage, BufferUsage::VERTEX)) flags |= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
if (hasFlag(usage, BufferUsage::UNIFORM)) flags |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
if (hasFlag(usage, BufferUsage::STORAGE)) flags |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
if (hasFlag(usage, BufferUsage::INDIRECT)) flags |= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
return static_cast<VkBufferUsageFlagBits>(flags);
}
VkImageType mapVkImageType(TextureType type) {
switch (type) {
case TextureType::TEX1D:
case TextureType::TEX1D_ARRAY: return VK_IMAGE_TYPE_1D;
case TextureType::CUBE:
case TextureType::TEX2D:
case TextureType::TEX2D_ARRAY: return VK_IMAGE_TYPE_2D;
case TextureType::TEX3D: return VK_IMAGE_TYPE_3D;
default: {
CC_ABORT();
return VK_IMAGE_TYPE_2D;
}
}
}
VkFormatFeatureFlags mapVkFormatFeatureFlags(TextureUsage usage) {
uint32_t flags = 0U;
if (hasFlag(usage, TextureUsage::TRANSFER_SRC)) flags |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT;
if (hasFlag(usage, TextureUsage::TRANSFER_DST)) flags |= VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
if (hasFlag(usage, TextureUsage::SAMPLED)) flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
if (hasFlag(usage, TextureUsage::STORAGE)) flags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
if (hasFlag(usage, TextureUsage::COLOR_ATTACHMENT)) flags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
if (hasFlag(usage, TextureUsage::DEPTH_STENCIL_ATTACHMENT)) flags |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
return static_cast<VkFormatFeatureFlags>(flags);
}
VkImageUsageFlags mapVkImageUsageFlags(TextureUsage usage, TextureFlags textureFlags) {
VkImageUsageFlags flags = 0;
if (hasFlag(usage, TextureUsage::TRANSFER_SRC)) flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
if (hasFlag(usage, TextureUsage::TRANSFER_DST)) flags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
if (hasFlag(usage, TextureUsage::SAMPLED)) flags |= VK_IMAGE_USAGE_SAMPLED_BIT;
if (hasFlag(usage, TextureUsage::STORAGE)) flags |= VK_IMAGE_USAGE_STORAGE_BIT;
if (hasFlag(usage, TextureUsage::COLOR_ATTACHMENT)) flags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
if (hasFlag(usage, TextureUsage::DEPTH_STENCIL_ATTACHMENT)) flags |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
if (hasFlag(usage, TextureUsage::INPUT_ATTACHMENT)) flags |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
if (hasFlag(usage, TextureUsage::SHADING_RATE)) flags |= VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR;
if (hasFlag(textureFlags, TextureFlags::GEN_MIPMAP)) {
flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
}
if (hasFlag(textureFlags, TextureFlags::LAZILY_ALLOCATED)) {
flags |= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
}
return flags;
}
VkImageAspectFlags mapVkImageAspectFlags(Format format) {
VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
const FormatInfo &info = GFX_FORMAT_INFOS[toNumber(format)];
if (info.hasDepth) aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
if (info.hasStencil) aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
return aspectMask;
}
VkImageCreateFlags mapVkImageCreateFlags(TextureType type) {
uint32_t res = 0U;
switch (type) {
case TextureType::CUBE: res |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; break;
default: break;
}
return static_cast<VkImageCreateFlags>(res);
}
VkImageViewType mapVkImageViewType(TextureType viewType) {
switch (viewType) {
case TextureType::TEX1D: return VK_IMAGE_VIEW_TYPE_1D;
case TextureType::TEX1D_ARRAY: return VK_IMAGE_VIEW_TYPE_1D_ARRAY;
case TextureType::TEX2D: return VK_IMAGE_VIEW_TYPE_2D;
case TextureType::TEX2D_ARRAY: return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
case TextureType::TEX3D: return VK_IMAGE_VIEW_TYPE_3D;
case TextureType::CUBE: return VK_IMAGE_VIEW_TYPE_CUBE;
default: {
CC_ABORT();
return VK_IMAGE_VIEW_TYPE_2D;
}
}
}
VkCommandBufferLevel mapVkCommandBufferLevel(CommandBufferType type) {
switch (type) {
case CommandBufferType::PRIMARY: return VK_COMMAND_BUFFER_LEVEL_PRIMARY;
case CommandBufferType::SECONDARY: return VK_COMMAND_BUFFER_LEVEL_SECONDARY;
default: {
CC_ABORT();
return VK_COMMAND_BUFFER_LEVEL_SECONDARY;
}
}
}
VkDescriptorType mapVkDescriptorType(DescriptorType type) {
switch (type) {
case DescriptorType::DYNAMIC_UNIFORM_BUFFER: return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
case DescriptorType::UNIFORM_BUFFER: return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
case DescriptorType::DYNAMIC_STORAGE_BUFFER: return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
case DescriptorType::STORAGE_BUFFER: return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
case DescriptorType::SAMPLER_TEXTURE: return VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
case DescriptorType::SAMPLER: return VK_DESCRIPTOR_TYPE_SAMPLER;
case DescriptorType::TEXTURE: return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
case DescriptorType::STORAGE_IMAGE: return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
case DescriptorType::INPUT_ATTACHMENT: return VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
default: {
CC_ABORT();
return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
}
}
}
VkColorComponentFlags mapVkColorComponentFlags(ColorMask colorMask) {
uint32_t flags = 0U;
if (hasFlag(colorMask, ColorMask::R)) flags |= VK_COLOR_COMPONENT_R_BIT;
if (hasFlag(colorMask, ColorMask::G)) flags |= VK_COLOR_COMPONENT_G_BIT;
if (hasFlag(colorMask, ColorMask::B)) flags |= VK_COLOR_COMPONENT_B_BIT;
if (hasFlag(colorMask, ColorMask::A)) flags |= VK_COLOR_COMPONENT_A_BIT;
return static_cast<VkColorComponentFlags>(flags);
}
VkShaderStageFlagBits mapVkShaderStageFlagBits(ShaderStageFlagBit stage) {
switch (stage) {
case ShaderStageFlagBit::VERTEX: return VK_SHADER_STAGE_VERTEX_BIT;
case ShaderStageFlagBit::CONTROL: return VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
case ShaderStageFlagBit::EVALUATION: return VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
case ShaderStageFlagBit::GEOMETRY: return VK_SHADER_STAGE_GEOMETRY_BIT;
case ShaderStageFlagBit::FRAGMENT: return VK_SHADER_STAGE_FRAGMENT_BIT;
case ShaderStageFlagBit::COMPUTE: return VK_SHADER_STAGE_COMPUTE_BIT;
default: {
CC_ABORT();
return VK_SHADER_STAGE_VERTEX_BIT;
}
}
}
VkShaderStageFlags mapVkShaderStageFlags(ShaderStageFlagBit stages) {
uint32_t flags = 0U;
if (hasFlag(stages, ShaderStageFlagBit::VERTEX)) flags |= VK_SHADER_STAGE_VERTEX_BIT;
if (hasFlag(stages, ShaderStageFlagBit::CONTROL)) flags |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
if (hasFlag(stages, ShaderStageFlagBit::EVALUATION)) flags |= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
if (hasFlag(stages, ShaderStageFlagBit::GEOMETRY)) flags |= VK_SHADER_STAGE_GEOMETRY_BIT;
if (hasFlag(stages, ShaderStageFlagBit::FRAGMENT)) flags |= VK_SHADER_STAGE_FRAGMENT_BIT;
if (hasFlag(stages, ShaderStageFlagBit::COMPUTE)) flags |= VK_SHADER_STAGE_COMPUTE_BIT;
return static_cast<VkShaderStageFlags>(flags);
}
SurfaceTransform mapSurfaceTransform(VkSurfaceTransformFlagBitsKHR transform) {
if (transform & VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR) return SurfaceTransform::ROTATE_90;
if (transform & VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR) return SurfaceTransform::ROTATE_180;
if (transform & VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR) return SurfaceTransform::ROTATE_270;
return SurfaceTransform::IDENTITY;
}
ccstd::string mapVendorName(uint32_t vendorID) {
switch (vendorID) {
case 0x1002: return "Advanced Micro Devices, Inc.";
case 0x1010: return "Imagination Technologies";
case 0x106b: return "Apple Inc.";
case 0x10DE: return "Nvidia Corporation";
case 0x13B5: return "Arm Limited";
case 0x5143: return "Qualcomm Incorporated";
case 0x8086: return "Intel Corporation";
}
return StringUtil::format("Unknown VendorID %d", vendorID);
}
const VkSurfaceTransformFlagsKHR TRANSFORMS_THAT_REQUIRE_FLIPPING =
VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR |
VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR;
const VkPrimitiveTopology VK_PRIMITIVE_MODES[] = {
VK_PRIMITIVE_TOPOLOGY_POINT_LIST, // POINT_LIST
VK_PRIMITIVE_TOPOLOGY_LINE_LIST, // LINE_LIST
VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, // LINE_STRIP
static_cast<VkPrimitiveTopology>(0), // LINE_LOOP
VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY, // LINE_LIST_ADJACENCY
VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY, // LINE_STRIP_ADJACENCY
static_cast<VkPrimitiveTopology>(0), // ISO_LINE_LIST
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // TRIANGLE_LIST
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // TRIANGLE_STRIP
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, // TRIANGLE_FAN
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY, // TRIANGLE_LIST_ADJACENCY
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY, // TRIANGLE_STRIP_ADJACENCY,
static_cast<VkPrimitiveTopology>(0), // TRIANGLE_PATCH_ADJACENCY,
VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, // QUAD_PATCH_LIST,
};
const VkCullModeFlags VK_CULL_MODES[] = {
VK_CULL_MODE_NONE,
VK_CULL_MODE_FRONT_BIT,
VK_CULL_MODE_BACK_BIT,
};
const VkPolygonMode VK_POLYGON_MODES[] = {
VK_POLYGON_MODE_FILL,
VK_POLYGON_MODE_LINE,
VK_POLYGON_MODE_POINT,
};
const VkCompareOp VK_CMP_FUNCS[] = {
VK_COMPARE_OP_NEVER,
VK_COMPARE_OP_LESS,
VK_COMPARE_OP_EQUAL,
VK_COMPARE_OP_LESS_OR_EQUAL,
VK_COMPARE_OP_GREATER,
VK_COMPARE_OP_NOT_EQUAL,
VK_COMPARE_OP_GREATER_OR_EQUAL,
VK_COMPARE_OP_ALWAYS,
};
const VkStencilOp VK_STENCIL_OPS[] = {
VK_STENCIL_OP_ZERO,
VK_STENCIL_OP_KEEP,
VK_STENCIL_OP_REPLACE,
VK_STENCIL_OP_INCREMENT_AND_CLAMP,
VK_STENCIL_OP_DECREMENT_AND_CLAMP,
VK_STENCIL_OP_INVERT,
VK_STENCIL_OP_INCREMENT_AND_WRAP,
VK_STENCIL_OP_DECREMENT_AND_WRAP,
};
const VkBlendOp VK_BLEND_OPS[] = {
VK_BLEND_OP_ADD,
VK_BLEND_OP_SUBTRACT,
VK_BLEND_OP_REVERSE_SUBTRACT,
VK_BLEND_OP_MIN,
VK_BLEND_OP_MAX,
};
const VkBlendFactor VK_BLEND_FACTORS[] = {
VK_BLEND_FACTOR_ZERO,
VK_BLEND_FACTOR_ONE,
VK_BLEND_FACTOR_SRC_ALPHA,
VK_BLEND_FACTOR_DST_ALPHA,
VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA,
VK_BLEND_FACTOR_SRC_COLOR,
VK_BLEND_FACTOR_DST_COLOR,
VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR,
VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR,
VK_BLEND_FACTOR_SRC_ALPHA_SATURATE,
VK_BLEND_FACTOR_CONSTANT_COLOR,
VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR,
VK_BLEND_FACTOR_CONSTANT_ALPHA,
VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA,
};
const VkFilter VK_FILTERS[] = {
static_cast<VkFilter>(0), // NONE
VK_FILTER_NEAREST, // POINT
VK_FILTER_LINEAR, // LINEAR
static_cast<VkFilter>(0), // ANISOTROPIC
};
const VkSamplerMipmapMode VK_SAMPLER_MIPMAP_MODES[] = {
static_cast<VkSamplerMipmapMode>(0), // NONE
VK_SAMPLER_MIPMAP_MODE_NEAREST, // POINT
VK_SAMPLER_MIPMAP_MODE_LINEAR, // LINEAR
VK_SAMPLER_MIPMAP_MODE_LINEAR, // ANISOTROPIC
};
const VkSamplerAddressMode VK_SAMPLER_ADDRESS_MODES[] = {
VK_SAMPLER_ADDRESS_MODE_REPEAT, // WRAP
VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, // MIRROR
VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // CLAMP
VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, // BORDER
};
const VkPipelineBindPoint VK_PIPELINE_BIND_POINTS[] = {
VK_PIPELINE_BIND_POINT_GRAPHICS,
VK_PIPELINE_BIND_POINT_COMPUTE,
VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR,
};
const VkResolveModeFlagBits VK_RESOLVE_MODES[] = {
VK_RESOLVE_MODE_NONE,
VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,
VK_RESOLVE_MODE_AVERAGE_BIT,
VK_RESOLVE_MODE_MIN_BIT,
VK_RESOLVE_MODE_MAX_BIT,
};
const VkImageLayout VK_IMAGE_LAYOUTS[] = {
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_GENERAL,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_IMAGE_LAYOUT_PREINITIALIZED,
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
};
const VkStencilFaceFlags VK_STENCIL_FACE_FLAGS[] = {
VK_STENCIL_FACE_FRONT_BIT,
VK_STENCIL_FACE_BACK_BIT,
VK_STENCIL_FACE_FRONT_AND_BACK,
};
const VkAccessFlags FULL_ACCESS_FLAGS =
VK_ACCESS_INDIRECT_COMMAND_READ_BIT |
VK_ACCESS_INDEX_READ_BIT |
VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT |
VK_ACCESS_UNIFORM_READ_BIT |
VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
VK_ACCESS_SHADER_READ_BIT |
VK_ACCESS_SHADER_WRITE_BIT |
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
VK_ACCESS_TRANSFER_READ_BIT |
VK_ACCESS_TRANSFER_WRITE_BIT |
VK_ACCESS_HOST_READ_BIT |
VK_ACCESS_HOST_WRITE_BIT;
void fullPipelineBarrier(VkCommandBuffer cmdBuff) {
#if CC_DEBUG > 0
VkMemoryBarrier memoryBarrier{VK_STRUCTURE_TYPE_MEMORY_BARRIER};
memoryBarrier.srcAccessMask = FULL_ACCESS_FLAGS;
memoryBarrier.dstAccessMask = FULL_ACCESS_FLAGS;
vkCmdPipelineBarrier(cmdBuff, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
0, 1, &memoryBarrier, 0, nullptr, 0, nullptr);
#endif
}
static constexpr ThsvsAccessType THSVS_ACCESS_TYPES[] = {
THSVS_ACCESS_NONE, // NONE
THSVS_ACCESS_INDIRECT_BUFFER, // INDIRECT_BUFFER
THSVS_ACCESS_INDEX_BUFFER, // INDEX_BUFFER
THSVS_ACCESS_VERTEX_BUFFER, // VERTEX_BUFFER
THSVS_ACCESS_VERTEX_SHADER_READ_UNIFORM_BUFFER, // VERTEX_SHADER_READ_UNIFORM_BUFFER
THSVS_ACCESS_VERTEX_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER, // VERTEX_SHADER_READ_TEXTURE
THSVS_ACCESS_VERTEX_SHADER_READ_OTHER, // VERTEX_SHADER_READ_OTHER
THSVS_ACCESS_FRAGMENT_SHADER_READ_UNIFORM_BUFFER, // FRAGMENT_SHADER_READ_UNIFORM_BUFFER
THSVS_ACCESS_FRAGMENT_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER, // FRAGMENT_SHADER_READ_TEXTURE
THSVS_ACCESS_FRAGMENT_SHADER_READ_COLOR_INPUT_ATTACHMENT, // FRAGMENT_SHADER_READ_COLOR_INPUT_ATTACHMENT
THSVS_ACCESS_FRAGMENT_SHADER_READ_DEPTH_STENCIL_INPUT_ATTACHMENT, // FRAGMENT_SHADER_READ_DEPTH_STENCIL_INPUT_ATTACHMENT
THSVS_ACCESS_FRAGMENT_SHADER_READ_OTHER, // FRAGMENT_SHADER_READ_OTHER
THSVS_ACCESS_COLOR_ATTACHMENT_READ, // COLOR_ATTACHMENT_READ
THSVS_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ, // DEPTH_STENCIL_ATTACHMENT_READ
THSVS_ACCESS_COMPUTE_SHADER_READ_UNIFORM_BUFFER, // COMPUTE_SHADER_READ_UNIFORM_BUFFER
THSVS_ACCESS_COMPUTE_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER, // COMPUTE_SHADER_READ_TEXTURE
THSVS_ACCESS_COMPUTE_SHADER_READ_OTHER, // COMPUTE_SHADER_READ_OTHER
THSVS_ACCESS_TRANSFER_READ, // TRANSFER_READ
THSVS_ACCESS_HOST_READ, // HOST_READ
THSVS_ACCESS_PRESENT, // PRESENT
THSVS_ACCESS_VERTEX_SHADER_WRITE, // VERTEX_SHADER_WRITE
THSVS_ACCESS_FRAGMENT_SHADER_WRITE, // FRAGMENT_SHADER_WRITE
THSVS_ACCESS_COLOR_ATTACHMENT_WRITE, // COLOR_ATTACHMENT_WRITE
THSVS_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE, // DEPTH_STENCIL_ATTACHMENT_WRITE
THSVS_ACCESS_COMPUTE_SHADER_WRITE, // COMPUTE_SHADER_WRITE
THSVS_ACCESS_TRANSFER_WRITE, // TRANSFER_WRITE
THSVS_ACCESS_HOST_PREINITIALIZED, // HOST_PREINITIALIZED
THSVS_ACCESS_HOST_WRITE, // HOST_WRITE
THSVS_ACCESS_SHADING_RATE_READ_NV, // SHADING_RATE
};
const ThsvsAccessType *getAccessType(AccessFlagBit flag) {
return &THSVS_ACCESS_TYPES[utils::getBitPosition(toNumber(flag))];
}
ThsvsImageLayout getAccessLayout(AccessFlags flag) {
if (hasAllFlags(flag, AccessFlagBit::FRAGMENT_SHADER_READ_COLOR_INPUT_ATTACHMENT | AccessFlagBit::COLOR_ATTACHMENT_WRITE) ||
hasAllFlags(flag, AccessFlagBit::FRAGMENT_SHADER_READ_DEPTH_STENCIL_INPUT_ATTACHMENT | AccessFlagBit::DEPTH_STENCIL_ATTACHMENT_WRITE)) {
return THSVS_IMAGE_LAYOUT_GENERAL;
}
return THSVS_IMAGE_LAYOUT_OPTIMAL;
}
void getAccessTypes(AccessFlags flag, ccstd::vector<ThsvsAccessType> &v) {
for (uint32_t mask = toNumber(flag); mask; mask = utils::clearLowestBit(mask)) {
v.push_back(THSVS_ACCESS_TYPES[utils::getBitPosition(utils::getLowestBit(mask))]);
}
}
VkDeviceSize roundUp(VkDeviceSize numToRound, uint32_t multiple) {
return ((numToRound + multiple - 1) / multiple) * multiple;
}
bool isLayerSupported(const char *required, const ccstd::vector<VkLayerProperties> &available) {
for (const VkLayerProperties &availableLayer : available) {
if (strcmp(availableLayer.layerName, required) == 0) {
return true;
}
}
return false;
}
bool isExtensionSupported(const char *required, const ccstd::vector<VkExtensionProperties> &available) {
for (const VkExtensionProperties &availableExtension : available) {
if (strcmp(availableExtension.extensionName, required) == 0) {
return true;
}
}
return false;
}
bool isFormatSupported(VkPhysicalDevice device, VkFormat format) {
VkFormatProperties properties;
vkGetPhysicalDeviceFormatProperties(device, format, &properties);
return (properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0;
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,100 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#define WIN32_LEAN_AND_MEAN
#include "base/Macros.h"
#include "base/StringUtil.h"
#include "base/Utils.h"
#include "gfx-base/GFXDef.h"
#include "vk_mem_alloc.h"
#include "volk.h"
#include "thsvs_simpler_vulkan_synchronization.h"
#define DEFAULT_TIMEOUT 10000000000 // 10 second
#define BARRIER_DEDUCTION_LEVEL_NONE 0
#define BARRIER_DEDUCTION_LEVEL_BASIC 1
#define BARRIER_DEDUCTION_LEVEL_FULL 2
#ifndef BARRIER_DEDUCTION_LEVEL
#define BARRIER_DEDUCTION_LEVEL BARRIER_DEDUCTION_LEVEL_BASIC
#endif
namespace cc {
namespace gfx {
class CCVKGPUDevice;
VkQueryType mapVkQueryType(QueryType type);
VkFormat mapVkFormat(Format format, const CCVKGPUDevice *gpuDevice);
VkAttachmentLoadOp mapVkLoadOp(LoadOp loadOp);
VkAttachmentStoreOp mapVkStoreOp(StoreOp storeOp);
VkBufferUsageFlagBits mapVkBufferUsageFlagBits(BufferUsage usage);
VkImageType mapVkImageType(TextureType type);
VkFormatFeatureFlags mapVkFormatFeatureFlags(TextureUsage usage);
VkImageUsageFlags mapVkImageUsageFlags(TextureUsage usage, TextureFlags textureFlags);
VkImageAspectFlags mapVkImageAspectFlags(Format format);
VkImageCreateFlags mapVkImageCreateFlags(TextureType type);
VkImageViewType mapVkImageViewType(TextureType viewType);
VkCommandBufferLevel mapVkCommandBufferLevel(CommandBufferType type);
VkDescriptorType mapVkDescriptorType(DescriptorType type);
VkColorComponentFlags mapVkColorComponentFlags(ColorMask colorMask);
VkShaderStageFlagBits mapVkShaderStageFlagBits(ShaderStageFlagBit stage);
VkShaderStageFlags mapVkShaderStageFlags(ShaderStageFlagBit stages);
SurfaceTransform mapSurfaceTransform(VkSurfaceTransformFlagBitsKHR transform);
ccstd::string mapVendorName(uint32_t vendorID);
void fullPipelineBarrier(VkCommandBuffer cmdBuff);
const ThsvsAccessType *getAccessType(AccessFlagBit flag);
ThsvsImageLayout getAccessLayout(AccessFlags flag);
void getAccessTypes(AccessFlags flag, ccstd::vector<ThsvsAccessType> &v);
VkDeviceSize roundUp(VkDeviceSize numToRound, uint32_t multiple);
bool isLayerSupported(const char *required, const ccstd::vector<VkLayerProperties> &available);
bool isExtensionSupported(const char *required, const ccstd::vector<VkExtensionProperties> &available);
bool isFormatSupported(VkPhysicalDevice device, VkFormat format);
extern const VkSurfaceTransformFlagsKHR TRANSFORMS_THAT_REQUIRE_FLIPPING;
extern const VkPrimitiveTopology VK_PRIMITIVE_MODES[];
extern const VkCullModeFlags VK_CULL_MODES[];
extern const VkPolygonMode VK_POLYGON_MODES[];
extern const VkCompareOp VK_CMP_FUNCS[];
extern const VkStencilOp VK_STENCIL_OPS[];
extern const VkBlendOp VK_BLEND_OPS[];
extern const VkBlendFactor VK_BLEND_FACTORS[];
extern const VkFilter VK_FILTERS[];
extern const VkSamplerMipmapMode VK_SAMPLER_MIPMAP_MODES[];
extern const VkSamplerAddressMode VK_SAMPLER_ADDRESS_MODES[];
extern const VkPipelineBindPoint VK_PIPELINE_BIND_POINTS[];
extern const VkResolveModeFlagBits VK_RESOLVE_MODES[];
extern const VkImageLayout VK_IMAGE_LAYOUTS[];
extern const VkStencilFaceFlags VK_STENCIL_FACE_FLAGS[];
extern const VkAccessFlags FULL_ACCESS_FLAGS;
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,59 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "VKBufferBarrier.h"
#include "../VKGPUObjects.h"
#include "../VKQueue.h"
#include "gfx-base/GFXDef-common.h"
#include "gfx-vulkan/thsvs_simpler_vulkan_synchronization.h"
namespace cc {
namespace gfx {
CCVKBufferBarrier::CCVKBufferBarrier(const BufferBarrierInfo &info) : BufferBarrier(info) {
_typedID = generateObjectID<decltype(this)>();
_gpuBarrier = std::make_unique<CCVKGPUBufferBarrier>();
getAccessTypes(info.prevAccesses, _gpuBarrier->prevAccesses);
getAccessTypes(info.nextAccesses, _gpuBarrier->nextAccesses);
_gpuBarrier->barrier.prevAccessCount = utils::toUint(_gpuBarrier->prevAccesses.size());
_gpuBarrier->barrier.pPrevAccesses = _gpuBarrier->prevAccesses.data();
_gpuBarrier->barrier.nextAccessCount = utils::toUint(_gpuBarrier->nextAccesses.size());
_gpuBarrier->barrier.pNextAccesses = _gpuBarrier->nextAccesses.data();
_gpuBarrier->barrier.offset = info.offset;
_gpuBarrier->barrier.size = info.size;
_gpuBarrier->barrier.srcQueueFamilyIndex = info.srcQueue
? static_cast<CCVKQueue *>(info.srcQueue)->gpuQueue()->queueFamilyIndex
: VK_QUEUE_FAMILY_IGNORED;
_gpuBarrier->barrier.dstQueueFamilyIndex = info.dstQueue
? static_cast<CCVKQueue *>(info.dstQueue)->gpuQueue()->queueFamilyIndex
: VK_QUEUE_FAMILY_IGNORED;
thsvsGetVulkanBufferMemoryBarrier(_gpuBarrier->barrier, &_gpuBarrier->srcStageMask, &_gpuBarrier->dstStageMask, &_gpuBarrier->vkBarrier);
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,47 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "../VKStd.h"
#include "gfx-base/states/GFXBufferBarrier.h"
namespace cc {
namespace gfx {
struct CCVKGPUBufferBarrier;
class CC_VULKAN_API CCVKBufferBarrier : public BufferBarrier {
public:
explicit CCVKBufferBarrier(const BufferBarrierInfo &info);
~CCVKBufferBarrier() override = default;
inline const CCVKGPUBufferBarrier *gpuBarrier() const { return _gpuBarrier.get(); }
protected:
std::unique_ptr<CCVKGPUBufferBarrier> _gpuBarrier;
};
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,43 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "VKGeneralBarrier.h"
#include "../VKCommands.h"
#include "../VKDevice.h"
namespace cc {
namespace gfx {
CCVKGeneralBarrier::CCVKGeneralBarrier(const GeneralBarrierInfo &info) : GeneralBarrier(info) {
_typedID = generateObjectID<decltype(this)>();
_gpuBarrier = std::make_unique<CCVKGPUGeneralBarrier>();
getAccessTypes(info.prevAccesses, _gpuBarrier->prevAccesses);
getAccessTypes(info.nextAccesses, _gpuBarrier->nextAccesses);
cmdFuncCCVKCreateGeneralBarrier(CCVKDevice::getInstance(), _gpuBarrier.get());
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,48 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include <memory>
#include "../VKStd.h"
#include "gfx-base/states/GFXGeneralBarrier.h"
namespace cc {
namespace gfx {
struct CCVKGPUGeneralBarrier;
class CC_VULKAN_API CCVKGeneralBarrier : public GeneralBarrier {
public:
explicit CCVKGeneralBarrier(const GeneralBarrierInfo &info);
~CCVKGeneralBarrier() override = default;
inline const CCVKGPUGeneralBarrier *gpuBarrier() const { return _gpuBarrier.get(); }
protected:
std::unique_ptr<CCVKGPUGeneralBarrier> _gpuBarrier;
};
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,57 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "VKSampler.h"
#include "../VKCommands.h"
#include "../VKDevice.h"
namespace cc {
namespace gfx {
CCVKSampler::CCVKSampler(const SamplerInfo &info) : Sampler(info) {
_typedID = generateObjectID<decltype(this)>();
_gpuSampler = ccnew CCVKGPUSampler;
_gpuSampler->minFilter = _info.minFilter;
_gpuSampler->magFilter = _info.magFilter;
_gpuSampler->mipFilter = _info.mipFilter;
_gpuSampler->addressU = _info.addressU;
_gpuSampler->addressV = _info.addressV;
_gpuSampler->addressW = _info.addressW;
_gpuSampler->maxAnisotropy = _info.maxAnisotropy;
_gpuSampler->cmpFunc = _info.cmpFunc;
_gpuSampler->init();
}
void CCVKGPUSampler::init() {
cmdFuncCCVKCreateSampler(CCVKDevice::getInstance(), this);
}
void CCVKGPUSampler::shutdown() {
CCVKDevice::getInstance()->gpuDescriptorHub()->disengage(this);
CCVKDevice::getInstance()->gpuRecycleBin()->collect(this);
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,46 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "../VKStd.h"
#include "gfx-base/states/GFXSampler.h"
#include "gfx-vulkan/VKGPUObjects.h"
namespace cc {
namespace gfx {
class CC_VULKAN_API CCVKSampler final : public Sampler {
public:
explicit CCVKSampler(const SamplerInfo &info);
~CCVKSampler() override = default;
inline CCVKGPUSampler *gpuSampler() const { return _gpuSampler; }
protected:
IntrusivePtr<CCVKGPUSampler> _gpuSampler;
};
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,62 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "VKTextureBarrier.h"
#include "../VKGPUObjects.h"
#include "../VKQueue.h"
namespace cc {
namespace gfx {
CCVKTextureBarrier::CCVKTextureBarrier(const TextureBarrierInfo &info) : TextureBarrier(info) {
_typedID = generateObjectID<decltype(this)>();
_gpuBarrier = std::make_unique<CCVKGPUTextureBarrier>();
getAccessTypes(info.prevAccesses, _gpuBarrier->prevAccesses);
getAccessTypes(info.nextAccesses, _gpuBarrier->nextAccesses);
_gpuBarrier->barrier.prevAccessCount = utils::toUint(_gpuBarrier->prevAccesses.size());
_gpuBarrier->barrier.pPrevAccesses = _gpuBarrier->prevAccesses.data();
_gpuBarrier->barrier.nextAccessCount = utils::toUint(_gpuBarrier->nextAccesses.size());
_gpuBarrier->barrier.pNextAccesses = _gpuBarrier->nextAccesses.data();
_gpuBarrier->barrier.prevLayout = getAccessLayout(info.prevAccesses);
_gpuBarrier->barrier.nextLayout = getAccessLayout(info.nextAccesses);
_gpuBarrier->barrier.discardContents = !!info.discardContents;
_gpuBarrier->barrier.subresourceRange.baseMipLevel = info.range.mipLevel;
_gpuBarrier->barrier.subresourceRange.levelCount = info.range.levelCount;
_gpuBarrier->barrier.subresourceRange.baseArrayLayer = info.range.firstSlice;
_gpuBarrier->barrier.subresourceRange.layerCount = info.range.numSlices;
_gpuBarrier->barrier.srcQueueFamilyIndex = info.srcQueue
? static_cast<CCVKQueue *>(info.srcQueue)->gpuQueue()->queueFamilyIndex
: VK_QUEUE_FAMILY_IGNORED;
_gpuBarrier->barrier.dstQueueFamilyIndex = info.dstQueue
? static_cast<CCVKQueue *>(info.dstQueue)->gpuQueue()->queueFamilyIndex
: VK_QUEUE_FAMILY_IGNORED;
thsvsGetVulkanImageMemoryBarrier(_gpuBarrier->barrier, &_gpuBarrier->srcStageMask, &_gpuBarrier->dstStageMask, &_gpuBarrier->vkBarrier);
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,47 @@
/****************************************************************************
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include <memory>
#include "../VKStd.h"
#include "gfx-base/states/GFXTextureBarrier.h"
namespace cc {
namespace gfx {
struct CCVKGPUTextureBarrier;
class CC_VULKAN_API CCVKTextureBarrier : public TextureBarrier {
public:
explicit CCVKTextureBarrier(const TextureBarrierInfo &info);
~CCVKTextureBarrier() override = default;
inline const CCVKGPUTextureBarrier *gpuBarrier() const { return _gpuBarrier.get(); }
protected:
std::unique_ptr<CCVKGPUTextureBarrier> _gpuBarrier;
};
} // namespace gfx
} // namespace cc

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff