| // Copyright 2021 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. | |
| #ifndef VK_STRUCT_CONVERSION_HPP_ | |
| #define VK_STRUCT_CONVERSION_HPP_ | |
| #include "VkMemory.hpp" | |
| #include "VkStringify.hpp" | |
| #include <cstring> | |
| #include <vector> | |
| namespace vk { | |
| struct CopyBufferInfo : public VkCopyBufferInfo2 | |
| { | |
| CopyBufferInfo(VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferCopy *pRegions) | |
| : VkCopyBufferInfo2{ | |
| VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2, | |
| nullptr, | |
| srcBuffer, | |
| dstBuffer, | |
| regionCount, | |
| nullptr | |
| } | |
| { | |
| regions.resize(regionCount); | |
| for(uint32_t i = 0; i < regionCount; i++) | |
| { | |
| regions[i] = { | |
| VK_STRUCTURE_TYPE_BUFFER_COPY_2, | |
| nullptr, | |
| pRegions[i].srcOffset, | |
| pRegions[i].dstOffset, | |
| pRegions[i].size | |
| }; | |
| } | |
| this->pRegions = ®ions.front(); | |
| } | |
| private: | |
| std::vector<VkBufferCopy2> regions; | |
| }; | |
| struct CopyImageInfo : public VkCopyImageInfo2 | |
| { | |
| CopyImageInfo(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageCopy *pRegions) | |
| : VkCopyImageInfo2{ | |
| VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2, | |
| nullptr, | |
| srcImage, | |
| srcImageLayout, | |
| dstImage, | |
| dstImageLayout, | |
| regionCount, | |
| nullptr | |
| } | |
| { | |
| regions.resize(regionCount); | |
| for(uint32_t i = 0; i < regionCount; i++) | |
| { | |
| regions[i] = { | |
| VK_STRUCTURE_TYPE_IMAGE_COPY_2, | |
| nullptr, | |
| pRegions[i].srcSubresource, | |
| pRegions[i].srcOffset, | |
| pRegions[i].dstSubresource, | |
| pRegions[i].dstOffset, | |
| pRegions[i].extent | |
| }; | |
| } | |
| this->pRegions = ®ions.front(); | |
| } | |
| private: | |
| std::vector<VkImageCopy2> regions; | |
| }; | |
| struct BlitImageInfo : public VkBlitImageInfo2 | |
| { | |
| BlitImageInfo(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageBlit *pRegions, VkFilter filter) | |
| : VkBlitImageInfo2{ | |
| VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2, | |
| nullptr, | |
| srcImage, | |
| srcImageLayout, | |
| dstImage, | |
| dstImageLayout, | |
| regionCount, | |
| nullptr, | |
| filter | |
| } | |
| { | |
| regions.resize(regionCount); | |
| for(uint32_t i = 0; i < regionCount; i++) | |
| { | |
| regions[i] = { | |
| VK_STRUCTURE_TYPE_IMAGE_BLIT_2, | |
| nullptr, | |
| pRegions[i].srcSubresource, | |
| { pRegions[i].srcOffsets[0], pRegions[i].srcOffsets[1] }, | |
| pRegions[i].dstSubresource, | |
| { pRegions[i].dstOffsets[0], pRegions[i].dstOffsets[1] } | |
| }; | |
| } | |
| this->pRegions = ®ions.front(); | |
| } | |
| private: | |
| std::vector<VkImageBlit2> regions; | |
| }; | |
| struct CopyBufferToImageInfo : public VkCopyBufferToImageInfo2 | |
| { | |
| CopyBufferToImageInfo(VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkBufferImageCopy *pRegions) | |
| : VkCopyBufferToImageInfo2{ | |
| VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2, | |
| nullptr, | |
| srcBuffer, | |
| dstImage, | |
| dstImageLayout, | |
| regionCount, | |
| nullptr | |
| } | |
| { | |
| regions.resize(regionCount); | |
| for(uint32_t i = 0; i < regionCount; i++) | |
| { | |
| regions[i] = { | |
| VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2, | |
| nullptr, | |
| pRegions[i].bufferOffset, | |
| pRegions[i].bufferRowLength, | |
| pRegions[i].bufferImageHeight, | |
| pRegions[i].imageSubresource, | |
| pRegions[i].imageOffset, | |
| pRegions[i].imageExtent | |
| }; | |
| } | |
| this->pRegions = ®ions.front(); | |
| } | |
| private: | |
| std::vector<VkBufferImageCopy2> regions; | |
| }; | |
| struct CopyImageToBufferInfo : public VkCopyImageToBufferInfo2 | |
| { | |
| CopyImageToBufferInfo(VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy *pRegions) | |
| : VkCopyImageToBufferInfo2{ | |
| VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2, | |
| nullptr, | |
| srcImage, | |
| srcImageLayout, | |
| dstBuffer, | |
| regionCount, | |
| nullptr | |
| } | |
| { | |
| regions.resize(regionCount); | |
| for(uint32_t i = 0; i < regionCount; i++) | |
| { | |
| regions[i] = { | |
| VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2, | |
| nullptr, | |
| pRegions[i].bufferOffset, | |
| pRegions[i].bufferRowLength, | |
| pRegions[i].bufferImageHeight, | |
| pRegions[i].imageSubresource, | |
| pRegions[i].imageOffset, | |
| pRegions[i].imageExtent | |
| }; | |
| } | |
| this->pRegions = ®ions.front(); | |
| } | |
| private: | |
| std::vector<VkBufferImageCopy2> regions; | |
| }; | |
| struct ResolveImageInfo : public VkResolveImageInfo2 | |
| { | |
| ResolveImageInfo(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageResolve *pRegions) | |
| : VkResolveImageInfo2{ | |
| VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2, | |
| nullptr, | |
| srcImage, | |
| srcImageLayout, | |
| dstImage, | |
| dstImageLayout, | |
| regionCount, | |
| nullptr | |
| } | |
| { | |
| regions.resize(regionCount); | |
| for(uint32_t i = 0; i < regionCount; i++) | |
| { | |
| regions[i] = { | |
| VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2, | |
| nullptr, | |
| pRegions[i].srcSubresource, | |
| pRegions[i].srcOffset, | |
| pRegions[i].dstSubresource, | |
| pRegions[i].dstOffset, | |
| pRegions[i].extent | |
| }; | |
| } | |
| this->pRegions = ®ions.front(); | |
| } | |
| private: | |
| std::vector<VkImageResolve2> regions; | |
| }; | |
| struct DependencyInfo : public VkDependencyInfo | |
| { | |
| DependencyInfo(VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, | |
| VkDependencyFlags dependencyFlags, | |
| uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, | |
| uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers, | |
| uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) | |
| : VkDependencyInfo{ | |
| VK_STRUCTURE_TYPE_DEPENDENCY_INFO, | |
| nullptr, | |
| dependencyFlags, | |
| memoryBarrierCount, | |
| nullptr, | |
| bufferMemoryBarrierCount, | |
| nullptr, | |
| imageMemoryBarrierCount, | |
| nullptr | |
| } | |
| { | |
| if((memoryBarrierCount == 0) && | |
| (bufferMemoryBarrierCount == 0) && | |
| (imageMemoryBarrierCount == 0)) | |
| { | |
| // Create a single memory barrier entry to store the source and destination stage masks | |
| memoryBarriers.resize(1); | |
| memoryBarriers[0] = { | |
| VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, | |
| nullptr, | |
| srcStageMask, | |
| VK_ACCESS_2_NONE, | |
| dstStageMask, | |
| VK_ACCESS_2_NONE | |
| }; | |
| } | |
| else | |
| { | |
| memoryBarriers.resize(memoryBarrierCount); | |
| for(uint32_t i = 0; i < memoryBarrierCount; i++) | |
| { | |
| memoryBarriers[i] = { | |
| VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, | |
| pMemoryBarriers[i].pNext, | |
| srcStageMask, | |
| pMemoryBarriers[i].srcAccessMask, | |
| dstStageMask, | |
| pMemoryBarriers[i].dstAccessMask | |
| }; | |
| } | |
| bufferMemoryBarriers.resize(bufferMemoryBarrierCount); | |
| for(uint32_t i = 0; i < bufferMemoryBarrierCount; i++) | |
| { | |
| bufferMemoryBarriers[i] = { | |
| VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2, | |
| pBufferMemoryBarriers[i].pNext, | |
| srcStageMask, | |
| pBufferMemoryBarriers[i].srcAccessMask, | |
| dstStageMask, | |
| pBufferMemoryBarriers[i].dstAccessMask, | |
| pBufferMemoryBarriers[i].srcQueueFamilyIndex, | |
| pBufferMemoryBarriers[i].dstQueueFamilyIndex, | |
| pBufferMemoryBarriers[i].buffer, | |
| pBufferMemoryBarriers[i].offset, | |
| pBufferMemoryBarriers[i].size | |
| }; | |
| } | |
| imageMemoryBarriers.resize(imageMemoryBarrierCount); | |
| for(uint32_t i = 0; i < imageMemoryBarrierCount; i++) | |
| { | |
| imageMemoryBarriers[i] = { | |
| VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, | |
| pImageMemoryBarriers[i].pNext, | |
| srcStageMask, | |
| pImageMemoryBarriers[i].srcAccessMask, | |
| dstStageMask, | |
| pImageMemoryBarriers[i].dstAccessMask, | |
| pImageMemoryBarriers[i].oldLayout, | |
| pImageMemoryBarriers[i].newLayout, | |
| pImageMemoryBarriers[i].srcQueueFamilyIndex, | |
| pImageMemoryBarriers[i].dstQueueFamilyIndex, | |
| pImageMemoryBarriers[i].image, | |
| pImageMemoryBarriers[i].subresourceRange | |
| }; | |
| } | |
| } | |
| this->pMemoryBarriers = memoryBarriers.empty() ? nullptr : &memoryBarriers.front(); | |
| this->pBufferMemoryBarriers = bufferMemoryBarriers.empty() ? nullptr : &bufferMemoryBarriers.front(); | |
| this->pImageMemoryBarriers = imageMemoryBarriers.empty() ? nullptr : &imageMemoryBarriers.front(); | |
| } | |
| private: | |
| std::vector<VkMemoryBarrier2> memoryBarriers; | |
| std::vector<VkBufferMemoryBarrier2> bufferMemoryBarriers; | |
| std::vector<VkImageMemoryBarrier2> imageMemoryBarriers; | |
| }; | |
| struct ImageSubresource : VkImageSubresource | |
| { | |
| ImageSubresource(const VkImageSubresourceLayers &subresourceLayers) | |
| : VkImageSubresource{ | |
| subresourceLayers.aspectMask, | |
| subresourceLayers.mipLevel, | |
| subresourceLayers.baseArrayLayer | |
| } | |
| {} | |
| }; | |
| struct ImageSubresourceRange : VkImageSubresourceRange | |
| { | |
| ImageSubresourceRange(const VkImageSubresourceLayers &subresourceLayers) | |
| : VkImageSubresourceRange{ | |
| subresourceLayers.aspectMask, | |
| subresourceLayers.mipLevel, | |
| 1, | |
| subresourceLayers.baseArrayLayer, | |
| subresourceLayers.layerCount | |
| } | |
| {} | |
| }; | |
| struct Extent2D : VkExtent2D | |
| { | |
| Extent2D(const VkExtent3D &extent3D) | |
| : VkExtent2D{ extent3D.width, extent3D.height } | |
| {} | |
| }; | |
| struct SubmitInfo | |
| { | |
| static SubmitInfo *Allocate(uint32_t submitCount, const VkSubmitInfo *pSubmits) | |
| { | |
| size_t submitSize = sizeof(SubmitInfo) * submitCount; | |
| size_t totalSize = submitSize; | |
| for(uint32_t i = 0; i < submitCount; i++) | |
| { | |
| totalSize += pSubmits[i].waitSemaphoreCount * sizeof(VkSemaphore); | |
| totalSize += pSubmits[i].waitSemaphoreCount * sizeof(VkPipelineStageFlags); | |
| totalSize += pSubmits[i].signalSemaphoreCount * sizeof(VkSemaphore); | |
| totalSize += pSubmits[i].commandBufferCount * sizeof(VkCommandBuffer); | |
| for(const auto *extension = reinterpret_cast<const VkBaseInStructure *>(pSubmits[i].pNext); | |
| extension != nullptr; extension = reinterpret_cast<const VkBaseInStructure *>(extension->pNext)) | |
| { | |
| switch(extension->sType) | |
| { | |
| case VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO: | |
| { | |
| const auto *tlsSubmitInfo = reinterpret_cast<const VkTimelineSemaphoreSubmitInfo *>(extension); | |
| totalSize += tlsSubmitInfo->waitSemaphoreValueCount * sizeof(uint64_t); | |
| totalSize += tlsSubmitInfo->signalSemaphoreValueCount * sizeof(uint64_t); | |
| } | |
| break; | |
| case VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO: | |
| // SwiftShader doesn't use device group submit info because it only supports a single physical device. | |
| // However, this extension is core in Vulkan 1.1, so we must treat it as a valid structure type. | |
| break; | |
| case VK_STRUCTURE_TYPE_MAX_ENUM: | |
| // dEQP tests that this value is ignored. | |
| break; | |
| default: | |
| UNSUPPORTED("submitInfo[%d]->pNext sType: %s", i, vk::Stringify(extension->sType).c_str()); | |
| break; | |
| } | |
| } | |
| } | |
| uint8_t *mem = static_cast<uint8_t *>( | |
| vk::allocateHostMemory(totalSize, vk::HOST_MEMORY_ALLOCATION_ALIGNMENT, vk::NULL_ALLOCATION_CALLBACKS, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT)); | |
| auto submits = new(mem) SubmitInfo[submitCount]; | |
| mem += submitSize; | |
| for(uint32_t i = 0; i < submitCount; i++) | |
| { | |
| submits[i].commandBufferCount = pSubmits[i].commandBufferCount; | |
| submits[i].signalSemaphoreCount = pSubmits[i].signalSemaphoreCount; | |
| submits[i].waitSemaphoreCount = pSubmits[i].waitSemaphoreCount; | |
| submits[i].pWaitSemaphores = nullptr; | |
| submits[i].pWaitDstStageMask = nullptr; | |
| submits[i].pSignalSemaphores = nullptr; | |
| submits[i].pCommandBuffers = nullptr; | |
| if(pSubmits[i].waitSemaphoreCount > 0) | |
| { | |
| size_t size = pSubmits[i].waitSemaphoreCount * sizeof(VkSemaphore); | |
| submits[i].pWaitSemaphores = reinterpret_cast<VkSemaphore *>(mem); | |
| memcpy(mem, pSubmits[i].pWaitSemaphores, size); | |
| mem += size; | |
| size = pSubmits[i].waitSemaphoreCount * sizeof(VkPipelineStageFlags); | |
| submits[i].pWaitDstStageMask = reinterpret_cast<VkPipelineStageFlags *>(mem); | |
| memcpy(mem, pSubmits[i].pWaitDstStageMask, size); | |
| mem += size; | |
| } | |
| if(pSubmits[i].signalSemaphoreCount > 0) | |
| { | |
| size_t size = pSubmits[i].signalSemaphoreCount * sizeof(VkSemaphore); | |
| submits[i].pSignalSemaphores = reinterpret_cast<VkSemaphore *>(mem); | |
| memcpy(mem, pSubmits[i].pSignalSemaphores, size); | |
| mem += size; | |
| } | |
| if(pSubmits[i].commandBufferCount > 0) | |
| { | |
| size_t size = pSubmits[i].commandBufferCount * sizeof(VkCommandBuffer); | |
| submits[i].pCommandBuffers = reinterpret_cast<VkCommandBuffer *>(mem); | |
| memcpy(mem, pSubmits[i].pCommandBuffers, size); | |
| mem += size; | |
| } | |
| submits[i].waitSemaphoreValueCount = 0; | |
| submits[i].pWaitSemaphoreValues = nullptr; | |
| submits[i].signalSemaphoreValueCount = 0; | |
| submits[i].pSignalSemaphoreValues = nullptr; | |
| for(const auto *extension = reinterpret_cast<const VkBaseInStructure *>(pSubmits[i].pNext); | |
| extension != nullptr; extension = reinterpret_cast<const VkBaseInStructure *>(extension->pNext)) | |
| { | |
| switch(extension->sType) | |
| { | |
| case VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO: | |
| { | |
| const VkTimelineSemaphoreSubmitInfo *tlsSubmitInfo = reinterpret_cast<const VkTimelineSemaphoreSubmitInfo *>(extension); | |
| if(tlsSubmitInfo->waitSemaphoreValueCount > 0) | |
| { | |
| submits[i].waitSemaphoreValueCount = tlsSubmitInfo->waitSemaphoreValueCount; | |
| size_t size = tlsSubmitInfo->waitSemaphoreValueCount * sizeof(uint64_t); | |
| submits[i].pWaitSemaphoreValues = reinterpret_cast<uint64_t *>(mem); | |
| memcpy(mem, tlsSubmitInfo->pWaitSemaphoreValues, size); | |
| mem += size; | |
| } | |
| if(tlsSubmitInfo->signalSemaphoreValueCount > 0) | |
| { | |
| submits[i].signalSemaphoreValueCount = tlsSubmitInfo->signalSemaphoreValueCount; | |
| size_t size = tlsSubmitInfo->signalSemaphoreValueCount * sizeof(uint64_t); | |
| submits[i].pSignalSemaphoreValues = reinterpret_cast<uint64_t *>(mem); | |
| memcpy(mem, tlsSubmitInfo->pSignalSemaphoreValues, size); | |
| mem += size; | |
| } | |
| } | |
| break; | |
| case VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO: | |
| // SwiftShader doesn't use device group submit info because it only supports a single physical device. | |
| // However, this extension is core in Vulkan 1.1, so we must treat it as a valid structure type. | |
| break; | |
| case VK_STRUCTURE_TYPE_MAX_ENUM: | |
| // dEQP tests that this value is ignored. | |
| break; | |
| default: | |
| UNSUPPORTED("submitInfo[%d]->pNext sType: %s", i, vk::Stringify(extension->sType).c_str()); | |
| break; | |
| } | |
| } | |
| } | |
| return submits; | |
| } | |
| static SubmitInfo *Allocate(uint32_t submitCount, const VkSubmitInfo2 *pSubmits) | |
| { | |
| size_t submitSize = sizeof(SubmitInfo) * submitCount; | |
| size_t totalSize = submitSize; | |
| for(uint32_t i = 0; i < submitCount; i++) | |
| { | |
| totalSize += pSubmits[i].waitSemaphoreInfoCount * sizeof(VkSemaphore); | |
| totalSize += pSubmits[i].waitSemaphoreInfoCount * sizeof(VkPipelineStageFlags); | |
| totalSize += pSubmits[i].waitSemaphoreInfoCount * sizeof(uint64_t); | |
| totalSize += pSubmits[i].signalSemaphoreInfoCount * sizeof(VkSemaphore); | |
| totalSize += pSubmits[i].signalSemaphoreInfoCount * sizeof(uint64_t); | |
| totalSize += pSubmits[i].commandBufferInfoCount * sizeof(VkCommandBuffer); | |
| for(const auto *extension = reinterpret_cast<const VkBaseInStructure *>(pSubmits[i].pNext); | |
| extension != nullptr; extension = reinterpret_cast<const VkBaseInStructure *>(extension->pNext)) | |
| { | |
| switch(extension->sType) | |
| { | |
| case VK_STRUCTURE_TYPE_MAX_ENUM: | |
| // dEQP tests that this value is ignored. | |
| break; | |
| case VK_STRUCTURE_TYPE_PERFORMANCE_QUERY_SUBMIT_INFO_KHR: // VK_KHR_performance_query | |
| case VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR: // VK_KHR_win32_keyed_mutex | |
| case VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV: // VK_NV_win32_keyed_mutex | |
| default: | |
| UNSUPPORTED("submitInfo[%d]->pNext sType: %s", i, vk::Stringify(extension->sType).c_str()); | |
| break; | |
| } | |
| } | |
| } | |
| uint8_t *mem = static_cast<uint8_t *>( | |
| vk::allocateHostMemory(totalSize, vk::HOST_MEMORY_ALLOCATION_ALIGNMENT, vk::NULL_ALLOCATION_CALLBACKS, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT)); | |
| auto submits = new(mem) SubmitInfo[submitCount]; | |
| mem += submitSize; | |
| for(uint32_t i = 0; i < submitCount; i++) | |
| { | |
| submits[i].commandBufferCount = pSubmits[i].commandBufferInfoCount; | |
| submits[i].signalSemaphoreCount = pSubmits[i].signalSemaphoreInfoCount; | |
| submits[i].waitSemaphoreCount = pSubmits[i].waitSemaphoreInfoCount; | |
| submits[i].signalSemaphoreValueCount = pSubmits[i].signalSemaphoreInfoCount; | |
| submits[i].waitSemaphoreValueCount = pSubmits[i].waitSemaphoreInfoCount; | |
| submits[i].pWaitSemaphores = nullptr; | |
| submits[i].pWaitDstStageMask = nullptr; | |
| submits[i].pSignalSemaphores = nullptr; | |
| submits[i].pCommandBuffers = nullptr; | |
| submits[i].pWaitSemaphoreValues = nullptr; | |
| submits[i].pSignalSemaphoreValues = nullptr; | |
| if(submits[i].waitSemaphoreCount > 0) | |
| { | |
| size_t size = submits[i].waitSemaphoreCount * sizeof(VkSemaphore); | |
| submits[i].pWaitSemaphores = reinterpret_cast<VkSemaphore *>(mem); | |
| mem += size; | |
| size = submits[i].waitSemaphoreCount * sizeof(VkPipelineStageFlags); | |
| submits[i].pWaitDstStageMask = reinterpret_cast<VkPipelineStageFlags *>(mem); | |
| mem += size; | |
| size = submits[i].waitSemaphoreCount * sizeof(uint64_t); | |
| submits[i].pWaitSemaphoreValues = reinterpret_cast<uint64_t *>(mem); | |
| mem += size; | |
| for(uint32_t j = 0; j < submits[i].waitSemaphoreCount; j++) | |
| { | |
| submits[i].pWaitSemaphores[j] = pSubmits[i].pWaitSemaphoreInfos[j].semaphore; | |
| submits[i].pWaitDstStageMask[j] = pSubmits[i].pWaitSemaphoreInfos[j].stageMask; | |
| submits[i].pWaitSemaphoreValues[j] = pSubmits[i].pWaitSemaphoreInfos[j].value; | |
| } | |
| } | |
| if(submits[i].signalSemaphoreCount > 0) | |
| { | |
| size_t size = submits[i].signalSemaphoreCount * sizeof(VkSemaphore); | |
| submits[i].pSignalSemaphores = reinterpret_cast<VkSemaphore *>(mem); | |
| mem += size; | |
| size = submits[i].signalSemaphoreCount * sizeof(uint64_t); | |
| submits[i].pSignalSemaphoreValues = reinterpret_cast<uint64_t *>(mem); | |
| mem += size; | |
| for(uint32_t j = 0; j < submits[i].signalSemaphoreCount; j++) | |
| { | |
| submits[i].pSignalSemaphores[j] = pSubmits[i].pSignalSemaphoreInfos[j].semaphore; | |
| submits[i].pSignalSemaphoreValues[j] = pSubmits[i].pSignalSemaphoreInfos[j].value; | |
| } | |
| } | |
| if(submits[i].commandBufferCount > 0) | |
| { | |
| size_t size = submits[i].commandBufferCount * sizeof(VkCommandBuffer); | |
| submits[i].pCommandBuffers = reinterpret_cast<VkCommandBuffer *>(mem); | |
| mem += size; | |
| for(uint32_t j = 0; j < submits[i].commandBufferCount; j++) | |
| { | |
| submits[i].pCommandBuffers[j] = pSubmits[i].pCommandBufferInfos[j].commandBuffer; | |
| } | |
| } | |
| } | |
| return submits; | |
| } | |
| static void Release(SubmitInfo *submitInfo) | |
| { | |
| vk::freeHostMemory(submitInfo, NULL_ALLOCATION_CALLBACKS); | |
| } | |
| uint32_t waitSemaphoreCount; | |
| VkSemaphore *pWaitSemaphores; | |
| VkPipelineStageFlags *pWaitDstStageMask; | |
| uint32_t commandBufferCount; | |
| VkCommandBuffer *pCommandBuffers; | |
| uint32_t signalSemaphoreCount; | |
| VkSemaphore *pSignalSemaphores; | |
| uint32_t waitSemaphoreValueCount; | |
| uint64_t *pWaitSemaphoreValues; | |
| uint32_t signalSemaphoreValueCount; | |
| uint64_t *pSignalSemaphoreValues; | |
| }; | |
| } // namespace vk | |
| #endif // VK_STRUCT_CONVERSION_HPP_ |