mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-14 04:29:15 +01:00
[dxvk] Implementing unbound resource handling (2/4)
Refactored pipeline binding and descriptor set updates so that no descriptor info gets written for unbound resources.
This commit is contained in:
parent
c64103c73f
commit
b22d56ac06
@ -94,33 +94,36 @@ namespace dxvk {
|
||||
VkDescriptorSetLayout descriptorLayout,
|
||||
uint32_t descriptorCount,
|
||||
const DxvkDescriptorSlot* descriptorSlots,
|
||||
const DxvkDescriptorInfo* descriptorInfos) {
|
||||
const DxvkDescriptorInfo* descriptorInfos,
|
||||
const DxvkBindingState& bindingState) {
|
||||
|
||||
// Allocate a new descriptor set
|
||||
VkDescriptorSet dset = m_descAlloc.alloc(descriptorLayout);
|
||||
|
||||
// Write data to the descriptor set
|
||||
std::array<VkWriteDescriptorSet, MaxNumResourceSlots> descriptorWrites;
|
||||
uint32_t writeId = 0;
|
||||
|
||||
for (uint32_t i = 0; i < descriptorCount; i++) {
|
||||
auto& curr = descriptorWrites[i];
|
||||
auto& binding = descriptorSlots[i];
|
||||
|
||||
curr.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
curr.pNext = nullptr;
|
||||
curr.dstSet = dset;
|
||||
curr.dstBinding = i;
|
||||
curr.dstArrayElement = 0;
|
||||
curr.descriptorCount = 1;
|
||||
curr.descriptorType = binding.type;
|
||||
curr.pImageInfo = &descriptorInfos[i].image;
|
||||
curr.pBufferInfo = &descriptorInfos[i].buffer;
|
||||
curr.pTexelBufferView = &descriptorInfos[i].texelBuffer;
|
||||
if (bindingState.isBound(i)) {
|
||||
auto& curr = descriptorWrites[writeId++];
|
||||
auto& binding = descriptorSlots[i];
|
||||
|
||||
curr.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
curr.pNext = nullptr;
|
||||
curr.dstSet = dset;
|
||||
curr.dstBinding = i;
|
||||
curr.dstArrayElement = 0;
|
||||
curr.descriptorCount = 1;
|
||||
curr.descriptorType = binding.type;
|
||||
curr.pImageInfo = &descriptorInfos[i].image;
|
||||
curr.pBufferInfo = &descriptorInfos[i].buffer;
|
||||
curr.pTexelBufferView = &descriptorInfos[i].texelBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
m_vkd->vkUpdateDescriptorSets(
|
||||
m_vkd->device(),
|
||||
descriptorCount,
|
||||
m_vkd->device(), writeId,
|
||||
descriptorWrites.data(),
|
||||
0, nullptr);
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
#include "dxvk_binding.h"
|
||||
#include "dxvk_descriptor.h"
|
||||
#include "dxvk_lifetime.h"
|
||||
#include "dxvk_limits.h"
|
||||
@ -87,7 +88,8 @@ namespace dxvk {
|
||||
VkDescriptorSetLayout descriptorLayout,
|
||||
uint32_t descriptorCount,
|
||||
const DxvkDescriptorSlot* descriptorSlots,
|
||||
const DxvkDescriptorInfo* descriptorInfos);
|
||||
const DxvkDescriptorInfo* descriptorInfos,
|
||||
const DxvkBindingState& bindingState);
|
||||
|
||||
void cmdBeginRenderPass(
|
||||
const VkRenderPassBeginInfo* pRenderPassBegin,
|
||||
|
@ -142,10 +142,12 @@ namespace dxvk {
|
||||
if (stage == VK_SHADER_STAGE_COMPUTE_BIT) {
|
||||
m_flags.set(
|
||||
DxvkContextFlag::CpDirtyPipeline,
|
||||
DxvkContextFlag::CpDirtyPipelineState,
|
||||
DxvkContextFlag::CpDirtyResources);
|
||||
} else {
|
||||
m_flags.set(
|
||||
DxvkContextFlag::GpDirtyPipeline,
|
||||
DxvkContextFlag::GpDirtyPipelineState,
|
||||
DxvkContextFlag::GpDirtyResources);
|
||||
}
|
||||
}
|
||||
@ -920,17 +922,22 @@ namespace dxvk {
|
||||
|
||||
|
||||
void DxvkContext::updateGraphicsPipeline() {
|
||||
if (m_flags.any(DxvkContextFlag::GpDirtyPipeline, DxvkContextFlag::GpDirtyPipelineState)) {
|
||||
m_flags.clr(DxvkContextFlag::GpDirtyPipelineState);
|
||||
if (m_flags.test(DxvkContextFlag::GpDirtyPipeline)) {
|
||||
m_flags.clr(DxvkContextFlag::GpDirtyPipeline);
|
||||
|
||||
if (m_flags.test(DxvkContextFlag::GpDirtyPipeline)) {
|
||||
m_flags.clr(DxvkContextFlag::GpDirtyPipeline);
|
||||
|
||||
m_state.gp.bs.clear();
|
||||
m_state.gp.pipeline = m_device->createGraphicsPipeline(
|
||||
m_state.gp.vs.shader, m_state.gp.tcs.shader, m_state.gp.tes.shader,
|
||||
m_state.gp.gs.shader, m_state.gp.fs.shader);
|
||||
}
|
||||
m_state.gp.bs.clear();
|
||||
m_state.gp.pipeline = m_device->createGraphicsPipeline(
|
||||
m_state.gp.vs.shader, m_state.gp.tcs.shader, m_state.gp.tes.shader,
|
||||
m_state.gp.gs.shader, m_state.gp.fs.shader);
|
||||
|
||||
m_cmd->trackResource(m_state.gp.pipeline);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::updateGraphicsPipelineState() {
|
||||
if (m_flags.test(DxvkContextFlag::GpDirtyPipelineState)) {
|
||||
m_flags.clr(DxvkContextFlag::GpDirtyPipelineState);
|
||||
|
||||
DxvkGraphicsPipelineStateInfo gpState;
|
||||
gpState.bsBindingState = m_state.gp.bs;
|
||||
@ -1005,15 +1012,12 @@ namespace dxvk {
|
||||
|
||||
m_cmd->cmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
m_state.gp.pipeline->getPipelineHandle(gpState));
|
||||
m_cmd->trackResource(m_state.gp.pipeline);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::updateComputeShaderResources() {
|
||||
if (m_flags.test(DxvkContextFlag::CpDirtyResources)) {
|
||||
m_flags.clr(DxvkContextFlag::CpDirtyResources);
|
||||
|
||||
this->updateShaderResources(
|
||||
VK_PIPELINE_BIND_POINT_COMPUTE,
|
||||
m_state.cp.pipeline->layout());
|
||||
@ -1021,12 +1025,34 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::updateComputeShaderDescriptors() {
|
||||
if (m_flags.test(DxvkContextFlag::CpDirtyResources)) {
|
||||
m_flags.clr(DxvkContextFlag::CpDirtyResources);
|
||||
|
||||
this->updateShaderDescriptors(
|
||||
VK_PIPELINE_BIND_POINT_COMPUTE,
|
||||
m_state.cp.bs,
|
||||
m_state.cp.pipeline->layout());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::updateGraphicsShaderResources() {
|
||||
if (m_flags.test(DxvkContextFlag::GpDirtyResources)) {
|
||||
this->updateShaderResources(
|
||||
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
m_state.gp.pipeline->layout());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::updateGraphicsShaderDescriptors() {
|
||||
if (m_flags.test(DxvkContextFlag::GpDirtyResources)) {
|
||||
m_flags.clr(DxvkContextFlag::GpDirtyResources);
|
||||
|
||||
this->updateShaderResources(
|
||||
this->updateShaderDescriptors(
|
||||
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
m_state.gp.bs,
|
||||
m_state.gp.pipeline->layout());
|
||||
}
|
||||
}
|
||||
@ -1059,7 +1085,6 @@ namespace dxvk {
|
||||
|
||||
m_cmd->trackResource(res.sampler);
|
||||
} else {
|
||||
Logger::err("DxvkContext: Unbound sampler descriptor");
|
||||
updatePipelineState |= bs.setUnbound(i);
|
||||
|
||||
m_descriptors[i].image.sampler = VK_NULL_HANDLE;
|
||||
@ -1069,7 +1094,7 @@ namespace dxvk {
|
||||
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
|
||||
if (res.imageView != nullptr/* && res.imageView->type() != binding.view*/) {
|
||||
if (res.imageView != nullptr && res.imageView->type() != binding.view) {
|
||||
updatePipelineState |= bs.setBound(i);
|
||||
|
||||
m_descriptors[i].image.sampler = VK_NULL_HANDLE;
|
||||
@ -1079,7 +1104,6 @@ namespace dxvk {
|
||||
m_cmd->trackResource(res.imageView);
|
||||
m_cmd->trackResource(res.imageView->image());
|
||||
} else {
|
||||
Logger::err("DxvkContext: Unbound or incompatible image descriptor");
|
||||
updatePipelineState |= bs.setUnbound(i);
|
||||
|
||||
m_descriptors[i].image.sampler = VK_NULL_HANDLE;
|
||||
@ -1097,7 +1121,6 @@ namespace dxvk {
|
||||
m_cmd->trackResource(res.bufferView);
|
||||
m_cmd->trackResource(res.bufferView->buffer()->resource());
|
||||
} else {
|
||||
Logger::err("DxvkContext: Unbound texel buffer");
|
||||
updatePipelineState |= bs.setUnbound(i);
|
||||
|
||||
m_descriptors[i].texelBuffer = VK_NULL_HANDLE;
|
||||
@ -1111,7 +1134,6 @@ namespace dxvk {
|
||||
m_descriptors[i].buffer = res.bufferSlice.descriptorInfo();
|
||||
m_cmd->trackResource(res.bufferSlice.resource());
|
||||
} else {
|
||||
Logger::err("DxvkContext: Unbound buffer");
|
||||
updatePipelineState |= bs.setUnbound(i);
|
||||
|
||||
m_descriptors[i].buffer.buffer = VK_NULL_HANDLE;
|
||||
@ -1124,19 +1146,26 @@ namespace dxvk {
|
||||
}
|
||||
}
|
||||
|
||||
if (updatePipelineState) {
|
||||
m_flags.set(bindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS
|
||||
? DxvkContextFlag::GpDirtyPipelineState
|
||||
: DxvkContextFlag::CpDirtyPipelineState);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::updateShaderDescriptors(
|
||||
VkPipelineBindPoint bindPoint,
|
||||
const DxvkBindingState& bindingState,
|
||||
const Rc<DxvkBindingLayout>& layout) {
|
||||
m_cmd->bindResourceDescriptors(
|
||||
bindPoint,
|
||||
layout->pipelineLayout(),
|
||||
layout->descriptorSetLayout(),
|
||||
layout->bindingCount(),
|
||||
layout->bindings(),
|
||||
m_descriptors.data());
|
||||
|
||||
if (updatePipelineState) {
|
||||
m_flags.set(bindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS
|
||||
? DxvkContextFlag::GpDirtyPipelineState
|
||||
: DxvkContextFlag::CpDirtyPipelineState);
|
||||
}
|
||||
m_descriptors.data(),
|
||||
bindingState);
|
||||
}
|
||||
|
||||
|
||||
@ -1213,6 +1242,7 @@ namespace dxvk {
|
||||
this->renderPassEnd();
|
||||
this->updateComputePipeline();
|
||||
this->updateComputeShaderResources();
|
||||
this->updateComputeShaderDescriptors();
|
||||
}
|
||||
|
||||
|
||||
@ -1223,6 +1253,8 @@ namespace dxvk {
|
||||
this->updateIndexBufferBinding();
|
||||
this->updateVertexBufferBindings();
|
||||
this->updateGraphicsShaderResources();
|
||||
this->updateGraphicsPipelineState();
|
||||
this->updateGraphicsShaderDescriptors();
|
||||
}
|
||||
|
||||
|
||||
|
@ -492,15 +492,25 @@ namespace dxvk {
|
||||
void renderPassEnd();
|
||||
|
||||
void updateComputePipeline();
|
||||
|
||||
void updateGraphicsPipeline();
|
||||
void updateGraphicsPipelineState();
|
||||
|
||||
void updateComputeShaderResources();
|
||||
void updateComputeShaderDescriptors();
|
||||
|
||||
void updateGraphicsShaderResources();
|
||||
void updateGraphicsShaderDescriptors();
|
||||
|
||||
void updateShaderResources(
|
||||
VkPipelineBindPoint bindPoint,
|
||||
const Rc<DxvkBindingLayout>& layout);
|
||||
|
||||
void updateShaderDescriptors(
|
||||
VkPipelineBindPoint bindPoint,
|
||||
const DxvkBindingState& bindingState,
|
||||
const Rc<DxvkBindingLayout>& layout);
|
||||
|
||||
void updateDynamicState();
|
||||
void updateViewports();
|
||||
void updateBlendConstants();
|
||||
|
Loading…
x
Reference in New Issue
Block a user