mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-01 08:52:11 +01:00
[dxvk] Add helper for out-of-order resource transfers
This commit is contained in:
parent
f0054e7e65
commit
c8ab88e8f5
@ -7140,6 +7140,81 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
bool DxvkContext::prepareOutOfOrderTransfer(
|
||||
const Rc<DxvkBuffer>& buffer,
|
||||
VkDeviceSize offset,
|
||||
VkDeviceSize size,
|
||||
DxvkAccess access) {
|
||||
// If the resource hasn't been used yet or both uses are reads,
|
||||
// we can use this buffer in the init command buffer
|
||||
if (!buffer->isTracked(m_trackingId, access))
|
||||
return true;
|
||||
|
||||
// Otherwise, our only option is to discard. We can only do that if
|
||||
// we're writing the full buffer. Therefore, the resource being read
|
||||
// should always be checked first to avoid unnecessary discards.
|
||||
if (access != DxvkAccess::Write || size < buffer->info().size || offset)
|
||||
return false;
|
||||
|
||||
// Check if the buffer can actually be discarded at all.
|
||||
if (!buffer->canRelocate())
|
||||
return false;
|
||||
|
||||
// Ignore large buffers to keep memory overhead in check. Use a higher
|
||||
// threshold when a render pass is active to avoid interrupting it.
|
||||
VkDeviceSize threshold = !m_flags.test(DxvkContextFlag::GpRenderPassBound)
|
||||
? MaxDiscardSizeInRp
|
||||
: MaxDiscardSize;
|
||||
|
||||
if (size > threshold)
|
||||
return false;
|
||||
|
||||
// If the buffer is used for transform feedback in any way, we have to stop
|
||||
// the render pass anyway, but we can at least avoid an extra barrier.
|
||||
if (unlikely(m_flags.test(DxvkContextFlag::GpXfbActive))) {
|
||||
VkBufferUsageFlags xfbUsage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT
|
||||
| VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT;
|
||||
|
||||
if (buffer->info().usage & xfbUsage)
|
||||
this->spillRenderPass(true);
|
||||
}
|
||||
|
||||
// Actually allocate and assign new backing storage
|
||||
this->invalidateBuffer(buffer, buffer->allocateStorage());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool DxvkContext::prepareOutOfOrderTransfer(
|
||||
const Rc<DxvkBufferView>& bufferView,
|
||||
VkDeviceSize offset,
|
||||
VkDeviceSize size,
|
||||
DxvkAccess access) {
|
||||
if (bufferView->info().format) {
|
||||
offset *= bufferView->formatInfo()->elementSize;
|
||||
size *= bufferView->formatInfo()->elementSize;
|
||||
}
|
||||
|
||||
return prepareOutOfOrderTransfer(bufferView->buffer(),
|
||||
offset + bufferView->info().offset, size, access);
|
||||
}
|
||||
|
||||
|
||||
bool DxvkContext::prepareOutOfOrderTransfer(
|
||||
const Rc<DxvkImage>& image,
|
||||
DxvkAccess access) {
|
||||
// If the image can be used for rendering, some or all subresources
|
||||
// might be in a non-default layout, and copies to or from render
|
||||
// targets typically depend on rendering operations anyway. Skip.
|
||||
if (image->info().usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT))
|
||||
return false;
|
||||
|
||||
// If the image hasn't been used yet or all uses are
|
||||
// reads, we can use it in the init command buffer
|
||||
return !image->isTracked(m_trackingId, access);
|
||||
}
|
||||
|
||||
|
||||
bool DxvkContext::formatsAreCopyCompatible(
|
||||
VkFormat imageFormat,
|
||||
VkFormat bufferFormat) {
|
||||
|
@ -29,7 +29,8 @@ namespace dxvk {
|
||||
* recorded.
|
||||
*/
|
||||
class DxvkContext : public RcObject {
|
||||
|
||||
constexpr static VkDeviceSize MaxDiscardSizeInRp = 256u << 10u;
|
||||
constexpr static VkDeviceSize MaxDiscardSize = 16u << 10u;
|
||||
public:
|
||||
|
||||
DxvkContext(const Rc<DxvkDevice>& device);
|
||||
@ -1903,6 +1904,22 @@ namespace dxvk {
|
||||
DxvkBarrierBatch& getBarrierBatch(
|
||||
DxvkCmdBuffer cmdBuffer);
|
||||
|
||||
bool prepareOutOfOrderTransfer(
|
||||
const Rc<DxvkBuffer>& buffer,
|
||||
VkDeviceSize offset,
|
||||
VkDeviceSize size,
|
||||
DxvkAccess access);
|
||||
|
||||
bool prepareOutOfOrderTransfer(
|
||||
const Rc<DxvkBufferView>& bufferView,
|
||||
VkDeviceSize offset,
|
||||
VkDeviceSize size,
|
||||
DxvkAccess access);
|
||||
|
||||
bool prepareOutOfOrderTransfer(
|
||||
const Rc<DxvkImage>& image,
|
||||
DxvkAccess access);
|
||||
|
||||
template<typename Pred>
|
||||
bool checkResourceBarrier(
|
||||
const Pred& pred,
|
||||
|
Loading…
x
Reference in New Issue
Block a user