// Copyright 2018 The SwiftShader Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "VkRenderPass.hpp" #include <cstring> namespace vk { RenderPass::RenderPass(const VkRenderPassCreateInfo* pCreateInfo, void* mem) : attachmentCount(pCreateInfo->attachmentCount), subpassCount(pCreateInfo->subpassCount), dependencyCount(pCreateInfo->dependencyCount) { char* hostMemory = reinterpret_cast<char*>(mem); // subpassCount must be greater than 0 ASSERT(pCreateInfo->subpassCount > 0); size_t subpassesSize = pCreateInfo->subpassCount * sizeof(VkSubpassDescription); subpasses = reinterpret_cast<VkSubpassDescription*>(hostMemory); memcpy(subpasses, pCreateInfo->pSubpasses, subpassesSize); hostMemory += subpassesSize; if(pCreateInfo->attachmentCount > 0) { size_t attachmentSize = pCreateInfo->attachmentCount * sizeof(VkAttachmentDescription); attachments = reinterpret_cast<VkAttachmentDescription*>(hostMemory); memcpy(attachments, pCreateInfo->pAttachments, attachmentSize); hostMemory += attachmentSize; } // Deep copy subpasses for(uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { const auto& subpass = pCreateInfo->pSubpasses[i]; subpasses[i].pInputAttachments = nullptr; subpasses[i].pColorAttachments = nullptr; subpasses[i].pResolveAttachments = nullptr; subpasses[i].pDepthStencilAttachment = nullptr; subpasses[i].pPreserveAttachments = nullptr; if(subpass.inputAttachmentCount > 0) { size_t inputAttachmentsSize = subpass.inputAttachmentCount * sizeof(VkAttachmentReference); subpasses[i].pInputAttachments = reinterpret_cast<VkAttachmentReference*>(hostMemory); memcpy(const_cast<VkAttachmentReference*>(subpasses[i].pInputAttachments), pCreateInfo->pSubpasses[i].pInputAttachments, inputAttachmentsSize); hostMemory += inputAttachmentsSize; } if(subpass.colorAttachmentCount > 0) { size_t colorAttachmentsSize = subpass.colorAttachmentCount * sizeof(VkAttachmentReference); subpasses[i].pColorAttachments = reinterpret_cast<VkAttachmentReference*>(hostMemory); memcpy(const_cast<VkAttachmentReference*>(subpasses[i].pColorAttachments), pCreateInfo->pSubpasses[i].pColorAttachments, colorAttachmentsSize); hostMemory += colorAttachmentsSize; if(subpass.pResolveAttachments != nullptr) { subpasses[i].pResolveAttachments = reinterpret_cast<VkAttachmentReference*>(hostMemory); memcpy(const_cast<VkAttachmentReference*>(subpasses[i].pResolveAttachments), pCreateInfo->pSubpasses[i].pResolveAttachments, colorAttachmentsSize); hostMemory += colorAttachmentsSize; } } if(subpass.pDepthStencilAttachment != nullptr) { subpasses[i].pDepthStencilAttachment = reinterpret_cast<VkAttachmentReference*>(hostMemory); memcpy(const_cast<VkAttachmentReference*>(subpasses[i].pDepthStencilAttachment), pCreateInfo->pSubpasses[i].pDepthStencilAttachment, sizeof(VkAttachmentReference)); hostMemory += sizeof(VkAttachmentReference); } if(subpass.preserveAttachmentCount > 0) { size_t preserveAttachmentSize = subpass.preserveAttachmentCount * sizeof(uint32_t); subpasses[i].pPreserveAttachments = reinterpret_cast<uint32_t*>(hostMemory); memcpy(const_cast<uint32_t*>(subpasses[i].pPreserveAttachments), pCreateInfo->pSubpasses[i].pPreserveAttachments, preserveAttachmentSize); hostMemory += preserveAttachmentSize; } } if(pCreateInfo->dependencyCount > 0) { size_t dependenciesSize = pCreateInfo->dependencyCount * sizeof(VkSubpassDependency); dependencies = reinterpret_cast<VkSubpassDependency*>(hostMemory); memcpy(dependencies, pCreateInfo->pDependencies, dependenciesSize); } } void RenderPass::destroy(const VkAllocationCallbacks* pAllocator) { vk::deallocate(subpasses, pAllocator); // attachments and dependencies are in the same allocation } size_t RenderPass::ComputeRequiredAllocationSize(const VkRenderPassCreateInfo* pCreateInfo) { size_t attachmentSize = pCreateInfo->attachmentCount * sizeof(VkAttachmentDescription); size_t subpassesSize = 0; for(uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { const auto& subpass = pCreateInfo->pSubpasses[i]; uint32_t nbAttachments = subpass.inputAttachmentCount + subpass.colorAttachmentCount; if(subpass.pResolveAttachments != nullptr) { nbAttachments += subpass.colorAttachmentCount; } if(subpass.pDepthStencilAttachment != nullptr) { nbAttachments += 1; } subpassesSize += sizeof(VkSubpassDescription) + sizeof(VkAttachmentReference) * nbAttachments + sizeof(uint32_t) * subpass.preserveAttachmentCount; } size_t dependenciesSize = pCreateInfo->dependencyCount * sizeof(VkSubpassDependency); return attachmentSize + subpassesSize + dependenciesSize; } void RenderPass::begin() { currentSubpass = 0; } void RenderPass::nextSubpass() { ++currentSubpass; ASSERT(currentSubpass < subpassCount); } void RenderPass::end() { currentSubpass = 0; } } // namespace vk