mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-27 22:54:16 +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:
parent
e4e82007b1
commit
f501ebce97
src/dxvk
@ -434,7 +434,7 @@ namespace dxvk {
|
|||||||
? m_buffer->mapPtr(m_offset + offset)
|
? m_buffer->mapPtr(m_offset + offset)
|
||||||
: nullptr;
|
: nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Checks whether two slices are equal
|
* \brief Checks whether two slices are equal
|
||||||
*
|
*
|
||||||
@ -448,6 +448,45 @@ namespace dxvk {
|
|||||||
&& this->m_offset == other.m_offset
|
&& this->m_offset == other.m_offset
|
||||||
&& this->m_length == other.m_length;
|
&& 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:
|
private:
|
||||||
|
|
||||||
|
@ -158,12 +158,20 @@ namespace dxvk {
|
|||||||
void DxvkContext::bindResourceBuffer(
|
void DxvkContext::bindResourceBuffer(
|
||||||
uint32_t slot,
|
uint32_t slot,
|
||||||
const DxvkBufferSlice& buffer) {
|
const DxvkBufferSlice& buffer) {
|
||||||
if (!m_rc[slot].bufferSlice.matches(buffer)) {
|
if (!m_rc[slot].bufferSlice.matchesBuffer(buffer)) {
|
||||||
m_rc[slot].bufferSlice = buffer;
|
m_rc[slot].bufferSlice = buffer;
|
||||||
|
|
||||||
m_flags.set(
|
m_flags.set(
|
||||||
DxvkContextFlag::CpDirtyResources,
|
DxvkContextFlag::CpDirtyResources,
|
||||||
DxvkContextFlag::GpDirtyResources);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user