1
0
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:
Philip Rebohle 2017-12-19 01:08:48 +01:00
parent 6df9fc75d2
commit da2cc5a6a0
4 changed files with 67 additions and 53 deletions

View File

@ -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;
};

View File

@ -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(

View File

@ -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;

View File

@ -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