mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-13 16:08:50 +01:00
[dxvk] Simplify barrier image and buffer slice implementations
Pre-process the given ranges so that compare and merge operations become both simpler and faster.
This commit is contained in:
parent
8aae9c85bb
commit
4c7da80c14
@ -20,10 +20,12 @@ namespace dxvk {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
DxvkBarrierBufferSlice()
|
DxvkBarrierBufferSlice()
|
||||||
: m_offset(0), m_length(0), m_access(0) { }
|
: m_loAddr(0), m_hiAddr(0), m_access(0) { }
|
||||||
|
|
||||||
DxvkBarrierBufferSlice(VkDeviceSize offset, VkDeviceSize length, DxvkAccessFlags access)
|
DxvkBarrierBufferSlice(VkDeviceSize offset, VkDeviceSize length, DxvkAccessFlags access)
|
||||||
: m_offset(offset), m_length(length), m_access(access) { }
|
: m_loAddr(offset),
|
||||||
|
m_hiAddr(offset + length),
|
||||||
|
m_access(access) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Checks whether two slices overlap
|
* \brief Checks whether two slices overlap
|
||||||
@ -32,8 +34,8 @@ namespace dxvk {
|
|||||||
* \returns \c true if the two slices overlap
|
* \returns \c true if the two slices overlap
|
||||||
*/
|
*/
|
||||||
bool overlaps(const DxvkBarrierBufferSlice& slice) const {
|
bool overlaps(const DxvkBarrierBufferSlice& slice) const {
|
||||||
return m_offset + m_length > slice.m_offset
|
return m_hiAddr > slice.m_loAddr
|
||||||
&& m_offset < slice.m_offset + slice.m_length;
|
&& m_loAddr < slice.m_hiAddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,11 +60,11 @@ namespace dxvk {
|
|||||||
*/
|
*/
|
||||||
bool canMerge(const DxvkBarrierBufferSlice& slice) const {
|
bool canMerge(const DxvkBarrierBufferSlice& slice) const {
|
||||||
if (m_access == slice.m_access) {
|
if (m_access == slice.m_access) {
|
||||||
return m_offset + m_length >= slice.m_offset
|
return m_hiAddr >= slice.m_loAddr
|
||||||
&& m_offset <= slice.m_offset + slice.m_length;
|
&& m_loAddr <= slice.m_hiAddr;
|
||||||
} else {
|
} else {
|
||||||
return m_offset == slice.m_offset
|
return m_loAddr == slice.m_loAddr
|
||||||
&& m_length == slice.m_length;
|
&& m_hiAddr == slice.m_hiAddr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,10 +77,8 @@ namespace dxvk {
|
|||||||
* \param [in] slice The slice to merge
|
* \param [in] slice The slice to merge
|
||||||
*/
|
*/
|
||||||
void merge(const DxvkBarrierBufferSlice& slice) {
|
void merge(const DxvkBarrierBufferSlice& slice) {
|
||||||
VkDeviceSize end = std::max(m_offset + m_length, slice.m_offset + slice.m_length);
|
m_loAddr = std::min(m_loAddr, slice.m_loAddr);
|
||||||
|
m_hiAddr = std::max(m_hiAddr, slice.m_hiAddr);
|
||||||
m_offset = std::min(m_offset, slice.m_offset);
|
|
||||||
m_length = end - m_offset;
|
|
||||||
m_access.set(slice.m_access);
|
m_access.set(slice.m_access);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,13 +87,13 @@ namespace dxvk {
|
|||||||
* \returns Access flags
|
* \returns Access flags
|
||||||
*/
|
*/
|
||||||
DxvkAccessFlags getAccess() const {
|
DxvkAccessFlags getAccess() const {
|
||||||
return m_access;
|
return DxvkAccessFlags(m_access);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
VkDeviceSize m_offset;
|
VkDeviceSize m_loAddr;
|
||||||
VkDeviceSize m_length;
|
VkDeviceSize m_hiAddr;
|
||||||
DxvkAccessFlags m_access;
|
DxvkAccessFlags m_access;
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -110,10 +110,20 @@ namespace dxvk {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
DxvkBarrierImageSlice()
|
DxvkBarrierImageSlice()
|
||||||
: m_range(VkImageSubresourceRange()), m_access(0) { }
|
: m_aspects(0),
|
||||||
|
m_minLayer(0),
|
||||||
|
m_maxLayer(0),
|
||||||
|
m_minLevel(0),
|
||||||
|
m_maxLevel(0),
|
||||||
|
m_access(0) { }
|
||||||
|
|
||||||
DxvkBarrierImageSlice(VkImageSubresourceRange range, DxvkAccessFlags access)
|
DxvkBarrierImageSlice(VkImageSubresourceRange range, DxvkAccessFlags access)
|
||||||
: m_range(range), m_access(access) { }
|
: m_aspects(range.aspectMask),
|
||||||
|
m_minLayer(range.baseArrayLayer),
|
||||||
|
m_maxLayer(range.baseArrayLayer + range.layerCount),
|
||||||
|
m_minLevel(range.baseMipLevel),
|
||||||
|
m_maxLevel(range.baseMipLevel + range.levelCount),
|
||||||
|
m_access(access) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Checks whether two slices overlap
|
* \brief Checks whether two slices overlap
|
||||||
@ -122,11 +132,11 @@ namespace dxvk {
|
|||||||
* \returns \c true if the two slices overlap
|
* \returns \c true if the two slices overlap
|
||||||
*/
|
*/
|
||||||
bool overlaps(const DxvkBarrierImageSlice& slice) const {
|
bool overlaps(const DxvkBarrierImageSlice& slice) const {
|
||||||
return (m_range.aspectMask & slice.m_range.aspectMask)
|
return (m_aspects & slice.m_aspects)
|
||||||
&& (m_range.baseArrayLayer < slice.m_range.baseArrayLayer + slice.m_range.layerCount)
|
&& (m_minLayer < slice.m_maxLayer)
|
||||||
&& (m_range.baseArrayLayer + m_range.layerCount > slice.m_range.baseArrayLayer)
|
&& (m_maxLayer > slice.m_minLayer)
|
||||||
&& (m_range.baseMipLevel < slice.m_range.baseMipLevel + slice.m_range.levelCount)
|
&& (m_minLevel < slice.m_maxLevel)
|
||||||
&& (m_range.baseMipLevel + m_range.levelCount > slice.m_range.baseMipLevel);
|
&& (m_maxLevel > slice.m_minLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -143,18 +153,30 @@ namespace dxvk {
|
|||||||
/**
|
/**
|
||||||
* \brief Checks whether two slices can be merged
|
* \brief Checks whether two slices can be merged
|
||||||
*
|
*
|
||||||
* This is a simplified implementation that does not check for
|
* This is a simplified implementation that does only
|
||||||
* adjacent or overlapping layers or levels, and instead only
|
* checks for adjacent subresources in one dimension.
|
||||||
* returns \c true if both slices contain the same mip levels
|
|
||||||
* and array layers. Access flags and image aspects may differ.
|
|
||||||
* \param [in] slice The other image slice to check
|
* \param [in] slice The other image slice to check
|
||||||
* \returns \c true if the slices can be merged.
|
* \returns \c true if the slices can be merged.
|
||||||
*/
|
*/
|
||||||
bool canMerge(const DxvkBarrierImageSlice& slice) const {
|
bool canMerge(const DxvkBarrierImageSlice& slice) const {
|
||||||
return m_range.baseMipLevel == slice.m_range.baseMipLevel
|
bool sameLayers = m_minLayer == slice.m_minLayer
|
||||||
&& m_range.levelCount == slice.m_range.levelCount
|
&& m_maxLayer == slice.m_maxLayer;
|
||||||
&& m_range.baseArrayLayer == slice.m_range.baseArrayLayer
|
bool sameLevels = m_minLevel == slice.m_minLevel
|
||||||
&& m_range.layerCount == slice.m_range.layerCount;
|
&& m_maxLevel == slice.m_maxLevel;
|
||||||
|
|
||||||
|
if (sameLayers == sameLevels)
|
||||||
|
return sameLayers;
|
||||||
|
|
||||||
|
if (m_access != slice.m_access)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (sameLayers) {
|
||||||
|
return m_maxLevel >= slice.m_minLevel
|
||||||
|
&& m_minLevel <= slice.m_maxLevel;
|
||||||
|
} else /* if (sameLevels) */ {
|
||||||
|
return m_maxLayer >= slice.m_minLayer
|
||||||
|
&& m_minLayer <= slice.m_maxLayer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -166,15 +188,11 @@ namespace dxvk {
|
|||||||
* \param [in] slice The slice to merge
|
* \param [in] slice The slice to merge
|
||||||
*/
|
*/
|
||||||
void merge(const DxvkBarrierImageSlice& slice) {
|
void merge(const DxvkBarrierImageSlice& slice) {
|
||||||
uint32_t maxMipLevel = std::max(m_range.baseMipLevel + m_range.levelCount,
|
m_aspects |= slice.m_aspects;
|
||||||
slice.m_range.baseMipLevel + slice.m_range.levelCount);
|
m_minLayer = std::min(m_minLayer, slice.m_minLayer);
|
||||||
uint32_t maxArrayLayer = std::max(m_range.baseArrayLayer + m_range.layerCount,
|
m_maxLayer = std::max(m_maxLayer, slice.m_maxLayer);
|
||||||
slice.m_range.baseArrayLayer + slice.m_range.layerCount);
|
m_minLevel = std::min(m_minLevel, slice.m_minLevel);
|
||||||
m_range.aspectMask |= slice.m_range.aspectMask;
|
m_maxLevel = std::max(m_maxLevel, slice.m_maxLevel);
|
||||||
m_range.baseMipLevel = std::min(m_range.baseMipLevel, slice.m_range.baseMipLevel);
|
|
||||||
m_range.levelCount = maxMipLevel - m_range.baseMipLevel;
|
|
||||||
m_range.baseArrayLayer = std::min(m_range.baseMipLevel, slice.m_range.baseArrayLayer);
|
|
||||||
m_range.layerCount = maxArrayLayer - m_range.baseArrayLayer;
|
|
||||||
m_access.set(slice.m_access);
|
m_access.set(slice.m_access);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,7 +206,11 @@ namespace dxvk {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
VkImageSubresourceRange m_range;
|
VkImageAspectFlags m_aspects;
|
||||||
|
uint32_t m_minLayer;
|
||||||
|
uint32_t m_maxLayer;
|
||||||
|
uint32_t m_minLevel;
|
||||||
|
uint32_t m_maxLevel;
|
||||||
DxvkAccessFlags m_access;
|
DxvkAccessFlags m_access;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user