mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-11-29 19:24:10 +01:00
[dxvk] Fixed resource binding with invalidated buffers
When invalidating a constant buffer, the descriptor was not updated, which usually led to the wrong resource being used and could also cause crashes. This fix also includes resource tracking for shader resources on the graphics pipeline. The code needs to be made compatible with the compute pipeline as well.
This commit is contained in:
parent
6df9fc75d2
commit
da2cc5a6a0
@ -27,16 +27,7 @@ namespace dxvk {
|
||||
|
||||
DxvkShaderResourceSlots() { }
|
||||
DxvkShaderResourceSlots(size_t n) {
|
||||
m_resources .resize(n);
|
||||
m_descriptors.resize(n);
|
||||
}
|
||||
|
||||
uint32_t descriptorCount() const {
|
||||
return m_descriptors.size();
|
||||
}
|
||||
|
||||
const DxvkDescriptorInfo* descriptors() const {
|
||||
return m_descriptors.data();
|
||||
m_resources.resize(n);
|
||||
}
|
||||
|
||||
const DxvkShaderResourceSlot& getShaderResource(uint32_t slot) const {
|
||||
@ -45,16 +36,13 @@ namespace dxvk {
|
||||
|
||||
void bindShaderResource(
|
||||
uint32_t slot,
|
||||
const DxvkShaderResourceSlot& resource,
|
||||
const DxvkDescriptorInfo& descriptor) {
|
||||
m_resources .at(slot) = resource;
|
||||
m_descriptors .at(slot) = descriptor;
|
||||
const DxvkShaderResourceSlot& resource) {
|
||||
m_resources.at(slot) = resource;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::vector<DxvkShaderResourceSlot> m_resources;
|
||||
std::vector<DxvkDescriptorInfo> m_descriptors;
|
||||
|
||||
};
|
||||
|
||||
|
@ -120,9 +120,9 @@ namespace dxvk {
|
||||
curr.dstArrayElement = 0;
|
||||
curr.descriptorCount = 1;
|
||||
curr.descriptorType = binding.type;
|
||||
curr.pImageInfo = &descriptorInfos[binding.slot].image;
|
||||
curr.pBufferInfo = &descriptorInfos[binding.slot].buffer;
|
||||
curr.pTexelBufferView = &descriptorInfos[binding.slot].texelBuffer;
|
||||
curr.pImageInfo = &descriptorInfos[i].image;
|
||||
curr.pBufferInfo = &descriptorInfos[i].buffer;
|
||||
curr.pTexelBufferView = &descriptorInfos[i].texelBuffer;
|
||||
}
|
||||
|
||||
m_vkd->vkUpdateDescriptorSets(
|
||||
|
@ -81,12 +81,7 @@ namespace dxvk {
|
||||
DxvkShaderResourceSlot resource;
|
||||
resource.bufferSlice = buffer;
|
||||
|
||||
DxvkDescriptorInfo descriptor;
|
||||
|
||||
if (buffer.handle() != VK_NULL_HANDLE)
|
||||
descriptor.buffer = buffer.descriptorInfo();
|
||||
|
||||
rc->bindShaderResource(slot, resource, descriptor);
|
||||
rc->bindShaderResource(slot, resource);
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,12 +98,7 @@ namespace dxvk {
|
||||
DxvkShaderResourceSlot resource;
|
||||
resource.bufferView = bufferView;
|
||||
|
||||
DxvkDescriptorInfo descriptor;
|
||||
|
||||
if (bufferView != nullptr)
|
||||
descriptor.texelBuffer = bufferView->handle();
|
||||
|
||||
rc->bindShaderResource(slot, resource, descriptor);
|
||||
rc->bindShaderResource(slot, resource);
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,14 +115,7 @@ namespace dxvk {
|
||||
DxvkShaderResourceSlot resource;
|
||||
resource.imageView = image;
|
||||
|
||||
DxvkDescriptorInfo descriptor;
|
||||
|
||||
if (image != nullptr) {
|
||||
descriptor.image.imageView = image->handle();
|
||||
descriptor.image.imageLayout = image->imageInfo().layout;
|
||||
}
|
||||
|
||||
rc->bindShaderResource(slot, resource, descriptor);
|
||||
rc->bindShaderResource(slot, resource);
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,12 +132,7 @@ namespace dxvk {
|
||||
DxvkShaderResourceSlot resource;
|
||||
resource.sampler = sampler;
|
||||
|
||||
DxvkDescriptorInfo descriptor;
|
||||
|
||||
if (sampler != nullptr)
|
||||
descriptor.image.sampler = sampler->handle();
|
||||
|
||||
rc->bindShaderResource(slot, resource, descriptor);
|
||||
rc->bindShaderResource(slot, resource);
|
||||
}
|
||||
}
|
||||
|
||||
@ -867,13 +845,13 @@ namespace dxvk {
|
||||
|
||||
// TODO refcount used resources
|
||||
|
||||
m_cmd->bindResourceDescriptors(
|
||||
VK_PIPELINE_BIND_POINT_COMPUTE,
|
||||
layout->pipelineLayout(),
|
||||
layout->descriptorSetLayout(),
|
||||
layout->bindingCount(),
|
||||
layout->bindings(),
|
||||
m_cResources.descriptors());
|
||||
// m_cmd->bindResourceDescriptors(
|
||||
// VK_PIPELINE_BIND_POINT_COMPUTE,
|
||||
// layout->pipelineLayout(),
|
||||
// layout->descriptorSetLayout(),
|
||||
// layout->bindingCount(),
|
||||
// layout->bindings(),
|
||||
// m_cResources.descriptors());
|
||||
}
|
||||
}
|
||||
|
||||
@ -884,13 +862,51 @@ namespace dxvk {
|
||||
|
||||
auto layout = m_state.gp.pipeline->layout();
|
||||
|
||||
// TODO recreate resource views if the underlying
|
||||
// resource was marked as dirty after invalidation
|
||||
// TODO move this into a separate method so that
|
||||
// compute can use this code as well
|
||||
std::vector<DxvkDescriptorInfo> descriptors;
|
||||
|
||||
for (uint32_t i = 0; i < layout->bindingCount(); i++) {
|
||||
const uint32_t slot = layout->binding(i).slot;
|
||||
const auto& res = m_gResources.getShaderResource(slot);
|
||||
|
||||
DxvkDescriptorInfo descriptor;
|
||||
|
||||
if (res.sampler != nullptr) {
|
||||
m_cmd->trackResource(res.sampler);
|
||||
descriptor.image.sampler = res.sampler->handle();
|
||||
}
|
||||
|
||||
if (res.imageView != nullptr) {
|
||||
m_cmd->trackResource(res.imageView);
|
||||
m_cmd->trackResource(res.imageView->image());
|
||||
descriptor.image.imageView = res.imageView->handle();
|
||||
descriptor.image.imageLayout = res.imageView->imageInfo().layout;
|
||||
}
|
||||
|
||||
if (res.bufferView != nullptr) {
|
||||
m_cmd->trackResource(res.bufferView);
|
||||
m_cmd->trackResource(res.bufferView->buffer()->resource());
|
||||
descriptor.texelBuffer = res.bufferView->handle();
|
||||
}
|
||||
|
||||
if (res.bufferSlice.handle() != VK_NULL_HANDLE) {
|
||||
m_cmd->trackResource(res.bufferSlice.buffer()->resource());
|
||||
descriptor.buffer = res.bufferSlice.descriptorInfo();
|
||||
}
|
||||
|
||||
descriptors.push_back(descriptor);
|
||||
}
|
||||
|
||||
m_cmd->bindResourceDescriptors(
|
||||
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
layout->pipelineLayout(),
|
||||
layout->descriptorSetLayout(),
|
||||
layout->bindingCount(),
|
||||
layout->bindings(),
|
||||
m_gResources.descriptors());
|
||||
descriptors.data());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1073,7 +1089,7 @@ namespace dxvk {
|
||||
m_barriers.recordCommands(m_cmd);
|
||||
}
|
||||
|
||||
|
||||
|
||||
DxvkShaderResourceSlots* DxvkContext::getShaderResourceSlots(VkPipelineBindPoint pipe) {
|
||||
switch (pipe) {
|
||||
case VK_PIPELINE_BIND_POINT_GRAPHICS: return &m_gResources;
|
||||
|
@ -108,6 +108,16 @@ namespace dxvk {
|
||||
return m_bindingSlots.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Resource binding info
|
||||
*
|
||||
* \param [in] id Binding index
|
||||
* \returns Resource binding info
|
||||
*/
|
||||
const DxvkDescriptorSlot& binding(uint32_t id) const {
|
||||
return m_bindingSlots.at(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Resource binding info
|
||||
* \returns Resource binding info
|
||||
|
Loading…
Reference in New Issue
Block a user