mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-31 14:52:11 +01:00
[dxvk] Use dynamic rendering for regular graphics pipelines
For now, just do whatever we were previously doing for render passes, but explicitly.
This commit is contained in:
parent
5b6a598ed6
commit
343eba693d
@ -1932,10 +1932,7 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
if (attachmentIndex < 0) {
|
||||
if (m_execBarriers.isImageDirty(
|
||||
imageView->image(),
|
||||
imageView->imageSubresources(),
|
||||
DxvkAccess::Write))
|
||||
if (m_execBarriers.isImageDirty(imageView->image(), imageView->imageSubresources(), DxvkAccess::Write))
|
||||
m_execBarriers.recordCommands(m_cmd);
|
||||
|
||||
// Set up and bind a temporary framebuffer
|
||||
@ -3982,6 +3979,133 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::renderPassEmitInitBarriers(
|
||||
const DxvkFramebufferInfo& framebufferInfo,
|
||||
const DxvkRenderPassOps& ops) {
|
||||
// If any of the involved images are dirty, emit all pending barriers now.
|
||||
// Otherwise, skip this step so that we can more efficiently batch barriers.
|
||||
for (uint32_t i = 0; i < framebufferInfo.numAttachments(); i++) {
|
||||
const auto& attachment = framebufferInfo.getAttachment(i);
|
||||
|
||||
if (m_execBarriers.isImageDirty(
|
||||
attachment.view->image(),
|
||||
attachment.view->imageSubresources(),
|
||||
DxvkAccess::Write)) {
|
||||
m_execBarriers.recordCommands(m_cmd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Transition all images to the render layout as necessary
|
||||
const auto& depthAttachment = framebufferInfo.getDepthTarget();
|
||||
|
||||
if (depthAttachment.layout != ops.depthOps.loadLayout
|
||||
&& depthAttachment.view != nullptr) {
|
||||
VkImageAspectFlags depthAspects = depthAttachment.view->info().aspect;
|
||||
|
||||
VkPipelineStageFlags depthStages =
|
||||
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
|
||||
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
|
||||
VkAccessFlags depthAccess = 0;
|
||||
|
||||
if (((depthAspects & VK_IMAGE_ASPECT_DEPTH_BIT) && ops.depthOps.loadOpD == VK_ATTACHMENT_LOAD_OP_LOAD)
|
||||
|| ((depthAspects & VK_IMAGE_ASPECT_STENCIL_BIT) && ops.depthOps.loadOpS == VK_ATTACHMENT_LOAD_OP_LOAD))
|
||||
depthAccess |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
|
||||
|
||||
if (((depthAspects & VK_IMAGE_ASPECT_DEPTH_BIT) && ops.depthOps.loadOpD != VK_ATTACHMENT_LOAD_OP_LOAD)
|
||||
|| ((depthAspects & VK_IMAGE_ASPECT_STENCIL_BIT) && ops.depthOps.loadOpS != VK_ATTACHMENT_LOAD_OP_LOAD)
|
||||
|| (depthAttachment.layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL))
|
||||
depthAccess |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||
|
||||
if (depthAttachment.layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
|
||||
depthStages |= m_device->getShaderPipelineStages();
|
||||
depthAccess |= VK_ACCESS_SHADER_READ_BIT;
|
||||
}
|
||||
|
||||
m_execBarriers.accessImage(
|
||||
depthAttachment.view->image(),
|
||||
depthAttachment.view->imageSubresources(),
|
||||
ops.depthOps.loadLayout,
|
||||
depthStages, 0,
|
||||
depthAttachment.layout,
|
||||
depthStages, depthAccess);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
||||
const auto& colorAttachment = framebufferInfo.getColorTarget(i);
|
||||
|
||||
if (colorAttachment.layout != ops.colorOps[i].loadLayout
|
||||
&& colorAttachment.view != nullptr) {
|
||||
VkAccessFlags colorAccess = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
|
||||
if (ops.colorOps[i].loadOp == VK_ATTACHMENT_LOAD_OP_LOAD)
|
||||
colorAccess |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
|
||||
|
||||
m_execBarriers.accessImage(
|
||||
colorAttachment.view->image(),
|
||||
colorAttachment.view->imageSubresources(),
|
||||
ops.colorOps[i].loadLayout,
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0,
|
||||
colorAttachment.layout,
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
colorAccess);
|
||||
}
|
||||
}
|
||||
|
||||
// Unconditionally emit barriers here. We need to do this
|
||||
// even if there are no layout transitions, since we don't
|
||||
// track resource usage during render passes.
|
||||
m_execBarriers.recordCommands(m_cmd);
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::renderPassEmitPostBarriers(
|
||||
const DxvkFramebufferInfo& framebufferInfo,
|
||||
const DxvkRenderPassOps& ops) {
|
||||
const auto& depthAttachment = framebufferInfo.getDepthTarget();
|
||||
|
||||
if (depthAttachment.view != nullptr) {
|
||||
m_execBarriers.accessImage(
|
||||
depthAttachment.view->image(),
|
||||
depthAttachment.view->imageSubresources(),
|
||||
depthAttachment.layout,
|
||||
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
|
||||
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
ops.depthOps.storeLayout,
|
||||
depthAttachment.view->imageInfo().stages,
|
||||
depthAttachment.view->imageInfo().access);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
||||
const auto& colorAttachment = framebufferInfo.getColorTarget(i);
|
||||
|
||||
if (colorAttachment.view != nullptr) {
|
||||
m_execBarriers.accessImage(
|
||||
colorAttachment.view->image(),
|
||||
colorAttachment.view->imageSubresources(),
|
||||
colorAttachment.layout,
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
|
||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
ops.colorOps[i].storeLayout,
|
||||
colorAttachment.view->imageInfo().stages,
|
||||
colorAttachment.view->imageInfo().access);
|
||||
}
|
||||
}
|
||||
|
||||
m_execBarriers.accessMemory(
|
||||
ops.barrier.srcStages,
|
||||
ops.barrier.srcAccess,
|
||||
ops.barrier.dstStages,
|
||||
ops.barrier.dstAccess);
|
||||
|
||||
// Do not flush barriers here. This is intended since
|
||||
// we pre-record them when binding the framebuffer.
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::renderPassBindFramebuffer(
|
||||
const DxvkFramebufferInfo& framebufferInfo,
|
||||
const DxvkRenderPassOps& ops,
|
||||
@ -3989,26 +4113,75 @@ namespace dxvk {
|
||||
const VkClearValue* clearValues) {
|
||||
const DxvkFramebufferSize fbSize = framebufferInfo.size();
|
||||
|
||||
Rc<DxvkFramebuffer> framebuffer = this->lookupFramebuffer(framebufferInfo);
|
||||
this->renderPassEmitInitBarriers(framebufferInfo, ops);
|
||||
this->renderPassEmitPostBarriers(framebufferInfo, ops);
|
||||
|
||||
VkRect2D renderArea;
|
||||
renderArea.offset = VkOffset2D { 0, 0 };
|
||||
renderArea.extent = VkExtent2D { fbSize.width, fbSize.height };
|
||||
|
||||
VkRenderPassBeginInfo info;
|
||||
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||
info.pNext = nullptr;
|
||||
info.renderPass = framebufferInfo.renderPass()->getHandle(ops);
|
||||
info.framebuffer = framebuffer->handle();
|
||||
info.renderArea = renderArea;
|
||||
info.clearValueCount = clearValueCount;
|
||||
info.pClearValues = clearValues;
|
||||
|
||||
m_cmd->cmdBeginRenderPass(&info,
|
||||
VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
m_cmd->trackResource<DxvkAccess::None>(framebuffer);
|
||||
uint32_t clearValueIndex = 0;
|
||||
uint32_t colorInfoCount = 0;
|
||||
|
||||
std::array<VkRenderingAttachmentInfoKHR, MaxNumRenderTargets> colorInfos;
|
||||
|
||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
||||
const auto& colorTarget = framebufferInfo.getColorTarget(i);
|
||||
colorInfos[i] = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR };
|
||||
|
||||
if (colorTarget.view != nullptr) {
|
||||
colorInfos[i].imageView = colorTarget.view->handle();
|
||||
colorInfos[i].imageLayout = colorTarget.layout;
|
||||
colorInfos[i].loadOp = ops.colorOps[i].loadOp;
|
||||
colorInfos[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
|
||||
if (ops.colorOps[i].loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
|
||||
colorInfos[i].clearValue = clearValues[clearValueIndex];
|
||||
|
||||
clearValueIndex += 1;
|
||||
colorInfoCount = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
VkRenderingAttachmentInfoKHR depthInfo = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR };
|
||||
VkImageAspectFlags depthStencilAspects = 0;
|
||||
|
||||
if (framebufferInfo.getDepthTarget().view != nullptr) {
|
||||
const auto& depthTarget = framebufferInfo.getDepthTarget();
|
||||
depthStencilAspects = depthTarget.view->info().aspect;
|
||||
depthInfo.imageView = depthTarget.view->handle();
|
||||
depthInfo.imageLayout = depthTarget.layout;
|
||||
depthInfo.loadOp = ops.depthOps.loadOpD;
|
||||
depthInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
|
||||
if (ops.depthOps.loadOpD == VK_ATTACHMENT_LOAD_OP_CLEAR)
|
||||
depthInfo.clearValue = clearValues[clearValueIndex];
|
||||
}
|
||||
|
||||
VkRenderingAttachmentInfoKHR stencilInfo = depthInfo;
|
||||
|
||||
if (framebufferInfo.getDepthTarget().view != nullptr) {
|
||||
stencilInfo.loadOp = ops.depthOps.loadOpS;
|
||||
stencilInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
|
||||
if (ops.depthOps.loadOpS == VK_ATTACHMENT_LOAD_OP_CLEAR)
|
||||
stencilInfo.clearValue = clearValues[clearValueIndex];
|
||||
}
|
||||
|
||||
VkRenderingInfoKHR renderingInfo = { VK_STRUCTURE_TYPE_RENDERING_INFO_KHR };
|
||||
renderingInfo.renderArea.offset = VkOffset2D { 0, 0 };
|
||||
renderingInfo.renderArea.extent = VkExtent2D { fbSize.width, fbSize.height };
|
||||
renderingInfo.layerCount = fbSize.layers;
|
||||
|
||||
if (colorInfoCount) {
|
||||
renderingInfo.colorAttachmentCount = colorInfoCount;
|
||||
renderingInfo.pColorAttachments = colorInfos.data();
|
||||
}
|
||||
|
||||
if (depthStencilAspects & VK_IMAGE_ASPECT_DEPTH_BIT)
|
||||
renderingInfo.pDepthAttachment = &depthInfo;
|
||||
|
||||
if (depthStencilAspects & VK_IMAGE_ASPECT_STENCIL_BIT)
|
||||
renderingInfo.pStencilAttachment = &stencilInfo;
|
||||
|
||||
m_cmd->cmdBeginRendering(&renderingInfo);
|
||||
|
||||
for (uint32_t i = 0; i < framebufferInfo.numAttachments(); i++) {
|
||||
m_cmd->trackResource<DxvkAccess::None> (framebufferInfo.getAttachment(i).view);
|
||||
m_cmd->trackResource<DxvkAccess::Write>(framebufferInfo.getAttachment(i).view->image());
|
||||
@ -4019,7 +4192,11 @@ namespace dxvk {
|
||||
|
||||
|
||||
void DxvkContext::renderPassUnbindFramebuffer() {
|
||||
m_cmd->cmdEndRenderPass();
|
||||
m_cmd->cmdEndRendering();
|
||||
|
||||
// TODO Try to get rid of this for performance reasons.
|
||||
// This only exists to emulate render pass barriers.
|
||||
m_execBarriers.recordCommands(m_cmd);
|
||||
}
|
||||
|
||||
|
||||
@ -4499,7 +4676,9 @@ namespace dxvk {
|
||||
DxvkFramebufferInfo fbInfo = makeFramebufferInfo(m_state.om.renderTargets);
|
||||
this->updateRenderTargetLayouts(fbInfo, m_state.om.framebufferInfo);
|
||||
|
||||
// Update relevant graphics pipeline state
|
||||
m_state.gp.state.ms.setSampleCount(fbInfo.getSampleCount());
|
||||
m_state.gp.state.rt = fbInfo.getRtInfo();
|
||||
m_state.om.framebufferInfo = fbInfo;
|
||||
|
||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
||||
|
@ -1286,6 +1286,14 @@ namespace dxvk {
|
||||
void startRenderPass();
|
||||
void spillRenderPass(bool suspend);
|
||||
|
||||
void renderPassEmitInitBarriers(
|
||||
const DxvkFramebufferInfo& framebufferInfo,
|
||||
const DxvkRenderPassOps& ops);
|
||||
|
||||
void renderPassEmitPostBarriers(
|
||||
const DxvkFramebufferInfo& framebufferInfo,
|
||||
const DxvkRenderPassOps& ops);
|
||||
|
||||
void renderPassBindFramebuffer(
|
||||
const DxvkFramebufferInfo& framebufferInfo,
|
||||
const DxvkRenderPassOps& ops,
|
||||
|
@ -88,6 +88,27 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
DxvkRtInfo DxvkFramebufferInfo::getRtInfo() const {
|
||||
VkFormat depthStencilFormat = VK_FORMAT_UNDEFINED;
|
||||
VkImageAspectFlags depthStencilReadOnlyAspects = 0;
|
||||
|
||||
if (m_renderTargets.depth.view != nullptr) {
|
||||
depthStencilFormat = m_renderTargets.depth.view->info().format;
|
||||
depthStencilReadOnlyAspects = m_renderTargets.depth.view->formatInfo()->aspectMask
|
||||
& ~vk::getWritableAspectsForLayout(m_renderTargets.depth.layout);
|
||||
}
|
||||
|
||||
std::array<VkFormat, MaxNumRenderTargets> colorFormats = { };
|
||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
||||
if (m_renderTargets.color[i].view != nullptr)
|
||||
colorFormats[i] = m_renderTargets.color[i].view->info().format;
|
||||
}
|
||||
|
||||
return DxvkRtInfo(MaxNumRenderTargets, colorFormats.data(),
|
||||
depthStencilFormat, depthStencilReadOnlyAspects);
|
||||
}
|
||||
|
||||
|
||||
DxvkRenderPassFormat DxvkFramebufferInfo::getRenderPassFormat(const DxvkRenderTargets& renderTargets) {
|
||||
DxvkRenderPassFormat format;
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "dxvk_image.h"
|
||||
#include "dxvk_graphics_state.h"
|
||||
#include "dxvk_renderpass.h"
|
||||
|
||||
namespace dxvk {
|
||||
@ -225,6 +226,12 @@ namespace dxvk {
|
||||
*/
|
||||
DxvkFramebufferKey key() const;
|
||||
|
||||
/**
|
||||
* \brief Generates render target state
|
||||
* \returns Render target state info
|
||||
*/
|
||||
DxvkRtInfo getRtInfo() const;
|
||||
|
||||
/**
|
||||
* \brief Generatess render pass format
|
||||
*
|
||||
|
@ -120,9 +120,6 @@ namespace dxvk {
|
||||
this->logPipelineState(LogLevel::Debug, state);
|
||||
}
|
||||
|
||||
// Render pass format and image layouts
|
||||
DxvkRenderPassFormat passFormat = renderPass->format();
|
||||
|
||||
// Set up dynamic states as needed
|
||||
std::array<VkDynamicState, 6> dynamicStates;
|
||||
uint32_t dynamicStateCount = 0;
|
||||
@ -180,29 +177,41 @@ namespace dxvk {
|
||||
if (fsm) stages.push_back(fsm.stageInfo(&specInfo));
|
||||
|
||||
// Fix up color write masks using the component mappings
|
||||
std::array<VkPipelineColorBlendAttachmentState, MaxNumRenderTargets> omBlendAttachments;
|
||||
VkImageAspectFlags rtReadOnlyAspects = state.rt.getDepthStencilReadOnlyAspects();
|
||||
VkFormat rtDepthFormat = state.rt.getDepthStencilFormat();
|
||||
auto rtDepthFormatInfo = imageFormatInfo(rtDepthFormat);
|
||||
|
||||
std::array<VkPipelineColorBlendAttachmentState, MaxNumRenderTargets> omBlendAttachments = { };
|
||||
std::array<VkFormat, DxvkLimits::MaxNumRenderTargets> rtColorFormats;
|
||||
uint32_t rtColorFormatCount = 0;
|
||||
|
||||
const VkColorComponentFlags fullMask
|
||||
= VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT
|
||||
| VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||
|
||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
||||
auto formatInfo = imageFormatInfo(passFormat.color[i].format);
|
||||
omBlendAttachments[i] = state.omBlend[i].state();
|
||||
rtColorFormats[i] = state.rt.getColorFormat(i);
|
||||
|
||||
if (!(m_fsOut & (1 << i)) || !formatInfo) {
|
||||
omBlendAttachments[i].colorWriteMask = 0;
|
||||
} else {
|
||||
if (omBlendAttachments[i].colorWriteMask != fullMask) {
|
||||
omBlendAttachments[i].colorWriteMask = util::remapComponentMask(
|
||||
state.omBlend[i].colorWriteMask(), state.omSwizzle[i].mapping());
|
||||
}
|
||||
if (rtColorFormats[i]) {
|
||||
rtColorFormatCount = i + 1;
|
||||
|
||||
omBlendAttachments[i].colorWriteMask &= formatInfo->componentMask;
|
||||
auto formatInfo = imageFormatInfo(rtColorFormats[i]);
|
||||
omBlendAttachments[i] = state.omBlend[i].state();
|
||||
|
||||
if (omBlendAttachments[i].colorWriteMask == formatInfo->componentMask) {
|
||||
omBlendAttachments[i].colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT
|
||||
| VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||
if (!(m_fsOut & (1 << i)) || !formatInfo) {
|
||||
omBlendAttachments[i].colorWriteMask = 0;
|
||||
} else {
|
||||
if (omBlendAttachments[i].colorWriteMask != fullMask) {
|
||||
omBlendAttachments[i].colorWriteMask = util::remapComponentMask(
|
||||
state.omBlend[i].colorWriteMask(), state.omSwizzle[i].mapping());
|
||||
}
|
||||
|
||||
omBlendAttachments[i].colorWriteMask &= formatInfo->componentMask;
|
||||
|
||||
if (omBlendAttachments[i].colorWriteMask == formatInfo->componentMask) {
|
||||
omBlendAttachments[i].colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT
|
||||
| VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -241,16 +250,11 @@ namespace dxvk {
|
||||
viAttribs[i].binding = viBindingMap[state.ilAttributes[i].binding()];
|
||||
}
|
||||
|
||||
VkPipelineVertexInputDivisorStateCreateInfoEXT viDivisorInfo;
|
||||
viDivisorInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT;
|
||||
viDivisorInfo.pNext = nullptr;
|
||||
VkPipelineVertexInputDivisorStateCreateInfoEXT viDivisorInfo = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT };
|
||||
viDivisorInfo.vertexBindingDivisorCount = viDivisorCount;
|
||||
viDivisorInfo.pVertexBindingDivisors = viDivisorDesc.data();
|
||||
|
||||
VkPipelineVertexInputStateCreateInfo viInfo;
|
||||
viInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
||||
viInfo.pNext = &viDivisorInfo;
|
||||
viInfo.flags = 0;
|
||||
VkPipelineVertexInputStateCreateInfo viInfo = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, &viDivisorInfo };
|
||||
viInfo.vertexBindingDescriptionCount = state.il.bindingCount();
|
||||
viInfo.pVertexBindingDescriptions = viBindings.data();
|
||||
viInfo.vertexAttributeDescriptionCount = state.il.attributeCount();
|
||||
@ -263,60 +267,34 @@ namespace dxvk {
|
||||
if (!m_pipeMgr->m_device->features().extVertexAttributeDivisor.vertexAttributeInstanceRateDivisor)
|
||||
viInfo.pNext = viDivisorInfo.pNext;
|
||||
|
||||
VkPipelineInputAssemblyStateCreateInfo iaInfo;
|
||||
iaInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
||||
iaInfo.pNext = nullptr;
|
||||
iaInfo.flags = 0;
|
||||
VkPipelineInputAssemblyStateCreateInfo iaInfo = { VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO };
|
||||
iaInfo.topology = state.ia.primitiveTopology();
|
||||
iaInfo.primitiveRestartEnable = state.ia.primitiveRestart();
|
||||
|
||||
VkPipelineTessellationStateCreateInfo tsInfo;
|
||||
tsInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
|
||||
tsInfo.pNext = nullptr;
|
||||
tsInfo.flags = 0;
|
||||
VkPipelineTessellationStateCreateInfo tsInfo = { VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO };
|
||||
tsInfo.patchControlPoints = state.ia.patchVertexCount();
|
||||
|
||||
VkPipelineViewportStateCreateInfo vpInfo;
|
||||
vpInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
||||
vpInfo.pNext = nullptr;
|
||||
vpInfo.flags = 0;
|
||||
VkPipelineViewportStateCreateInfo vpInfo = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO };
|
||||
vpInfo.viewportCount = state.rs.viewportCount();
|
||||
vpInfo.pViewports = nullptr;
|
||||
vpInfo.scissorCount = state.rs.viewportCount();
|
||||
vpInfo.pScissors = nullptr;
|
||||
|
||||
VkPipelineRasterizationConservativeStateCreateInfoEXT conservativeInfo;
|
||||
conservativeInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT;
|
||||
conservativeInfo.pNext = nullptr;
|
||||
conservativeInfo.flags = 0;
|
||||
VkPipelineRasterizationConservativeStateCreateInfoEXT conservativeInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT };
|
||||
conservativeInfo.conservativeRasterizationMode = state.rs.conservativeMode();
|
||||
conservativeInfo.extraPrimitiveOverestimationSize = 0.0f;
|
||||
|
||||
VkPipelineRasterizationStateStreamCreateInfoEXT xfbStreamInfo;
|
||||
xfbStreamInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT;
|
||||
xfbStreamInfo.pNext = nullptr;
|
||||
xfbStreamInfo.flags = 0;
|
||||
VkPipelineRasterizationStateStreamCreateInfoEXT xfbStreamInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT };
|
||||
xfbStreamInfo.rasterizationStream = uint32_t(rasterizedStream);
|
||||
|
||||
VkPipelineRasterizationDepthClipStateCreateInfoEXT rsDepthClipInfo;
|
||||
rsDepthClipInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT;
|
||||
rsDepthClipInfo.pNext = nullptr;
|
||||
rsDepthClipInfo.flags = 0;
|
||||
VkPipelineRasterizationDepthClipStateCreateInfoEXT rsDepthClipInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT };
|
||||
rsDepthClipInfo.depthClipEnable = state.rs.depthClipEnable();
|
||||
|
||||
VkPipelineRasterizationStateCreateInfo rsInfo;
|
||||
rsInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
||||
rsInfo.pNext = nullptr;
|
||||
rsInfo.flags = 0;
|
||||
VkPipelineRasterizationStateCreateInfo rsInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO };
|
||||
rsInfo.depthClampEnable = VK_TRUE;
|
||||
rsInfo.rasterizerDiscardEnable = rasterizedStream < 0;
|
||||
rsInfo.polygonMode = state.rs.polygonMode();
|
||||
rsInfo.cullMode = state.rs.cullMode();
|
||||
rsInfo.frontFace = state.rs.frontFace();
|
||||
rsInfo.depthBiasEnable = state.rs.depthBiasEnable();
|
||||
rsInfo.depthBiasConstantFactor= 0.0f;
|
||||
rsInfo.depthBiasClamp = 0.0f;
|
||||
rsInfo.depthBiasSlopeFactor = 0.0f;
|
||||
rsInfo.lineWidth = 1.0f;
|
||||
|
||||
if (rasterizedStream > 0)
|
||||
@ -332,10 +310,7 @@ namespace dxvk {
|
||||
|
||||
uint32_t sampleMask = state.ms.sampleMask();
|
||||
|
||||
VkPipelineMultisampleStateCreateInfo msInfo;
|
||||
msInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
||||
msInfo.pNext = nullptr;
|
||||
msInfo.flags = 0;
|
||||
VkPipelineMultisampleStateCreateInfo msInfo = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO };
|
||||
msInfo.rasterizationSamples = sampleCount;
|
||||
msInfo.sampleShadingEnable = m_common.msSampleShadingEnable;
|
||||
msInfo.minSampleShading = m_common.msSampleShadingFactor;
|
||||
@ -343,43 +318,41 @@ namespace dxvk {
|
||||
msInfo.alphaToCoverageEnable = state.ms.enableAlphaToCoverage();
|
||||
msInfo.alphaToOneEnable = VK_FALSE;
|
||||
|
||||
VkPipelineDepthStencilStateCreateInfo dsInfo;
|
||||
dsInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
||||
dsInfo.pNext = nullptr;
|
||||
dsInfo.flags = 0;
|
||||
VkPipelineDepthStencilStateCreateInfo dsInfo = { VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO };
|
||||
dsInfo.depthTestEnable = state.ds.enableDepthTest();
|
||||
dsInfo.depthWriteEnable = state.ds.enableDepthWrite() && !util::isDepthReadOnlyLayout(passFormat.depth.layout);
|
||||
dsInfo.depthWriteEnable = state.ds.enableDepthWrite() && !(rtReadOnlyAspects & VK_IMAGE_ASPECT_DEPTH_BIT);
|
||||
dsInfo.depthCompareOp = state.ds.depthCompareOp();
|
||||
dsInfo.depthBoundsTestEnable = state.ds.enableDepthBoundsTest();
|
||||
dsInfo.stencilTestEnable = state.ds.enableStencilTest();
|
||||
dsInfo.front = state.dsFront.state();
|
||||
dsInfo.back = state.dsBack.state();
|
||||
dsInfo.minDepthBounds = 0.0f;
|
||||
dsInfo.maxDepthBounds = 1.0f;
|
||||
|
||||
VkPipelineColorBlendStateCreateInfo cbInfo;
|
||||
cbInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
||||
cbInfo.pNext = nullptr;
|
||||
cbInfo.flags = 0;
|
||||
VkPipelineColorBlendStateCreateInfo cbInfo = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO };
|
||||
cbInfo.logicOpEnable = state.om.enableLogicOp();
|
||||
cbInfo.logicOp = state.om.logicOp();
|
||||
cbInfo.attachmentCount = DxvkLimits::MaxNumRenderTargets;
|
||||
cbInfo.attachmentCount = rtColorFormatCount;
|
||||
cbInfo.pAttachments = omBlendAttachments.data();
|
||||
|
||||
for (uint32_t i = 0; i < 4; i++)
|
||||
cbInfo.blendConstants[i] = 0.0f;
|
||||
|
||||
VkPipelineDynamicStateCreateInfo dyInfo;
|
||||
dyInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
|
||||
dyInfo.pNext = nullptr;
|
||||
dyInfo.flags = 0;
|
||||
VkPipelineDynamicStateCreateInfo dyInfo = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO };
|
||||
dyInfo.dynamicStateCount = dynamicStateCount;
|
||||
dyInfo.pDynamicStates = dynamicStates.data();
|
||||
|
||||
VkGraphicsPipelineCreateInfo info;
|
||||
info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||
info.pNext = nullptr;
|
||||
info.flags = 0;
|
||||
|
||||
VkPipelineRenderingCreateInfoKHR rtInfo = { VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR };
|
||||
|
||||
if (rtColorFormatCount) {
|
||||
rtInfo.colorAttachmentCount = rtColorFormatCount;
|
||||
rtInfo.pColorAttachmentFormats = rtColorFormats.data();
|
||||
}
|
||||
|
||||
if (rtDepthFormat) {
|
||||
if (rtDepthFormatInfo->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT)
|
||||
rtInfo.depthAttachmentFormat = rtDepthFormat;
|
||||
|
||||
if (rtDepthFormatInfo->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT)
|
||||
rtInfo.stencilAttachmentFormat = rtDepthFormat;
|
||||
}
|
||||
|
||||
VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &rtInfo };
|
||||
info.stageCount = stages.size();
|
||||
info.pStages = stages.data();
|
||||
info.pVertexInputState = &viInfo;
|
||||
@ -392,12 +365,9 @@ namespace dxvk {
|
||||
info.pColorBlendState = &cbInfo;
|
||||
info.pDynamicState = &dyInfo;
|
||||
info.layout = m_bindings->getPipelineLayout();
|
||||
info.renderPass = renderPass->getDefaultHandle();
|
||||
info.subpass = 0;
|
||||
info.basePipelineHandle = VK_NULL_HANDLE;
|
||||
info.basePipelineIndex = -1;
|
||||
|
||||
if (tsInfo.patchControlPoints == 0)
|
||||
if (!tsInfo.patchControlPoints)
|
||||
info.pTessellationState = nullptr;
|
||||
|
||||
// Time pipeline compilation for debugging purposes
|
||||
|
@ -477,6 +477,97 @@ namespace dxvk {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Packed render target formats
|
||||
*
|
||||
* Compact representation of depth-stencil and color attachments,
|
||||
* as well as the read-only mask for the depth-stencil attachment,
|
||||
* which needs to be known at pipeline compile time.
|
||||
*/
|
||||
class DxvkRtInfo {
|
||||
|
||||
public:
|
||||
|
||||
DxvkRtInfo() = default;
|
||||
|
||||
DxvkRtInfo(
|
||||
uint32_t colorFormatCount,
|
||||
const VkFormat* colorFormats,
|
||||
VkFormat depthStencilFormat,
|
||||
VkImageAspectFlags depthStencilReadOnlyAspects)
|
||||
: m_packedData(0ull) {
|
||||
m_packedData |= encodeDepthStencilFormat(depthStencilFormat);
|
||||
m_packedData |= encodeDepthStencilAspects(depthStencilReadOnlyAspects);
|
||||
|
||||
for (uint32_t i = 0; i < colorFormatCount; i++)
|
||||
m_packedData |= encodeColorFormat(colorFormats[i], i);
|
||||
}
|
||||
|
||||
VkFormat getColorFormat(uint32_t index) const {
|
||||
return decodeColorFormat(m_packedData, index);
|
||||
}
|
||||
|
||||
VkFormat getDepthStencilFormat() const {
|
||||
return decodeDepthStencilFormat(m_packedData);
|
||||
}
|
||||
|
||||
VkImageAspectFlags getDepthStencilReadOnlyAspects() const {
|
||||
return decodeDepthStencilAspects(m_packedData);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
uint64_t m_packedData;
|
||||
|
||||
static uint64_t encodeDepthStencilAspects(VkImageAspectFlags aspects) {
|
||||
return uint64_t(aspects) << 61;
|
||||
}
|
||||
|
||||
static uint64_t encodeDepthStencilFormat(VkFormat format) {
|
||||
return format
|
||||
? (uint64_t(format) - uint64_t(VK_FORMAT_E5B9G9R9_UFLOAT_PACK32)) << 56
|
||||
: (uint64_t(0));
|
||||
}
|
||||
|
||||
static uint64_t encodeColorFormat(VkFormat format, uint32_t index) {
|
||||
uint64_t value = uint64_t(format);
|
||||
|
||||
if (value >= uint64_t(VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT)) {
|
||||
value -= uint64_t(VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT);
|
||||
value += uint64_t(VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) + 1;
|
||||
} else if (value > uint64_t(VK_FORMAT_E5B9G9R9_UFLOAT_PACK32)) {
|
||||
value = 0;
|
||||
}
|
||||
|
||||
return value << (7 * index);
|
||||
}
|
||||
|
||||
static VkImageAspectFlags decodeDepthStencilAspects(uint64_t value) {
|
||||
return VkImageAspectFlags((value >> 61) & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));
|
||||
}
|
||||
|
||||
static VkFormat decodeDepthStencilFormat(uint64_t value) {
|
||||
value = (value >> 56) & 0x1F;
|
||||
|
||||
return value
|
||||
? VkFormat(value + uint64_t(VK_FORMAT_E5B9G9R9_UFLOAT_PACK32))
|
||||
: VkFormat(VK_FORMAT_UNDEFINED);
|
||||
}
|
||||
|
||||
static VkFormat decodeColorFormat(uint64_t value, uint32_t index) {
|
||||
value = (value >> (7 * index)) & 0x7F;
|
||||
|
||||
if (value > uint64_t(VK_FORMAT_E5B9G9R9_UFLOAT_PACK32)) {
|
||||
value -= uint64_t(VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) + 1ull;
|
||||
value += uint64_t(VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT);
|
||||
}
|
||||
|
||||
return VkFormat(value);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Packed attachment blend mode
|
||||
*
|
||||
@ -685,6 +776,7 @@ namespace dxvk {
|
||||
DxvkMsInfo ms;
|
||||
DxvkDsInfo ds;
|
||||
DxvkOmInfo om;
|
||||
DxvkRtInfo rt;
|
||||
DxvkScInfo sc;
|
||||
DxvkDsStencilOp dsFront;
|
||||
DxvkDsStencilOp dsBack;
|
||||
|
Loading…
x
Reference in New Issue
Block a user