1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-31 05:52:11 +01:00

[dxvk] Avoid redundant descriptor set updates when binding buffers

Reduces unnecessary overhead when binding a different range of the
same buffer, e.g. through D3D11 VSSetConstantBuffers1.
This commit is contained in:
Philip Rebohle 2019-06-03 20:14:27 +02:00
parent e4e82007b1
commit f501ebce97
2 changed files with 49 additions and 2 deletions

View File

@ -434,7 +434,7 @@ namespace dxvk {
? m_buffer->mapPtr(m_offset + offset)
: nullptr;
}
/**
* \brief Checks whether two slices are equal
*
@ -448,6 +448,45 @@ namespace dxvk {
&& this->m_offset == other.m_offset
&& this->m_length == other.m_length;
}
/**
* \brief Checks whether two slices are from the same buffer
*
* This returns \c true if the two slices are taken
* from the same buffer, but may have different ranges.
* \param [in] other The slice to compare to
* \returns \c true if the buffer objects are the same
*/
bool matchesBuffer(const DxvkBufferSlice& other) const {
return this->m_buffer == other.m_buffer;
}
/**
* \brief Checks whether two slices have the same range
*
* This returns \c true if the two slices have the same
* offset and size, even if the buffers are different.
* May be useful if the buffers are know to be the same.
* \param [in] other The slice to compare to
* \returns \c true if the buffer objects are the same
*/
bool matchesRange(const DxvkBufferSlice& other) const {
return this->m_offset == other.m_offset
&& this->m_length == other.m_length;
}
/**
* \brief Changes offset and size, but not the buffer
*
* Slightly faster alternative to overriding the full
* buffer slice object in case only the range changes.
* \param [in] offset New slice offset
* \param [in] length New slice length
*/
void updateRange(VkDeviceSize offset, VkDeviceSize length) {
m_offset = offset;
m_length = length;
}
private:

View File

@ -158,12 +158,20 @@ namespace dxvk {
void DxvkContext::bindResourceBuffer(
uint32_t slot,
const DxvkBufferSlice& buffer) {
if (!m_rc[slot].bufferSlice.matches(buffer)) {
if (!m_rc[slot].bufferSlice.matchesBuffer(buffer)) {
m_rc[slot].bufferSlice = buffer;
m_flags.set(
DxvkContextFlag::CpDirtyResources,
DxvkContextFlag::GpDirtyResources);
} else if (!m_rc[slot].bufferSlice.matchesRange(buffer)) {
m_rc[slot].bufferSlice.updateRange(
buffer.offset(),
buffer.length());
m_flags.set(
DxvkContextFlag::CpDirtyDescriptorOffsets,
DxvkContextFlag::GpDirtyDescriptorOffsets);
}
}