diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index ba889069d..66399112d 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1553,53 +1553,72 @@ namespace dxvk { this->spillRenderPass(false); this->invalidateState(); - m_execBarriers.recordCommands(m_cmd); + // Create image views, etc. + Rc mipGenerator = new DxvkMetaMipGenRenderPass(m_device->vkd(), imageView); - // Create the a set of framebuffers and image views - const Rc mipGenerator - = new DxvkMetaMipGenRenderPass(m_device->vkd(), imageView); + if (m_execBarriers.isImageDirty(imageView->image(), imageView->imageSubresources(), DxvkAccess::Write)) + m_execBarriers.recordCommands(m_cmd); + + VkImageLayout dstLayout = imageView->pickLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + VkImageLayout srcLayout = imageView->pickLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + + // If necessary, transition first mip level to the read-only layout + if (imageView->imageInfo().layout != srcLayout) { + m_execAcquires.accessImage(imageView->image(), + mipGenerator->getTopSubresource(), + imageView->imageInfo().layout, + imageView->imageInfo().stages, 0, + srcLayout, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_ACCESS_SHADER_READ_BIT); + } + + // If necessary, initialize all levels that are written to + if (imageView->imageInfo().layout != dstLayout) { + m_execAcquires.accessImage(imageView->image(), + mipGenerator->getAllTargetSubresources(), + VK_IMAGE_LAYOUT_UNDEFINED, + imageView->imageInfo().stages, 0, + dstLayout, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT); + } + + m_execAcquires.recordCommands(m_cmd); // Common descriptor set properties that we use to // bind the source image view to the fragment shader - VkDescriptorImageInfo descriptorImage; + VkDescriptorImageInfo descriptorImage = { }; descriptorImage.sampler = m_common->metaBlit().getSampler(filter); - descriptorImage.imageView = VK_NULL_HANDLE; - descriptorImage.imageLayout = imageView->imageInfo().layout; + descriptorImage.imageLayout = srcLayout; - VkWriteDescriptorSet descriptorWrite; - descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - descriptorWrite.pNext = nullptr; - descriptorWrite.dstSet = VK_NULL_HANDLE; + VkWriteDescriptorSet descriptorWrite = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET }; descriptorWrite.dstBinding = 0; descriptorWrite.dstArrayElement = 0; descriptorWrite.descriptorCount = 1; descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; descriptorWrite.pImageInfo = &descriptorImage; - descriptorWrite.pBufferInfo = nullptr; - descriptorWrite.pTexelBufferView = nullptr; // Common render pass info - VkRenderPassBeginInfo passInfo; - passInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - passInfo.pNext = nullptr; - passInfo.renderPass = mipGenerator->renderPass(); - passInfo.framebuffer = VK_NULL_HANDLE; - passInfo.renderArea = VkRect2D { }; - passInfo.clearValueCount = 0; - passInfo.pClearValues = nullptr; + VkRenderingAttachmentInfoKHR attachmentInfo = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR }; + attachmentInfo.imageLayout = dstLayout; + attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + + VkRenderingInfoKHR renderingInfo = { VK_STRUCTURE_TYPE_RENDERING_INFO_KHR }; + renderingInfo.colorAttachmentCount = 1; + renderingInfo.pColorAttachments = &attachmentInfo; // Retrieve a compatible pipeline to use for rendering DxvkMetaBlitPipeline pipeInfo = m_common->metaBlit().getPipeline( - mipGenerator->viewType(), imageView->info().format, VK_SAMPLE_COUNT_1_BIT); + mipGenerator->getSrcViewType(), imageView->info().format, VK_SAMPLE_COUNT_1_BIT); - for (uint32_t i = 0; i < mipGenerator->passCount(); i++) { - DxvkMetaBlitPass pass = mipGenerator->pass(i); - + for (uint32_t i = 0; i < mipGenerator->getPassCount(); i++) { // Width, height and layer count for the current pass - VkExtent3D passExtent = mipGenerator->passExtent(i); + VkExtent3D passExtent = mipGenerator->computePassExtent(i); // Create descriptor set with the current source view - descriptorImage.imageView = pass.srcView; + descriptorImage.imageView = mipGenerator->getSrcView(i); descriptorWrite.dstSet = m_descriptorPool->alloc(pipeInfo.dsetLayout); m_cmd->updateDescriptorSets(1, &descriptorWrite); @@ -1616,17 +1635,30 @@ namespace dxvk { scissor.offset = { 0, 0 }; scissor.extent = { passExtent.width, passExtent.height }; - // Set up render pass info - passInfo.framebuffer = pass.framebuffer; - passInfo.renderArea = scissor; + // Set up rendering info + attachmentInfo.imageView = mipGenerator->getDstView(i); + renderingInfo.renderArea = scissor; + renderingInfo.layerCount = passExtent.depth; // Set up push constants DxvkMetaBlitPushConstants pushConstants = { }; pushConstants.srcCoord0 = { 0.0f, 0.0f, 0.0f }; pushConstants.srcCoord1 = { 1.0f, 1.0f, 1.0f }; pushConstants.layerCount = passExtent.depth; - - m_cmd->cmdBeginRenderPass(&passInfo, VK_SUBPASS_CONTENTS_INLINE); + + if (i) { + m_execAcquires.accessImage(imageView->image(), + mipGenerator->getSourceSubresource(i), + dstLayout, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + srcLayout, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_ACCESS_SHADER_READ_BIT); + m_execAcquires.recordCommands(m_cmd); + } + + m_cmd->cmdBeginRendering(&renderingInfo); m_cmd->cmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeInfo.pipeHandle); m_cmd->cmdBindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeInfo.pipeLayout, descriptorWrite.dstSet, 0, nullptr); @@ -1641,9 +1673,44 @@ namespace dxvk { &pushConstants); m_cmd->cmdDraw(3, passExtent.depth, 0, 0); - m_cmd->cmdEndRenderPass(); + m_cmd->cmdEndRendering(); } - + + // Issue barriers to ensure we can safely access all mip + // levels of the image in all ways the image can be used + if (srcLayout == dstLayout) { + m_execBarriers.accessImage(imageView->image(), + imageView->imageSubresources(), + srcLayout, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | + VK_ACCESS_SHADER_READ_BIT, + imageView->imageInfo().layout, + imageView->imageInfo().stages, + imageView->imageInfo().access); + } else { + m_execBarriers.accessImage(imageView->image(), + mipGenerator->getAllSourceSubresources(), + srcLayout, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | + VK_ACCESS_SHADER_READ_BIT, + imageView->imageInfo().layout, + imageView->imageInfo().stages, + imageView->imageInfo().access); + + m_execBarriers.accessImage(imageView->image(), + mipGenerator->getBottomSubresource(), + dstLayout, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + imageView->imageInfo().layout, + imageView->imageInfo().stages, + imageView->imageInfo().access); + } + m_cmd->trackResource(mipGenerator); m_cmd->trackResource(imageView->image()); } @@ -2508,12 +2575,26 @@ namespace dxvk { || m_execBarriers.isImageDirty(srcImage, srcSubresourceRange, DxvkAccess::Write)) m_execBarriers.recordCommands(m_cmd); - bool isDepthStencil = region.srcSubresource.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); + bool srcIsDepthStencil = region.srcSubresource.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); - VkImageLayout srcLayout = srcImage->pickLayout(isDepthStencil + VkImageLayout srcLayout = srcImage->pickLayout(srcIsDepthStencil ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); - + + VkImageLayout dstLayout = dstImage->pickLayout( + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + + if (dstImage->info().layout != dstLayout) { + m_execAcquires.accessImage( + dstImage, dstSubresourceRange, + dstImage->info().layout, + dstImage->info().stages, 0, + dstLayout, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT); + } + if (srcImage->info().layout != srcLayout) { m_execAcquires.accessImage( srcImage, srcSubresourceRange, @@ -2522,10 +2603,10 @@ namespace dxvk { srcLayout, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_SHADER_READ_BIT); - - m_execAcquires.recordCommands(m_cmd); } + m_execAcquires.recordCommands(m_cmd); + // Sort out image offsets so that dstOffset[0] points // to the top-left corner of the target area VkOffset3D srcOffsets[2] = { region.srcOffsets[0], region.srcOffsets[1] }; @@ -2554,24 +2635,24 @@ namespace dxvk { // Begin render pass Rc pass = new DxvkMetaBlitRenderPass( m_device, dstImage, srcImage, region, mapping); - DxvkMetaBlitPass passObjects = pass->pass(); VkExtent3D imageExtent = dstImage->mipLevelExtent(region.dstSubresource.mipLevel); - VkRect2D renderArea; - renderArea.offset = VkOffset2D { 0, 0 }; - renderArea.extent = VkExtent2D { imageExtent.width, imageExtent.height }; + VkRenderingAttachmentInfoKHR attachmentInfo = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR }; + attachmentInfo.imageView = pass->getDstView(); + attachmentInfo.imageLayout = dstLayout; + attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - VkRenderPassBeginInfo passInfo; - passInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - passInfo.pNext = nullptr; - passInfo.renderPass = passObjects.renderPass; - passInfo.framebuffer = passObjects.framebuffer; - passInfo.renderArea = renderArea; - passInfo.clearValueCount = 0; - passInfo.pClearValues = nullptr; + VkRenderingInfoKHR renderingInfo = { VK_STRUCTURE_TYPE_RENDERING_INFO_KHR }; + renderingInfo.renderArea = VkRect2D { + VkOffset2D { 0, 0 }, + VkExtent2D { imageExtent.width, imageExtent.height } }; + renderingInfo.layerCount = pass->framebufferLayerCount(); + renderingInfo.colorAttachmentCount = 1; + renderingInfo.pColorAttachments = &attachmentInfo; - m_cmd->cmdBeginRenderPass(&passInfo, VK_SUBPASS_CONTENTS_INLINE); + m_cmd->cmdBeginRendering(&renderingInfo); // Bind pipeline DxvkMetaBlitPipeline pipeInfo = m_common->metaBlit().getPipeline( @@ -2598,20 +2679,16 @@ namespace dxvk { // Bind source image view VkDescriptorImageInfo descriptorImage; descriptorImage.sampler = m_common->metaBlit().getSampler(filter); - descriptorImage.imageView = passObjects.srcView; + descriptorImage.imageView = pass->getSrcView(); descriptorImage.imageLayout = srcLayout; - VkWriteDescriptorSet descriptorWrite; - descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - descriptorWrite.pNext = nullptr; + VkWriteDescriptorSet descriptorWrite = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET }; descriptorWrite.dstSet = m_descriptorPool->alloc(pipeInfo.dsetLayout); descriptorWrite.dstBinding = 0; descriptorWrite.dstArrayElement = 0; descriptorWrite.descriptorCount = 1; descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; descriptorWrite.pImageInfo = &descriptorImage; - descriptorWrite.pBufferInfo = nullptr; - descriptorWrite.pTexelBufferView = nullptr; m_cmd->updateDescriptorSets(1, &descriptorWrite); m_cmd->cmdBindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, @@ -2638,12 +2715,12 @@ namespace dxvk { &pushConstants); m_cmd->cmdDraw(3, pushConstants.layerCount, 0, 0); - m_cmd->cmdEndRenderPass(); + m_cmd->cmdEndRendering(); // Add barriers and track image objects m_execBarriers.accessImage(dstImage, vk::makeSubresourceRange(region.dstSubresource), - dstImage->info().layout, + dstLayout, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, dstImage->info().layout, diff --git a/src/dxvk/dxvk_meta_blit.cpp b/src/dxvk/dxvk_meta_blit.cpp index 7956b2ed4..2cf0773f0 100644 --- a/src/dxvk/dxvk_meta_blit.cpp +++ b/src/dxvk/dxvk_meta_blit.cpp @@ -22,9 +22,7 @@ namespace dxvk { m_srcImage (srcImage), m_region (region), m_dstView (createDstView()), - m_srcView (createSrcView(mapping)), - m_renderPass (createRenderPass()), - m_framebuffer (createFramebuffer()) { + m_srcView (createSrcView(mapping)) { } @@ -32,13 +30,11 @@ namespace dxvk { DxvkMetaBlitRenderPass::~DxvkMetaBlitRenderPass() { m_vkd->vkDestroyImageView(m_vkd->device(), m_dstView, nullptr); m_vkd->vkDestroyImageView(m_vkd->device(), m_srcView, nullptr); - m_vkd->vkDestroyRenderPass(m_vkd->device(), m_renderPass, nullptr); - m_vkd->vkDestroyFramebuffer(m_vkd->device(), m_framebuffer, nullptr); } VkImageViewType DxvkMetaBlitRenderPass::viewType() const { - std::array viewTypes = {{ + static const std::array viewTypes = {{ VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY, VK_IMAGE_VIEW_TYPE_3D, @@ -71,16 +67,6 @@ namespace dxvk { } - DxvkMetaBlitPass DxvkMetaBlitRenderPass::pass() const { - DxvkMetaBlitPass result; - result.srcView = m_srcView; - result.dstView = m_dstView; - result.renderPass = m_renderPass; - result.framebuffer = m_framebuffer; - return result; - } - - VkImageView DxvkMetaBlitRenderPass::createDstView() { std::array viewTypes = {{ VK_IMAGE_VIEW_TYPE_1D_ARRAY, @@ -138,75 +124,8 @@ namespace dxvk { } - VkRenderPass DxvkMetaBlitRenderPass::createRenderPass() { - VkAttachmentDescription attachment; - attachment.flags = 0; - attachment.format = m_dstImage->info().format; - attachment.samples = m_dstImage->info().sampleCount; - attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachment.initialLayout = m_dstImage->info().layout; - attachment.finalLayout = m_dstImage->info().layout; - - VkAttachmentReference attachmentRef; - attachmentRef.attachment = 0; - attachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - VkSubpassDescription subpass; - subpass.flags = 0; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.inputAttachmentCount = 0; - subpass.pInputAttachments = nullptr; - subpass.colorAttachmentCount = 1; - subpass.pColorAttachments = &attachmentRef; - subpass.pResolveAttachments = nullptr; - subpass.pDepthStencilAttachment = nullptr; - subpass.preserveAttachmentCount = 0; - subpass.pPreserveAttachments = nullptr; - - VkRenderPassCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; - info.attachmentCount = 1; - info.pAttachments = &attachment; - info.subpassCount = 1; - info.pSubpasses = &subpass; - info.dependencyCount = 0; - info.pDependencies = nullptr; - - VkRenderPass result = VK_NULL_HANDLE; - if (m_vkd->vkCreateRenderPass(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) - throw DxvkError("DxvkMetaBlitRenderPass: Failed to create render pass"); - return result; - } - VkFramebuffer DxvkMetaBlitRenderPass::createFramebuffer() { - VkExtent3D extent = m_dstImage->mipLevelExtent(m_region.dstSubresource.mipLevel); - - VkFramebufferCreateInfo fboInfo; - fboInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - fboInfo.pNext = nullptr; - fboInfo.flags = 0; - fboInfo.renderPass = m_renderPass; - fboInfo.attachmentCount = 1; - fboInfo.pAttachments = &m_dstView; - fboInfo.width = extent.width; - fboInfo.height = extent.height; - fboInfo.layers = framebufferLayerCount(); - - VkFramebuffer result; - if (m_vkd->vkCreateFramebuffer(m_vkd->device(), &fboInfo, nullptr, &result) != VK_SUCCESS) - throw DxvkError("DxvkMetaBlitRenderPass: Failed to create target framebuffer"); - return result; - } - - - - DxvkMetaBlitObjects::DxvkMetaBlitObjects(const DxvkDevice* device) : m_vkd (device->vkd()), m_samplerCopy (createSampler(VK_FILTER_NEAREST)), @@ -224,9 +143,6 @@ namespace dxvk { DxvkMetaBlitObjects::~DxvkMetaBlitObjects() { - for (const auto& pair : m_renderPasses) - m_vkd->vkDestroyRenderPass(m_vkd->device(), pair.second, nullptr); - for (const auto& pair : m_pipelines) { m_vkd->vkDestroyPipeline(m_vkd->device(), pair.second.pipeHandle, nullptr); m_vkd->vkDestroyPipelineLayout(m_vkd->device(), pair.second.pipeLayout, nullptr); @@ -272,23 +188,6 @@ namespace dxvk { } - VkRenderPass DxvkMetaBlitObjects::getRenderPass( - VkFormat viewFormat, - VkSampleCountFlagBits samples) { - DxvkMetaBlitRenderPassKey key; - key.viewFormat = viewFormat; - key.samples = samples; - - auto entry = m_renderPasses.find(key); - if (entry != m_renderPasses.end()) - return entry->second; - - VkRenderPass renderPass = this->createRenderPass(viewFormat, samples); - m_renderPasses.insert({ key, renderPass }); - return renderPass; - } - - VkSampler DxvkMetaBlitObjects::createSampler(VkFilter filter) const { VkSamplerCreateInfo info; info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; @@ -337,73 +236,18 @@ namespace dxvk { DxvkMetaBlitPipeline pipe; pipe.dsetLayout = this->createDescriptorSetLayout(key.viewType); pipe.pipeLayout = this->createPipelineLayout(pipe.dsetLayout); - pipe.pipeHandle = this->createPipeline(key.viewType, pipe.pipeLayout, - this->getRenderPass(key.viewFormat, key.samples), key.samples); + pipe.pipeHandle = this->createPipeline(pipe.pipeLayout, + key.viewType, key.viewFormat, key.samples); return pipe; } - VkRenderPass DxvkMetaBlitObjects::createRenderPass( - VkFormat format, - VkSampleCountFlagBits samples) const { - VkAttachmentDescription attachment; - attachment.flags = 0; - attachment.format = format; - attachment.samples = samples; - attachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - attachment.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - - VkAttachmentReference attachmentRef; - attachmentRef.attachment = 0; - attachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - VkSubpassDescription subpass; - subpass.flags = 0; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.inputAttachmentCount = 0; - subpass.pInputAttachments = nullptr; - subpass.colorAttachmentCount = 1; - subpass.pColorAttachments = &attachmentRef; - subpass.pResolveAttachments = nullptr; - subpass.pDepthStencilAttachment = nullptr; - subpass.preserveAttachmentCount = 0; - subpass.pPreserveAttachments = nullptr; - - VkRenderPassCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; - info.attachmentCount = 1; - info.pAttachments = &attachment; - info.subpassCount = 1; - info.pSubpasses = &subpass; - info.dependencyCount = 0; - info.pDependencies = nullptr; - - VkRenderPass result = VK_NULL_HANDLE; - if (m_vkd->vkCreateRenderPass(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) - throw DxvkError("DxvkMetaBlitObjects: Failed to create render pass"); - return result; - } - - VkDescriptorSetLayout DxvkMetaBlitObjects::createDescriptorSetLayout( VkImageViewType viewType) const { - VkDescriptorSetLayoutBinding binding; - binding.binding = 0; - binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - binding.descriptorCount = 1; - binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; - binding.pImmutableSamplers = nullptr; + VkDescriptorSetLayoutBinding binding = { 0, + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT }; - VkDescriptorSetLayoutCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; + VkDescriptorSetLayoutCreateInfo info = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO }; info.bindingCount = 1; info.pBindings = &binding; @@ -416,15 +260,9 @@ namespace dxvk { VkPipelineLayout DxvkMetaBlitObjects::createPipelineLayout( VkDescriptorSetLayout descriptorSetLayout) const { - VkPushConstantRange pushRange; - pushRange.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; - pushRange.offset = 0; - pushRange.size = sizeof(DxvkMetaBlitPushConstants); + VkPushConstantRange pushRange = { VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(DxvkMetaBlitPushConstants) }; - VkPipelineLayoutCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; + VkPipelineLayoutCreateInfo info = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO }; info.setLayoutCount = 1; info.pSetLayouts = &descriptorSetLayout; info.pushConstantRangeCount = 1; @@ -438,156 +276,90 @@ namespace dxvk { VkPipeline DxvkMetaBlitObjects::createPipeline( - VkImageViewType imageViewType, VkPipelineLayout pipelineLayout, - VkRenderPass renderPass, + VkImageViewType imageViewType, + VkFormat format, VkSampleCountFlagBits samples) const { std::array stages; uint32_t stageCount = 0; - VkPipelineShaderStageCreateInfo& vsStage = stages[stageCount++]; - vsStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - vsStage.pNext = nullptr; - vsStage.flags = 0; - vsStage.stage = VK_SHADER_STAGE_VERTEX_BIT; - vsStage.module = m_shaderVert; - vsStage.pName = "main"; - vsStage.pSpecializationInfo = nullptr; + stages[stageCount++] = VkPipelineShaderStageCreateInfo { + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0, + VK_SHADER_STAGE_VERTEX_BIT, m_shaderVert, "main" }; if (m_shaderGeom) { - VkPipelineShaderStageCreateInfo& gsStage = stages[stageCount++]; - gsStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - gsStage.pNext = nullptr; - gsStage.flags = 0; - gsStage.stage = VK_SHADER_STAGE_GEOMETRY_BIT; - gsStage.module = m_shaderGeom; - gsStage.pName = "main"; - gsStage.pSpecializationInfo = nullptr; + stages[stageCount++] = VkPipelineShaderStageCreateInfo { + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0, + VK_SHADER_STAGE_GEOMETRY_BIT, m_shaderGeom, "main" }; } - - VkPipelineShaderStageCreateInfo& psStage = stages[stageCount++]; - psStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - psStage.pNext = nullptr; - psStage.flags = 0; - psStage.stage = VK_SHADER_STAGE_FRAGMENT_BIT; - psStage.module = VK_NULL_HANDLE; - psStage.pName = "main"; - psStage.pSpecializationInfo = nullptr; - + + VkShaderModule psModule = VK_NULL_HANDLE; + switch (imageViewType) { - case VK_IMAGE_VIEW_TYPE_1D_ARRAY: psStage.module = m_shaderFrag1D; break; - case VK_IMAGE_VIEW_TYPE_2D_ARRAY: psStage.module = m_shaderFrag2D; break; - case VK_IMAGE_VIEW_TYPE_3D: psStage.module = m_shaderFrag3D; break; + case VK_IMAGE_VIEW_TYPE_1D_ARRAY: psModule = m_shaderFrag1D; break; + case VK_IMAGE_VIEW_TYPE_2D_ARRAY: psModule = m_shaderFrag2D; break; + case VK_IMAGE_VIEW_TYPE_3D: psModule = m_shaderFrag3D; break; default: throw DxvkError("DxvkMetaBlitObjects: Invalid view type"); } + stages[stageCount++] = VkPipelineShaderStageCreateInfo { + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0, + VK_SHADER_STAGE_FRAGMENT_BIT, psModule, "main" }; + std::array dynStates = {{ VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, }}; - VkPipelineDynamicStateCreateInfo dynState; - dynState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; - dynState.pNext = nullptr; - dynState.flags = 0; - dynState.dynamicStateCount = dynStates.size(); - dynState.pDynamicStates = dynStates.data(); + VkPipelineDynamicStateCreateInfo dynState = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; + dynState.dynamicStateCount = dynStates.size(); + dynState.pDynamicStates = dynStates.data(); - VkPipelineVertexInputStateCreateInfo viState; - viState.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - viState.pNext = nullptr; - viState.flags = 0; - viState.vertexBindingDescriptionCount = 0; - viState.pVertexBindingDescriptions = nullptr; - viState.vertexAttributeDescriptionCount = 0; - viState.pVertexAttributeDescriptions = nullptr; + VkPipelineVertexInputStateCreateInfo viState = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO }; - VkPipelineInputAssemblyStateCreateInfo iaState; - iaState.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; - iaState.pNext = nullptr; - iaState.flags = 0; - iaState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + VkPipelineInputAssemblyStateCreateInfo iaState = { VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO }; + iaState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; iaState.primitiveRestartEnable = VK_FALSE; - VkPipelineViewportStateCreateInfo vpState; - vpState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; - vpState.pNext = nullptr; - vpState.flags = 0; - vpState.viewportCount = 1; - vpState.pViewports = nullptr; - vpState.scissorCount = 1; - vpState.pScissors = nullptr; + VkPipelineViewportStateCreateInfo vpState = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO }; + vpState.viewportCount = 1; + vpState.scissorCount = 1; - VkPipelineRasterizationStateCreateInfo rsState; - rsState.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; - rsState.pNext = nullptr; - rsState.flags = 0; - rsState.depthClampEnable = VK_TRUE; - rsState.rasterizerDiscardEnable = VK_FALSE; - rsState.polygonMode = VK_POLYGON_MODE_FILL; - rsState.cullMode = VK_CULL_MODE_NONE; - rsState.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; - rsState.depthBiasEnable = VK_FALSE; - rsState.depthBiasConstantFactor = 0.0f; - rsState.depthBiasClamp = 0.0f; - rsState.depthBiasSlopeFactor = 0.0f; - rsState.lineWidth = 1.0f; + VkPipelineRasterizationStateCreateInfo rsState = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO }; + rsState.polygonMode = VK_POLYGON_MODE_FILL; + rsState.cullMode = VK_CULL_MODE_NONE; + rsState.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; + rsState.lineWidth = 1.0f; uint32_t msMask = 0xFFFFFFFF; - VkPipelineMultisampleStateCreateInfo msState; - msState.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; - msState.pNext = nullptr; - msState.flags = 0; + VkPipelineMultisampleStateCreateInfo msState = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO }; msState.rasterizationSamples = samples; - msState.sampleShadingEnable = VK_FALSE; - msState.minSampleShading = 1.0f; - msState.pSampleMask = &msMask; - msState.alphaToCoverageEnable = VK_FALSE; - msState.alphaToOneEnable = VK_FALSE; + msState.pSampleMask = &msMask; - VkPipelineColorBlendAttachmentState cbAttachment; - cbAttachment.blendEnable = VK_FALSE; - cbAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_ONE; - cbAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; - cbAttachment.colorBlendOp = VK_BLEND_OP_ADD; - cbAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; - cbAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; - cbAttachment.alphaBlendOp = VK_BLEND_OP_ADD; - cbAttachment.colorWriteMask = + VkPipelineColorBlendAttachmentState cbAttachment = { }; + cbAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; - VkPipelineColorBlendStateCreateInfo cbState; - cbState.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; - cbState.pNext = nullptr; - cbState.flags = 0; - cbState.logicOpEnable = VK_FALSE; - cbState.logicOp = VK_LOGIC_OP_NO_OP; + VkPipelineColorBlendStateCreateInfo cbState = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO }; cbState.attachmentCount = 1; cbState.pAttachments = &cbAttachment; - - for (uint32_t i = 0; i < 4; i++) - cbState.blendConstants[i] = 0.0f; - - VkGraphicsPipelineCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; + + VkPipelineRenderingCreateInfoKHR rtState = { VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR }; + rtState.colorAttachmentCount = 1; + rtState.pColorAttachmentFormats = &format; + + VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &rtState }; info.stageCount = stageCount; info.pStages = stages.data(); info.pVertexInputState = &viState; info.pInputAssemblyState = &iaState; - info.pTessellationState = nullptr; info.pViewportState = &vpState; info.pRasterizationState = &rsState; info.pMultisampleState = &msState; info.pColorBlendState = &cbState; - info.pDepthStencilState = nullptr; info.pDynamicState = &dynState; info.layout = pipelineLayout; - info.renderPass = renderPass; - info.subpass = 0; - info.basePipelineHandle = VK_NULL_HANDLE; info.basePipelineIndex = -1; VkPipeline result = VK_NULL_HANDLE; diff --git a/src/dxvk/dxvk_meta_blit.h b/src/dxvk/dxvk_meta_blit.h index 28f8616c5..32a1eab0d 100644 --- a/src/dxvk/dxvk_meta_blit.h +++ b/src/dxvk/dxvk_meta_blit.h @@ -87,20 +87,6 @@ namespace dxvk { }; - /** - * \brief Blit framebuffer - * - * Stores the image views and framebuffer - * handle used to generate one mip level. - */ - struct DxvkMetaBlitPass { - VkImageView srcView; - VkImageView dstView; - VkRenderPass renderPass; - VkFramebuffer framebuffer; - }; - - /** * \brief Blit render pass * @@ -126,7 +112,8 @@ namespace dxvk { uint32_t framebufferLayerIndex() const; uint32_t framebufferLayerCount() const; - DxvkMetaBlitPass pass() const; + VkImageView getDstView() const { return m_dstView; } + VkImageView getSrcView() const { return m_srcView; } private: @@ -137,15 +124,10 @@ namespace dxvk { VkImageBlit m_region; VkImageView m_dstView; VkImageView m_srcView; - VkRenderPass m_renderPass; - VkFramebuffer m_framebuffer; VkImageView createDstView(); VkImageView createSrcView(const VkComponentMapping& mapping); - VkRenderPass createRenderPass(); - VkFramebuffer createFramebuffer(); - }; @@ -201,20 +183,11 @@ namespace dxvk { dxvk::mutex m_mutex; - std::unordered_map< - DxvkMetaBlitRenderPassKey, - VkRenderPass, - DxvkHash, DxvkEq> m_renderPasses; - std::unordered_map< DxvkMetaBlitPipelineKey, DxvkMetaBlitPipeline, DxvkHash, DxvkEq> m_pipelines; - VkRenderPass getRenderPass( - VkFormat viewFormat, - VkSampleCountFlagBits samples); - VkSampler createSampler( VkFilter filter) const; @@ -224,10 +197,6 @@ namespace dxvk { DxvkMetaBlitPipeline createPipeline( const DxvkMetaBlitPipelineKey& key); - VkRenderPass createRenderPass( - VkFormat format, - VkSampleCountFlagBits samples) const; - VkDescriptorSetLayout createDescriptorSetLayout( VkImageViewType viewType) const; @@ -235,9 +204,9 @@ namespace dxvk { VkDescriptorSetLayout descriptorSetLayout) const; VkPipeline createPipeline( - VkImageViewType imageViewType, VkPipelineLayout pipelineLayout, - VkRenderPass renderPass, + VkImageViewType imageViewType, + VkFormat format, VkSampleCountFlagBits samples) const; }; diff --git a/src/dxvk/dxvk_meta_mipgen.cpp b/src/dxvk/dxvk_meta_mipgen.cpp index 297da07e7..46c2dd73c 100644 --- a/src/dxvk/dxvk_meta_mipgen.cpp +++ b/src/dxvk/dxvk_meta_mipgen.cpp @@ -5,7 +5,7 @@ namespace dxvk { DxvkMetaMipGenRenderPass::DxvkMetaMipGenRenderPass( const Rc& vkd, const Rc& view) - : m_vkd(vkd), m_view(view), m_renderPass(createRenderPass()) { + : m_vkd(vkd), m_view(view) { // Determine view type based on image type const std::array, 3> viewTypes = {{ { VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_1D_ARRAY }, @@ -20,22 +20,19 @@ namespace dxvk { m_passes.resize(view->info().numLevels - 1); for (uint32_t i = 0; i < m_passes.size(); i++) - m_passes.at(i) = this->createFramebuffer(i); + m_passes[i] = createViews(i); } DxvkMetaMipGenRenderPass::~DxvkMetaMipGenRenderPass() { - for (const auto& pass : m_passes) { - m_vkd->vkDestroyFramebuffer(m_vkd->device(), pass.framebuffer, nullptr); - m_vkd->vkDestroyImageView(m_vkd->device(), pass.dstView, nullptr); - m_vkd->vkDestroyImageView(m_vkd->device(), pass.srcView, nullptr); + for (const auto& views : m_passes) { + m_vkd->vkDestroyImageView(m_vkd->device(), views.src, nullptr); + m_vkd->vkDestroyImageView(m_vkd->device(), views.dst, nullptr); } - - m_vkd->vkDestroyRenderPass(m_vkd->device(), m_renderPass, nullptr); } - VkExtent3D DxvkMetaMipGenRenderPass::passExtent(uint32_t passId) const { + VkExtent3D DxvkMetaMipGenRenderPass::computePassExtent(uint32_t passId) const { VkExtent3D extent = m_view->mipLevelExtent(passId + 1); if (m_view->imageInfo().type != VK_IMAGE_TYPE_3D) @@ -45,81 +42,14 @@ namespace dxvk { } - VkRenderPass DxvkMetaMipGenRenderPass::createRenderPass() const { - std::array subpassDeps = {{ - { VK_SUBPASS_EXTERNAL, 0, - m_view->imageInfo().stages, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 0 }, - { 0, VK_SUBPASS_EXTERNAL, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - m_view->imageInfo().stages, - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - m_view->imageInfo().access, 0 }, - }}; - - VkAttachmentDescription attachment; - attachment.flags = 0; - attachment.format = m_view->info().format; - attachment.samples = VK_SAMPLE_COUNT_1_BIT; - attachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - attachment.finalLayout = m_view->imageInfo().layout; - - VkAttachmentReference attachmentRef; - attachmentRef.attachment = 0; - attachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - VkSubpassDescription subpass; - subpass.flags = 0; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.inputAttachmentCount = 0; - subpass.pInputAttachments = nullptr; - subpass.colorAttachmentCount = 1; - subpass.pColorAttachments = &attachmentRef; - subpass.pResolveAttachments = nullptr; - subpass.pDepthStencilAttachment = nullptr; - subpass.preserveAttachmentCount = 0; - subpass.pPreserveAttachments = nullptr; - - VkRenderPassCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; - info.attachmentCount = 1; - info.pAttachments = &attachment; - info.subpassCount = 1; - info.pSubpasses = &subpass; - info.dependencyCount = subpassDeps.size(); - info.pDependencies = subpassDeps.data(); - - VkRenderPass result = VK_NULL_HANDLE; - if (m_vkd->vkCreateRenderPass(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) - throw DxvkError("DxvkMetaMipGenRenderPass: Failed to create render pass"); - return result; - } - - - DxvkMetaBlitPass DxvkMetaMipGenRenderPass::createFramebuffer(uint32_t pass) const { - DxvkMetaBlitPass result; - result.srcView = VK_NULL_HANDLE; - result.dstView = VK_NULL_HANDLE; - result.renderPass = m_renderPass; - result.framebuffer = VK_NULL_HANDLE; - - // Common image view info - VkImageViewCreateInfo viewInfo; - viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - viewInfo.pNext = nullptr; - viewInfo.flags = 0; - viewInfo.image = m_view->imageHandle(); - viewInfo.format = m_view->info().format; - viewInfo.components = { - VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, - VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY }; + DxvkMetaMipGenRenderPass::PassViews DxvkMetaMipGenRenderPass::createViews(uint32_t pass) const { + PassViews result = { }; + + VkImageViewUsageCreateInfo usageInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO }; + + VkImageViewCreateInfo viewInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, &usageInfo }; + viewInfo.image = m_view->imageHandle(); + viewInfo.format = m_view->info().format; // Create source image view, which points to // the one mip level we're going to sample. @@ -130,10 +60,11 @@ namespace dxvk { srcSubresources.baseArrayLayer = m_view->info().minLayer; srcSubresources.layerCount = m_view->info().numLayers; - viewInfo.viewType = m_srcViewType; + usageInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT; + viewInfo.viewType = m_srcViewType; viewInfo.subresourceRange = srcSubresources; - - if (m_vkd->vkCreateImageView(m_vkd->device(), &viewInfo, nullptr, &result.srcView) != VK_SUCCESS) + + if (m_vkd->vkCreateImageView(m_vkd->device(), &viewInfo, nullptr, &result.src) != VK_SUCCESS) throw DxvkError("DxvkMetaMipGenRenderPass: Failed to create source image view"); // Create destination image view, which points @@ -147,34 +78,19 @@ namespace dxvk { if (m_view->imageInfo().type != VK_IMAGE_TYPE_3D) { dstSubresources.baseArrayLayer = m_view->info().minLayer; - dstSubresources.layerCount = m_view->info().numLayers; + dstSubresources.layerCount = m_view->info().numLayers; } else { dstSubresources.baseArrayLayer = 0; - dstSubresources.layerCount = dstExtent.depth; + dstSubresources.layerCount = dstExtent.depth; } - viewInfo.viewType = m_dstViewType; + usageInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + viewInfo.viewType = m_dstViewType; viewInfo.subresourceRange = dstSubresources; - if (m_vkd->vkCreateImageView(m_vkd->device(), &viewInfo, nullptr, &result.dstView) != VK_SUCCESS) - throw DxvkError("DxvkMetaMipGenRenderPass: Failed to create target image view"); - - // Create framebuffer using the destination - // image view as its color attachment. - VkFramebufferCreateInfo fboInfo; - fboInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - fboInfo.pNext = nullptr; - fboInfo.flags = 0; - fboInfo.renderPass = m_renderPass; - fboInfo.attachmentCount = 1; - fboInfo.pAttachments = &result.dstView; - fboInfo.width = dstExtent.width; - fboInfo.height = dstExtent.height; - fboInfo.layers = dstSubresources.layerCount; - - if (m_vkd->vkCreateFramebuffer(m_vkd->device(), &fboInfo, nullptr, &result.framebuffer) != VK_SUCCESS) - throw DxvkError("DxvkMetaMipGenRenderPass: Failed to create target framebuffer"); - + if (m_vkd->vkCreateImageView(m_vkd->device(), &viewInfo, nullptr, &result.dst) != VK_SUCCESS) + throw DxvkError("DxvkMetaMipGenRenderPass: Failed to create destination image view"); + return result; } diff --git a/src/dxvk/dxvk_meta_mipgen.h b/src/dxvk/dxvk_meta_mipgen.h index a5d2d60f9..e473816d1 100644 --- a/src/dxvk/dxvk_meta_mipgen.h +++ b/src/dxvk/dxvk_meta_mipgen.h @@ -23,14 +23,6 @@ namespace dxvk { ~DxvkMetaMipGenRenderPass(); - /** - * \brief Render pass handle - * \returns Render pass handle - */ - VkRenderPass renderPass() const { - return m_renderPass; - } - /** * \brief Source image view type * @@ -38,7 +30,7 @@ namespace dxvk { * resource descriptor needs to have. * \returns Source image view type */ - VkImageViewType viewType() const { + VkImageViewType getSrcViewType() const { return m_srcViewType; } @@ -48,45 +40,109 @@ namespace dxvk { * Number of mip levels to generate. * \returns Render pass count */ - uint32_t passCount() const { + uint32_t getPassCount() const { return m_passes.size(); } /** - * \brief Framebuffer handles + * \brief Source image view * - * Returns image view and framebuffer handles - * required to generate a single mip level. * \param [in] pass Render pass index - * \returns Object handles for the given pass + * \returns Source image view handle for the given pass */ - DxvkMetaBlitPass pass(uint32_t passId) const { - return m_passes.at(passId); + VkImageView getSrcView(uint32_t passId) const { + return m_passes.at(passId).src; } - + + /** + * \brief Destination image view + * + * \param [in] pass Render pass index + * \returns Destination image view handle for the given pass + */ + VkImageView getDstView(uint32_t passId) const { + return m_passes.at(passId).dst; + } + + /** + * \brief Returns subresource that will only be read + * \returns Top level of the image view + */ + VkImageSubresourceRange getTopSubresource() const { + VkImageSubresourceRange sr = m_view->imageSubresources(); + sr.levelCount = 1; + return sr; + } + + /** + * \brief Returns subresource that will only be written + * \returns Top level of the image view + */ + VkImageSubresourceRange getBottomSubresource() const { + VkImageSubresourceRange sr = m_view->imageSubresources(); + sr.baseMipLevel += sr.levelCount - 1; + sr.levelCount = 1; + return sr; + } + + /** + * \brief Returns all subresources that will be written + * \returns All mip levels except the top level + */ + VkImageSubresourceRange getAllTargetSubresources() const { + VkImageSubresourceRange sr = m_view->imageSubresources(); + sr.baseMipLevel += 1; + sr.levelCount -= 1; + return sr; + } + + /** + * \brief Returns all subresources that will be read + * \returns All mip levels except the bottom level + */ + VkImageSubresourceRange getAllSourceSubresources() const { + VkImageSubresourceRange sr = m_view->imageSubresources(); + sr.levelCount -= 1; + return sr; + } + + /** + * \brief Returns subresource read in a given pass + * + * \param [in] pass Pass index + * \returns The source subresource + */ + VkImageSubresourceRange getSourceSubresource(uint32_t pass) const { + VkImageSubresourceRange sr = m_view->imageSubresources(); + sr.baseMipLevel += pass; + sr.levelCount = 1; + return sr; + } + /** * \brief Framebuffer size for a given pass * * Stores the width, height, and layer count * of the framebuffer for the given pass ID. */ - VkExtent3D passExtent(uint32_t passId) const; + VkExtent3D computePassExtent(uint32_t passId) const; private: - + + struct PassViews { + VkImageView src; + VkImageView dst; + }; + Rc m_vkd; Rc m_view; - VkRenderPass m_renderPass; - VkImageViewType m_srcViewType; VkImageViewType m_dstViewType; - std::vector m_passes; + std::vector m_passes; - VkRenderPass createRenderPass() const; - - DxvkMetaBlitPass createFramebuffer(uint32_t pass) const; + PassViews createViews(uint32_t pass) const; };