diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index cd804b498..c6ceda9db 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1523,6 +1523,60 @@ namespace dxvk { } + void DxvkContext::initSparseImage( + const Rc& image) { + auto vk = m_device->vkd(); + + // Query sparse memory requirements + uint32_t reqCount = 0; + vk->vkGetImageSparseMemoryRequirements(vk->device(), image->handle(), &reqCount, nullptr); + + std::vector req(reqCount); + vk->vkGetImageSparseMemoryRequirements(vk->device(), image->handle(), &reqCount, req.data()); + + // Bind metadata aspects. Since the image was just created, + // we do not need to interrupt our command list for that. + VkDeviceMemory imageMemory = image->memory().memory(); + VkDeviceSize imageOffset = image->memory().offset(); + + for (const auto& r : req) { + if (!(r.formatProperties.aspectMask & VK_IMAGE_ASPECT_METADATA_BIT)) + continue; + + uint32_t layerCount = (r.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT) + ? 1u : image->info().numLayers; + + for (uint32_t i = 0; i < layerCount; i++) { + DxvkSparseImageOpaqueBindKey key; + key.image = image->handle(); + key.offset = r.imageMipTailOffset + i * r.imageMipTailStride; + key.size = r.imageMipTailSize; + key.flags = VK_SPARSE_MEMORY_BIND_METADATA_BIT; + + DxvkSparsePageHandle page; + page.memory = imageMemory; + page.offset = imageOffset; + page.length = r.imageMipTailSize; + + m_cmd->bindImageOpaqueMemory(key, page); + + imageOffset += r.imageMipTailSize; + } + } + + // Perform initial layout transition + m_initBarriers.accessImage(image, + image->getAvailableSubresources(), + VK_IMAGE_LAYOUT_UNDEFINED, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, + image->info().layout, + image->info().stages, + image->info().access); + + m_cmd->trackResource(image); + } + + void DxvkContext::emitGraphicsBarrier( VkPipelineStageFlags srcStages, VkAccessFlags srcAccess, diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index b9ec506cd..aa42ef79f 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -905,7 +905,17 @@ namespace dxvk { const Rc& image, const VkImageSubresourceRange& subresources, VkImageLayout initialLayout); - + + /** + * \brief Initializes sparse image + * + * Binds any metadata aspects that the image might + * have, and performs the initial layout transition. + * \param [in] image Image to initialize + */ + void initSparseImage( + const Rc& image); + /** * \brief Invalidates a buffer's contents *