mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-21 04:54:15 +01:00
[dxvk] Introduce tracking ID for resource tracking
Replaces the existing bit masks, which is possible now because the CS thread is the only place where submissions happen now. This way we only count each resource once per submission, or twice in case a read access is followed by a write. This also fixes a potential tracking bug with shader-writeable resources.
This commit is contained in:
parent
10fac66007
commit
0e14fff749
@ -289,17 +289,20 @@ namespace dxvk {
|
||||
*/
|
||||
template<typename T>
|
||||
void track(Rc<T>&& object, DxvkAccess access) {
|
||||
m_objectTracker.track<DxvkResourceRef>(std::move(object), access, m_trackingId);
|
||||
if (object->trackId(m_trackingId, access))
|
||||
m_objectTracker.track<DxvkResourceRef>(std::move(object), access);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void track(const Rc<T>& object, DxvkAccess access) {
|
||||
m_objectTracker.track<DxvkResourceRef>(object.ptr(), access, m_trackingId);
|
||||
if (object->trackId(m_trackingId, access))
|
||||
m_objectTracker.track<DxvkResourceRef>(object.ptr(), access);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void track(T* object, DxvkAccess access) {
|
||||
m_objectTracker.track<DxvkResourceRef>(object, access, m_trackingId);
|
||||
if (object->trackId(m_trackingId, access))
|
||||
m_objectTracker.track<DxvkResourceRef>(object, access);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5137,8 +5137,7 @@ namespace dxvk {
|
||||
descriptorInfo.image.imageView = VK_NULL_HANDLE;
|
||||
descriptorInfo.image.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
|
||||
if (m_rcTracked.set(binding.resourceBinding))
|
||||
m_cmd->track(res.sampler);
|
||||
m_cmd->track(res.sampler);
|
||||
} else {
|
||||
descriptorInfo.image.sampler = m_common->dummyResources().samplerHandle();
|
||||
descriptorInfo.image.imageView = VK_NULL_HANDLE;
|
||||
@ -5159,8 +5158,7 @@ namespace dxvk {
|
||||
descriptorInfo.image.imageView = viewHandle;
|
||||
descriptorInfo.image.imageLayout = res.imageView->image()->info().layout;
|
||||
|
||||
if (m_rcTracked.set(binding.resourceBinding))
|
||||
m_cmd->track(res.imageView->image(), DxvkAccess::Read);
|
||||
m_cmd->track(res.imageView->image(), DxvkAccess::Read);
|
||||
} else {
|
||||
descriptorInfo.image.sampler = VK_NULL_HANDLE;
|
||||
descriptorInfo.image.imageView = VK_NULL_HANDLE;
|
||||
@ -5181,10 +5179,8 @@ namespace dxvk {
|
||||
descriptorInfo.image.imageView = viewHandle;
|
||||
descriptorInfo.image.imageLayout = res.imageView->image()->info().layout;
|
||||
|
||||
if (m_rcTracked.set(binding.resourceBinding)) {
|
||||
m_cmd->track(res.imageView->image(), (binding.access & vk::AccessWriteMask)
|
||||
? DxvkAccess::Write : DxvkAccess::Read);
|
||||
}
|
||||
m_cmd->track(res.imageView->image(), (binding.access & vk::AccessWriteMask)
|
||||
? DxvkAccess::Write : DxvkAccess::Read);
|
||||
} else {
|
||||
descriptorInfo.image.sampler = VK_NULL_HANDLE;
|
||||
descriptorInfo.image.imageView = VK_NULL_HANDLE;
|
||||
@ -5205,10 +5201,8 @@ namespace dxvk {
|
||||
descriptorInfo.image.imageView = viewHandle;
|
||||
descriptorInfo.image.imageLayout = res.imageView->image()->info().layout;
|
||||
|
||||
if (m_rcTracked.set(binding.resourceBinding)) {
|
||||
m_cmd->track(res.sampler);
|
||||
m_cmd->track(res.imageView->image(), DxvkAccess::Read);
|
||||
}
|
||||
m_cmd->track(res.sampler);
|
||||
m_cmd->track(res.imageView->image(), DxvkAccess::Read);
|
||||
} else {
|
||||
descriptorInfo.image.sampler = m_common->dummyResources().samplerHandle();
|
||||
descriptorInfo.image.imageView = VK_NULL_HANDLE;
|
||||
@ -5222,8 +5216,7 @@ namespace dxvk {
|
||||
if (res.bufferView != nullptr) {
|
||||
descriptorInfo.texelBuffer = res.bufferView->handle();
|
||||
|
||||
if (m_rcTracked.set(binding.resourceBinding))
|
||||
m_cmd->track(res.bufferView->buffer(), DxvkAccess::Read);
|
||||
m_cmd->track(res.bufferView->buffer(), DxvkAccess::Read);
|
||||
} else {
|
||||
descriptorInfo.texelBuffer = VK_NULL_HANDLE;
|
||||
}
|
||||
@ -5235,10 +5228,8 @@ namespace dxvk {
|
||||
if (res.bufferView != nullptr) {
|
||||
descriptorInfo.texelBuffer = res.bufferView->handle();
|
||||
|
||||
if (m_rcTracked.set(binding.resourceBinding)) {
|
||||
m_cmd->track(res.bufferView->buffer(), (binding.access & vk::AccessWriteMask)
|
||||
? DxvkAccess::Write : DxvkAccess::Read);
|
||||
}
|
||||
m_cmd->track(res.bufferView->buffer(), (binding.access & vk::AccessWriteMask)
|
||||
? DxvkAccess::Write : DxvkAccess::Read);
|
||||
} else {
|
||||
descriptorInfo.texelBuffer = VK_NULL_HANDLE;
|
||||
}
|
||||
@ -5250,8 +5241,7 @@ namespace dxvk {
|
||||
if (res.bufferSlice.length()) {
|
||||
descriptorInfo = res.bufferSlice.getDescriptor();
|
||||
|
||||
if (m_rcTracked.set(binding.resourceBinding))
|
||||
m_cmd->track(res.bufferSlice.buffer(), DxvkAccess::Read);
|
||||
m_cmd->track(res.bufferSlice.buffer(), DxvkAccess::Read);
|
||||
} else {
|
||||
descriptorInfo.buffer.buffer = VK_NULL_HANDLE;
|
||||
descriptorInfo.buffer.offset = 0;
|
||||
@ -5265,10 +5255,8 @@ namespace dxvk {
|
||||
if (res.bufferSlice.length()) {
|
||||
descriptorInfo = res.bufferSlice.getDescriptor();
|
||||
|
||||
if (m_rcTracked.set(binding.resourceBinding)) {
|
||||
m_cmd->track(res.bufferSlice.buffer(), (binding.access & vk::AccessWriteMask)
|
||||
? DxvkAccess::Write : DxvkAccess::Read);
|
||||
}
|
||||
m_cmd->track(res.bufferSlice.buffer(), (binding.access & vk::AccessWriteMask)
|
||||
? DxvkAccess::Write : DxvkAccess::Read);
|
||||
} else {
|
||||
descriptorInfo.buffer.buffer = VK_NULL_HANDLE;
|
||||
descriptorInfo.buffer.offset = 0;
|
||||
@ -5552,9 +5540,7 @@ namespace dxvk {
|
||||
m_state.vi.indexType);
|
||||
}
|
||||
|
||||
if (m_vbTracked.set(MaxNumVertexBindings))
|
||||
m_cmd->track(m_state.vi.indexBuffer.buffer(), DxvkAccess::Read);
|
||||
|
||||
m_cmd->track(m_state.vi.indexBuffer.buffer(), DxvkAccess::Read);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -5591,8 +5577,7 @@ namespace dxvk {
|
||||
newDynamicStrides &= strides[i] >= m_state.vi.vertexExtents[i];
|
||||
}
|
||||
|
||||
if (m_vbTracked.set(binding))
|
||||
m_cmd->track(m_state.vi.vertexBuffers[binding].buffer(), DxvkAccess::Read);
|
||||
m_cmd->track(m_state.vi.vertexBuffers[binding].buffer(), DxvkAccess::Read);
|
||||
} else {
|
||||
buffers[i] = VK_NULL_HANDLE;
|
||||
offsets[i] = 0;
|
||||
@ -6669,10 +6654,6 @@ namespace dxvk {
|
||||
|
||||
|
||||
void DxvkContext::beginCurrentCommands() {
|
||||
// Mark all resources as untracked
|
||||
m_vbTracked.clear();
|
||||
m_rcTracked.clear();
|
||||
|
||||
// The current state of the internal command buffer is
|
||||
// undefined, so we have to bind and set up everything
|
||||
// before any draw or dispatch command is recorded.
|
||||
|
@ -177,9 +177,6 @@ namespace dxvk {
|
||||
void bindIndexBuffer(
|
||||
DxvkBufferSlice&& buffer,
|
||||
VkIndexType indexType) {
|
||||
if (!m_state.vi.indexBuffer.matchesBuffer(buffer))
|
||||
m_vbTracked.clr(MaxNumVertexBindings);
|
||||
|
||||
m_state.vi.indexBuffer = std::move(buffer);
|
||||
m_state.vi.indexType = indexType;
|
||||
|
||||
@ -218,11 +215,6 @@ namespace dxvk {
|
||||
VkShaderStageFlags stages,
|
||||
uint32_t slot,
|
||||
DxvkBufferSlice&& buffer) {
|
||||
bool needsUpdate = !m_rc[slot].bufferSlice.matchesBuffer(buffer);
|
||||
|
||||
if (likely(needsUpdate))
|
||||
m_rcTracked.clr(slot);
|
||||
|
||||
m_rc[slot].bufferSlice = std::move(buffer);
|
||||
|
||||
m_descriptorState.dirtyBuffers(stages);
|
||||
@ -261,7 +253,6 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
m_rc[slot].imageView = std::move(view);
|
||||
m_rcTracked.clr(slot);
|
||||
|
||||
m_descriptorState.dirtyViews(stages);
|
||||
}
|
||||
@ -288,8 +279,6 @@ namespace dxvk {
|
||||
m_rc[slot].bufferView = nullptr;
|
||||
}
|
||||
|
||||
m_rcTracked.clr(slot);
|
||||
|
||||
m_descriptorState.dirtyViews(stages);
|
||||
}
|
||||
|
||||
@ -307,7 +296,6 @@ namespace dxvk {
|
||||
uint32_t slot,
|
||||
Rc<DxvkSampler>&& sampler) {
|
||||
m_rc[slot].sampler = std::move(sampler);
|
||||
m_rcTracked.clr(slot);
|
||||
|
||||
m_descriptorState.dirtyViews(stages);
|
||||
}
|
||||
@ -371,9 +359,6 @@ namespace dxvk {
|
||||
uint32_t binding,
|
||||
DxvkBufferSlice&& buffer,
|
||||
uint32_t stride) {
|
||||
if (!m_state.vi.vertexBuffers[binding].matchesBuffer(buffer))
|
||||
m_vbTracked.clr(binding);
|
||||
|
||||
m_state.vi.vertexBuffers[binding] = std::move(buffer);
|
||||
m_state.vi.vertexStrides[binding] = stride;
|
||||
m_flags.set(DxvkContextFlag::GpDirtyVertexBuffers);
|
||||
@ -1413,9 +1398,6 @@ namespace dxvk {
|
||||
|
||||
DxvkRenderTargetLayouts m_rtLayouts = { };
|
||||
|
||||
DxvkBindingSet<MaxNumVertexBindings + 1> m_vbTracked;
|
||||
DxvkBindingSet<MaxNumResourceSlots> m_rcTracked;
|
||||
|
||||
std::vector<DxvkDeferredClear> m_deferredClears;
|
||||
|
||||
std::vector<VkWriteDescriptorSet> m_descriptorWrites;
|
||||
|
@ -542,10 +542,18 @@ namespace dxvk {
|
||||
* command list and optimize certain transfer operations.
|
||||
* \param [in] trackingId Tracking ID
|
||||
* \param [in] access Tracked access
|
||||
* \returns \c true if the tracking ID was updated, or \c false
|
||||
* if the resource was already tracked with the same ID.
|
||||
*/
|
||||
void trackId(uint64_t trackingId, DxvkAccess access) {
|
||||
bool trackId(uint64_t trackingId, DxvkAccess access) {
|
||||
// Encode write access in the least significant bit
|
||||
m_trackId = std::max(m_trackId, (trackingId << 1u) + uint64_t(access == DxvkAccess::Write));
|
||||
uint64_t trackId = (trackingId << 1u) + uint64_t(access == DxvkAccess::Write);
|
||||
|
||||
if (trackId <= m_trackId)
|
||||
return false;
|
||||
|
||||
m_trackId = trackId;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -623,15 +631,13 @@ namespace dxvk {
|
||||
public:
|
||||
|
||||
template<typename T>
|
||||
explicit DxvkResourceRef(Rc<T>&& object, DxvkAccess access, uint64_t trackingId)
|
||||
explicit DxvkResourceRef(Rc<T>&& object, DxvkAccess access)
|
||||
: m_ptr(reinterpret_cast<uintptr_t>(static_cast<DxvkPagedResource*>(object.ptr())) | uintptr_t(access)) {
|
||||
object->trackId(trackingId, access);
|
||||
object.unsafeExtract()->convertRef(DxvkAccess::None, access);
|
||||
}
|
||||
|
||||
explicit DxvkResourceRef(DxvkPagedResource* object, DxvkAccess access, uint64_t trackingId)
|
||||
explicit DxvkResourceRef(DxvkPagedResource* object, DxvkAccess access)
|
||||
: m_ptr(reinterpret_cast<uintptr_t>(object) | uintptr_t(access)) {
|
||||
object->trackId(trackingId, access);
|
||||
object->acquire(access);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user