mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-06 20:58:37 +01:00
2082 lines
69 KiB
C++
2082 lines
69 KiB
C++
#pragma once
|
|
|
|
#include "dxvk_barrier.h"
|
|
#include "dxvk_bind_mask.h"
|
|
#include "dxvk_cmdlist.h"
|
|
#include "dxvk_context_state.h"
|
|
#include "dxvk_latency.h"
|
|
#include "dxvk_objects.h"
|
|
#include "dxvk_queue.h"
|
|
#include "dxvk_util.h"
|
|
|
|
namespace dxvk {
|
|
|
|
/**
|
|
* \brief Context-provided objects
|
|
*
|
|
* Useful when submitting raw Vulkan commands to a command list.
|
|
*/
|
|
struct DxvkContextObjects {
|
|
Rc<DxvkCommandList> cmd;
|
|
Rc<DxvkDescriptorPool> descriptorPool;
|
|
};
|
|
|
|
|
|
/**
|
|
* \brief DXVK context
|
|
*
|
|
* Tracks pipeline state and records command lists.
|
|
* This is where the actual rendering commands are
|
|
* recorded.
|
|
*/
|
|
class DxvkContext : public RcObject {
|
|
constexpr static VkDeviceSize MaxDiscardSizeInRp = 256u << 10u;
|
|
constexpr static VkDeviceSize MaxDiscardSize = 16u << 10u;
|
|
public:
|
|
|
|
DxvkContext(const Rc<DxvkDevice>& device);
|
|
~DxvkContext();
|
|
|
|
/**
|
|
* \brief Begins command buffer recording
|
|
*
|
|
* Begins recording a command list. This does
|
|
* not alter any context state other than the
|
|
* active command list.
|
|
* \param [in] cmdList Target command list
|
|
*/
|
|
void beginRecording(
|
|
const Rc<DxvkCommandList>& cmdList);
|
|
|
|
/**
|
|
* \brief Ends command buffer recording
|
|
*
|
|
* Finishes recording the active command list.
|
|
* The command list can then be submitted to
|
|
* the device.
|
|
*
|
|
* This will not change any context state
|
|
* other than the active command list.
|
|
* \returns Active command list
|
|
*/
|
|
Rc<DxvkCommandList> endRecording();
|
|
|
|
/**
|
|
* \brief Ends frame
|
|
*
|
|
* Must be called once per frame before the
|
|
* final call to \ref endRecording.
|
|
*/
|
|
void endFrame();
|
|
|
|
/**
|
|
* \brief Begins latency tracking
|
|
*
|
|
* Notifies the beginning of a frame on the CS timeline
|
|
* an ensures that subsequent submissions are associated
|
|
* with the correct frame ID. Only one tracker can be
|
|
* active at any given time.
|
|
* \param [in] tracker Latency tracker object
|
|
* \param [in] frameId Current frame ID
|
|
*/
|
|
void beginLatencyTracking(
|
|
const Rc<DxvkLatencyTracker>& tracker,
|
|
uint64_t frameId);
|
|
|
|
/**
|
|
* \brief Ends latency tracking
|
|
*
|
|
* Notifies the end of the frame. Ignored if the
|
|
* tracker is not currently active.
|
|
* \param [in] tracker Latency tracker object
|
|
*/
|
|
void endLatencyTracking(
|
|
const Rc<DxvkLatencyTracker>& tracker);
|
|
|
|
/**
|
|
* \brief Flushes command buffer
|
|
*
|
|
* Transparently submits the current command
|
|
* buffer and allocates a new one.
|
|
* \param [out] status Submission feedback
|
|
*/
|
|
void flushCommandList(DxvkSubmitStatus* status);
|
|
|
|
/**
|
|
* \brief Synchronizes command list with WSI
|
|
*
|
|
* The next submission can be used to render
|
|
* to the swap chain image and present after.
|
|
*/
|
|
void synchronizeWsi(PresenterSync sync) {
|
|
m_cmd->setWsiSemaphores(sync);
|
|
}
|
|
|
|
/**
|
|
* \brief Begins external rendering
|
|
*
|
|
* Invalidates all state and provides the caller
|
|
* with the objects necessary to start drawing.
|
|
*/
|
|
DxvkContextObjects beginExternalRendering();
|
|
|
|
/**
|
|
* \brief Begins generating query data
|
|
* \param [in] query The query to end
|
|
*/
|
|
void beginQuery(
|
|
const Rc<DxvkQuery>& query);
|
|
|
|
/**
|
|
* \brief Ends generating query data
|
|
* \param [in] query The query to end
|
|
*/
|
|
void endQuery(
|
|
const Rc<DxvkQuery>& query);
|
|
|
|
/**
|
|
* \brief Sets render targets
|
|
*
|
|
* Creates a framebuffer on the fly if necessary
|
|
* and binds it using \c bindFramebuffer.
|
|
* \param [in] targets Render targets to bind
|
|
*/
|
|
void bindRenderTargets(
|
|
DxvkRenderTargets&& targets,
|
|
VkImageAspectFlags feedbackLoop) {
|
|
// Set up default render pass ops and normalize layouts
|
|
m_state.om.renderTargets = std::move(targets);
|
|
|
|
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
|
auto& rt = m_state.om.renderTargets.color[i];
|
|
|
|
if (rt.view)
|
|
rt.layout = rt.view->pickLayout(rt.layout);
|
|
}
|
|
|
|
if (unlikely(m_state.gp.state.om.feedbackLoop() != feedbackLoop)) {
|
|
m_state.gp.state.om.setFeedbackLoop(feedbackLoop);
|
|
m_flags.set(DxvkContextFlag::GpDirtyPipelineState);
|
|
}
|
|
|
|
this->resetRenderPassOps(
|
|
m_state.om.renderTargets,
|
|
m_state.om.renderPassOps);
|
|
|
|
if (!m_state.om.framebufferInfo.hasTargets(m_state.om.renderTargets)) {
|
|
// Create a new framebuffer object next
|
|
// time we start rendering something
|
|
m_flags.set(DxvkContextFlag::GpDirtyFramebuffer);
|
|
} else {
|
|
// Don't redundantly spill the render pass if
|
|
// the same render targets are bound again
|
|
m_flags.clr(DxvkContextFlag::GpDirtyFramebuffer);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Binds indirect argument buffer
|
|
*
|
|
* Sets the buffers that are going to be used
|
|
* for indirect draw and dispatch operations.
|
|
* \param [in] argBuffer New argument buffer
|
|
* \param [in] cntBuffer New count buffer
|
|
*/
|
|
void bindDrawBuffers(
|
|
DxvkBufferSlice&& argBuffer,
|
|
DxvkBufferSlice&& cntBuffer) {
|
|
m_state.id.argBuffer = std::move(argBuffer);
|
|
m_state.id.cntBuffer = std::move(cntBuffer);
|
|
|
|
m_flags.set(DxvkContextFlag::DirtyDrawBuffer);
|
|
}
|
|
|
|
/**
|
|
* \brief Binds index buffer
|
|
*
|
|
* The index buffer will be used when
|
|
* issuing \c drawIndexed commands.
|
|
* \param [in] buffer New index buffer
|
|
* \param [in] indexType Index type
|
|
*/
|
|
void bindIndexBuffer(
|
|
DxvkBufferSlice&& buffer,
|
|
VkIndexType indexType) {
|
|
m_state.vi.indexBuffer = std::move(buffer);
|
|
m_state.vi.indexType = indexType;
|
|
|
|
m_flags.set(DxvkContextFlag::GpDirtyIndexBuffer);
|
|
}
|
|
|
|
/**
|
|
* \brief Binds index buffer range
|
|
*
|
|
* Canges the offset and size of the bound index buffer.
|
|
* \param [in] offset Index buffer offset
|
|
* \param [in] length Index buffer size
|
|
* \param [in] indexType Index type
|
|
*/
|
|
void bindIndexBufferRange(
|
|
VkDeviceSize offset,
|
|
VkDeviceSize length,
|
|
VkIndexType indexType) {
|
|
m_state.vi.indexBuffer.setRange(offset, length);
|
|
m_state.vi.indexType = indexType;
|
|
|
|
m_flags.set(DxvkContextFlag::GpDirtyIndexBuffer);
|
|
}
|
|
|
|
/**
|
|
* \brief Binds buffer to the UBO set
|
|
*
|
|
* Can be used for uniform and storage buffers bound that
|
|
* are used within the UBO descriptor set. Storage buffers
|
|
* within the view set must be bound via a view.
|
|
* \param [in] stages Shader stages that access the binding
|
|
* \param [in] slot Resource binding slot
|
|
* \param [in] buffer Buffer to bind
|
|
*/
|
|
void bindUniformBuffer(
|
|
VkShaderStageFlags stages,
|
|
uint32_t slot,
|
|
DxvkBufferSlice&& buffer) {
|
|
m_rc[slot].bufferSlice = std::move(buffer);
|
|
|
|
m_descriptorState.dirtyBuffers(stages);
|
|
}
|
|
|
|
/**
|
|
* \brief Changes bound range of a uniform buffer
|
|
*
|
|
* Can be used to quickly bind a new sub-range of
|
|
* a buffer rather than re-binding the entire buffer.
|
|
*/
|
|
void bindUniformBufferRange(
|
|
VkShaderStageFlags stages,
|
|
uint32_t slot,
|
|
VkDeviceSize offset,
|
|
VkDeviceSize length) {
|
|
m_rc[slot].bufferSlice.setRange(offset, length);
|
|
|
|
m_descriptorState.dirtyBuffers(stages);
|
|
}
|
|
|
|
/**
|
|
* \brief Binds image view
|
|
*
|
|
* \param [in] stages Shader stages that access the binding
|
|
* \param [in] slot Resource binding slot
|
|
* \param [in] view Image view to bind
|
|
*/
|
|
void bindResourceImageView(
|
|
VkShaderStageFlags stages,
|
|
uint32_t slot,
|
|
Rc<DxvkImageView>&& view) {
|
|
if (m_rc[slot].bufferView != nullptr) {
|
|
m_rc[slot].bufferSlice = DxvkBufferSlice();
|
|
m_rc[slot].bufferView = nullptr;
|
|
}
|
|
|
|
m_rc[slot].imageView = std::move(view);
|
|
|
|
m_descriptorState.dirtyViews(stages);
|
|
}
|
|
|
|
/**
|
|
* \brief Binds buffer view
|
|
*
|
|
* \param [in] stages Shader stages that access the binding
|
|
* \param [in] slot Resource binding slot
|
|
* \param [in] view Buffer view to bind
|
|
*/
|
|
void bindResourceBufferView(
|
|
VkShaderStageFlags stages,
|
|
uint32_t slot,
|
|
Rc<DxvkBufferView>&& view) {
|
|
if (m_rc[slot].imageView != nullptr)
|
|
m_rc[slot].imageView = nullptr;
|
|
|
|
if (view != nullptr) {
|
|
m_rc[slot].bufferSlice = DxvkBufferSlice(view);
|
|
m_rc[slot].bufferView = std::move(view);
|
|
} else {
|
|
m_rc[slot].bufferSlice = DxvkBufferSlice();
|
|
m_rc[slot].bufferView = nullptr;
|
|
}
|
|
|
|
m_descriptorState.dirtyViews(stages);
|
|
}
|
|
|
|
/**
|
|
* \brief Binds image sampler
|
|
*
|
|
* Binds a sampler that can be used together with
|
|
* an image in order to read from a texture.
|
|
* \param [in] stages Shader stages that access the binding
|
|
* \param [in] slot Resource binding slot
|
|
* \param [in] sampler Sampler view to bind
|
|
*/
|
|
void bindResourceSampler(
|
|
VkShaderStageFlags stages,
|
|
uint32_t slot,
|
|
Rc<DxvkSampler>&& sampler) {
|
|
m_rc[slot].sampler = std::move(sampler);
|
|
|
|
m_descriptorState.dirtyViews(stages);
|
|
}
|
|
|
|
/**
|
|
* \brief Binds a shader to a given state
|
|
*
|
|
* \param [in] stage Target shader stage
|
|
* \param [in] shader The shader to bind
|
|
*/
|
|
template<VkShaderStageFlagBits Stage>
|
|
void bindShader(
|
|
Rc<DxvkShader>&& shader) {
|
|
switch (Stage) {
|
|
case VK_SHADER_STAGE_VERTEX_BIT:
|
|
m_state.gp.shaders.vs = std::move(shader);
|
|
break;
|
|
|
|
case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
|
|
m_state.gp.shaders.tcs = std::move(shader);
|
|
break;
|
|
|
|
case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
|
|
m_state.gp.shaders.tes = std::move(shader);
|
|
break;
|
|
|
|
case VK_SHADER_STAGE_GEOMETRY_BIT:
|
|
m_state.gp.shaders.gs = std::move(shader);
|
|
break;
|
|
|
|
case VK_SHADER_STAGE_FRAGMENT_BIT:
|
|
m_state.gp.shaders.fs = std::move(shader);
|
|
break;
|
|
|
|
case VK_SHADER_STAGE_COMPUTE_BIT:
|
|
m_state.cp.shaders.cs = std::move(shader);
|
|
break;
|
|
|
|
default:
|
|
return;
|
|
}
|
|
|
|
if (Stage == VK_SHADER_STAGE_COMPUTE_BIT) {
|
|
m_flags.set(
|
|
DxvkContextFlag::CpDirtyPipelineState);
|
|
} else {
|
|
m_flags.set(
|
|
DxvkContextFlag::GpDirtyPipeline,
|
|
DxvkContextFlag::GpDirtyPipelineState);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Binds vertex buffer
|
|
*
|
|
* \param [in] binding Vertex buffer binding
|
|
* \param [in] buffer New vertex buffer
|
|
* \param [in] stride Stride between vertices
|
|
*/
|
|
void bindVertexBuffer(
|
|
uint32_t binding,
|
|
DxvkBufferSlice&& buffer,
|
|
uint32_t stride) {
|
|
m_state.vi.vertexBuffers[binding] = std::move(buffer);
|
|
m_state.vi.vertexStrides[binding] = stride;
|
|
m_flags.set(DxvkContextFlag::GpDirtyVertexBuffers);
|
|
}
|
|
|
|
/**
|
|
* \brief Binds vertex buffer range
|
|
*
|
|
* Only changes offsets of a bound vertex buffer.
|
|
* \param [in] binding Vertex buffer binding
|
|
* \param [in] offset Vertex buffer offset
|
|
* \param [in] length Vertex buffer size
|
|
* \param [in] stride Stride between vertices
|
|
*/
|
|
void bindVertexBufferRange(
|
|
uint32_t binding,
|
|
VkDeviceSize offset,
|
|
VkDeviceSize length,
|
|
uint32_t stride) {
|
|
m_state.vi.vertexBuffers[binding].setRange(offset, length);
|
|
m_state.vi.vertexStrides[binding] = stride;
|
|
m_flags.set(DxvkContextFlag::GpDirtyVertexBuffers);
|
|
}
|
|
|
|
/**
|
|
* \brief Binds transform feedback buffer
|
|
*
|
|
* \param [in] binding Xfb buffer binding
|
|
* \param [in] buffer The buffer to bind
|
|
* \param [in] counter Xfb counter buffer
|
|
*/
|
|
void bindXfbBuffer(
|
|
uint32_t binding,
|
|
DxvkBufferSlice&& buffer,
|
|
DxvkBufferSlice&& counter) {
|
|
m_state.xfb.buffers [binding] = std::move(buffer);
|
|
m_state.xfb.counters[binding] = std::move(counter);
|
|
|
|
m_flags.set(DxvkContextFlag::GpDirtyXfbBuffers);
|
|
}
|
|
|
|
/**
|
|
* \brief Blits an image
|
|
*
|
|
* \param [in] dstView Destination image view
|
|
* \param [in] srcView Source image view
|
|
* \param [in] dstOffsets Two pixel coordinates in the destination image
|
|
* \param [in] srcOffsets Two pixel coordinates in the source image
|
|
* \param [in] filter Texture filter
|
|
*/
|
|
void blitImageView(
|
|
const Rc<DxvkImageView>& dstView,
|
|
const VkOffset3D* dstOffsets,
|
|
const Rc<DxvkImageView>& srcView,
|
|
const VkOffset3D* srcOffsets,
|
|
VkFilter filter);
|
|
|
|
/**
|
|
* \brief Changes image layout
|
|
*
|
|
* Permanently changes the layout for a given
|
|
* image. Immediately performs the transition.
|
|
* \param [in] image The image to transition
|
|
* \param [in] layout New image layout
|
|
*/
|
|
void changeImageLayout(
|
|
const Rc<DxvkImage>& image,
|
|
VkImageLayout layout);
|
|
|
|
/**
|
|
* \brief Clears a buffer with a fixed value
|
|
*
|
|
* Note that both \c offset and \c length must
|
|
* be multiples of four, and that \c value is
|
|
* consumed as a four-byte word.
|
|
* \param [in] buffer The buffer to clear
|
|
* \param [in] offset Offset of the range to clear
|
|
* \param [in] length Bumber of bytes to clear
|
|
* \param [in] value Clear value
|
|
*/
|
|
void clearBuffer(
|
|
const Rc<DxvkBuffer>& buffer,
|
|
VkDeviceSize offset,
|
|
VkDeviceSize length,
|
|
uint32_t value);
|
|
|
|
/**
|
|
* \brief Clears a buffer view
|
|
*
|
|
* Unlike \c clearBuffer, this method can be used
|
|
* to clear a buffer view with format conversion.
|
|
* \param [in] bufferView The buffer view
|
|
* \param [in] offset Offset of the region to clear
|
|
* \param [in] length Extent of the region to clear
|
|
* \param [in] value The clear value
|
|
*/
|
|
void clearBufferView(
|
|
const Rc<DxvkBufferView>& bufferView,
|
|
VkDeviceSize offset,
|
|
VkDeviceSize length,
|
|
VkClearColorValue value);
|
|
|
|
/**
|
|
* \brief Clears an active render target
|
|
*
|
|
* \param [in] imageView Render target view to clear
|
|
* \param [in] clearAspects Image aspects to clear
|
|
* \param [in] clearValue The clear value
|
|
*/
|
|
void clearRenderTarget(
|
|
const Rc<DxvkImageView>& imageView,
|
|
VkImageAspectFlags clearAspects,
|
|
VkClearValue clearValue);
|
|
|
|
/**
|
|
* \brief Clears an image view
|
|
*
|
|
* Can be used to clear sub-regions of storage images
|
|
* that are not going to be used as render targets.
|
|
* Implicit format conversion will be applied.
|
|
* \param [in] imageView The image view
|
|
* \param [in] offset Offset of the rect to clear
|
|
* \param [in] extent Extent of the rect to clear
|
|
* \param [in] aspect Aspect mask to clear
|
|
* \param [in] value The clear value
|
|
*/
|
|
void clearImageView(
|
|
const Rc<DxvkImageView>& imageView,
|
|
VkOffset3D offset,
|
|
VkExtent3D extent,
|
|
VkImageAspectFlags aspect,
|
|
VkClearValue value);
|
|
|
|
/**
|
|
* \brief Copies data from one buffer to another
|
|
*
|
|
* \param [in] dstBuffer Destination buffer
|
|
* \param [in] dstOffset Destination data offset
|
|
* \param [in] srcBuffer Source buffer
|
|
* \param [in] srcOffset Source data offset
|
|
* \param [in] numBytes Number of bytes to copy
|
|
*/
|
|
void copyBuffer(
|
|
const Rc<DxvkBuffer>& dstBuffer,
|
|
VkDeviceSize dstOffset,
|
|
const Rc<DxvkBuffer>& srcBuffer,
|
|
VkDeviceSize srcOffset,
|
|
VkDeviceSize numBytes);
|
|
|
|
/**
|
|
* \brief Copies overlapping buffer region
|
|
*
|
|
* Can be used to copy potentially overlapping
|
|
* buffer regions within the same buffer. If
|
|
* the source and destination regions do not
|
|
* overlap, it will behave as \ref copyBuffer.
|
|
* \param [in] dstBuffer The buffer
|
|
* \param [in] dstOffset Offset of target region
|
|
* \param [in] srcOffset Offset of source region
|
|
* \param [in] numBytes Number of bytes to copy
|
|
*/
|
|
void copyBufferRegion(
|
|
const Rc<DxvkBuffer>& dstBuffer,
|
|
VkDeviceSize dstOffset,
|
|
VkDeviceSize srcOffset,
|
|
VkDeviceSize numBytes);
|
|
|
|
/**
|
|
* \brief Copies data from a buffer to an image
|
|
*
|
|
* Source data must be packed, except for the row alignment.
|
|
* \param [in] dstImage Destination image
|
|
* \param [in] dstSubresource Destination subresource
|
|
* \param [in] dstOffset Destination area offset
|
|
* \param [in] dstExtent Destination area size
|
|
* \param [in] srcBuffer Source buffer
|
|
* \param [in] srcOffset Source offset, in bytes
|
|
* \param [in] rowAlignment Row alignment, in bytes
|
|
* \param [in] sliceAlignment Slice alignment, in bytes
|
|
* \param [in] srcFormat Buffer data format. May be
|
|
* \c VK_FORMAT_UNKNOWN to use the image format.
|
|
*/
|
|
void copyBufferToImage(
|
|
const Rc<DxvkImage>& dstImage,
|
|
VkImageSubresourceLayers dstSubresource,
|
|
VkOffset3D dstOffset,
|
|
VkExtent3D dstExtent,
|
|
const Rc<DxvkBuffer>& srcBuffer,
|
|
VkDeviceSize srcOffset,
|
|
VkDeviceSize rowAlignment,
|
|
VkDeviceSize sliceAlignment,
|
|
VkFormat srcFormat);
|
|
|
|
/**
|
|
* \brief Copies data from one image to another
|
|
*
|
|
* \param [in] dstImage Destination image
|
|
* \param [in] dstSubresource Destination subresource
|
|
* \param [in] dstOffset Destination area offset
|
|
* \param [in] srcImage Source image
|
|
* \param [in] srcSubresource Source subresource
|
|
* \param [in] srcOffset Source area offset
|
|
* \param [in] extent Size of the area to copy
|
|
*/
|
|
void copyImage(
|
|
const Rc<DxvkImage>& dstImage,
|
|
VkImageSubresourceLayers dstSubresource,
|
|
VkOffset3D dstOffset,
|
|
const Rc<DxvkImage>& srcImage,
|
|
VkImageSubresourceLayers srcSubresource,
|
|
VkOffset3D srcOffset,
|
|
VkExtent3D extent);
|
|
|
|
/**
|
|
* \brief Copies overlapping image region
|
|
*
|
|
* \param [in] dstImage The image
|
|
* \param [in] dstSubresource The image subresource
|
|
* \param [in] dstOffset Destination region offset
|
|
* \param [in] srcOffset Source region offset
|
|
* \param [in] extent Size of the copy region
|
|
*/
|
|
void copyImageRegion(
|
|
const Rc<DxvkImage>& dstImage,
|
|
VkImageSubresourceLayers dstSubresource,
|
|
VkOffset3D dstOffset,
|
|
VkOffset3D srcOffset,
|
|
VkExtent3D extent);
|
|
|
|
/**
|
|
* \brief Copies data from an image into a buffer
|
|
*
|
|
* \param [in] dstBuffer Destination buffer
|
|
* \param [in] dstOffset Destination offset, in bytes
|
|
* \param [in] dstExtent Destination data extent
|
|
* \param [in] rowAlignment Row alignment, in bytes
|
|
* \param [in] sliceAlignment Slice alignment, in bytes
|
|
* \param [in] dstFormat Buffer format
|
|
* \param [in] srcImage Source image
|
|
* \param [in] srcSubresource Source subresource
|
|
* \param [in] srcOffset Source area offset
|
|
* \param [in] srcExtent Source area size
|
|
*/
|
|
void copyImageToBuffer(
|
|
const Rc<DxvkBuffer>& dstBuffer,
|
|
VkDeviceSize dstOffset,
|
|
VkDeviceSize rowAlignment,
|
|
VkDeviceSize sliceAlignment,
|
|
VkFormat dstFormat,
|
|
const Rc<DxvkImage>& srcImage,
|
|
VkImageSubresourceLayers srcSubresource,
|
|
VkOffset3D srcOffset,
|
|
VkExtent3D srcExtent);
|
|
|
|
/**
|
|
* \brief Copies image data stored in a linear buffer to another
|
|
*
|
|
* The source and destination regions may overlap, in which case
|
|
* a temporary copy of the source buffer will be created.
|
|
* \param [in] dstBuffer Destination buffer
|
|
* \param [in] dstBufferOffset Destination subresource offset
|
|
* \param [in] dstOffset Destination image offset
|
|
* \param [in] dstSize Total size of the destination image
|
|
* \param [in] srcBuffer Source buffer
|
|
* \param [in] srcBufferOffset Source subresource offset
|
|
* \param [in] srcOffset Source image offset
|
|
* \param [in] srcSize Total size of the source image
|
|
* \param [in] extent Number of pixels to copy
|
|
* \param [in] elementSize Pixel size, in bytes
|
|
*/
|
|
void copyPackedBufferImage(
|
|
const Rc<DxvkBuffer>& dstBuffer,
|
|
VkDeviceSize dstBufferOffset,
|
|
VkOffset3D dstOffset,
|
|
VkExtent3D dstSize,
|
|
const Rc<DxvkBuffer>& srcBuffer,
|
|
VkDeviceSize srcBufferOffset,
|
|
VkOffset3D srcOffset,
|
|
VkExtent3D srcSize,
|
|
VkExtent3D extent,
|
|
VkDeviceSize elementSize);
|
|
|
|
/**
|
|
* \brief Copies pages from a sparse resource to a buffer
|
|
*
|
|
* \param [in] dstBuffer Buffer to write to
|
|
* \param [in] dstOffset Buffer offset
|
|
* \param [in] srcResource Source resource
|
|
* \param [in] pageCount Number of pages to copy
|
|
* \param [in] pages Page indices to copy
|
|
*/
|
|
void copySparsePagesToBuffer(
|
|
const Rc<DxvkBuffer>& dstBuffer,
|
|
VkDeviceSize dstOffset,
|
|
const Rc<DxvkPagedResource>& srcResource,
|
|
uint32_t pageCount,
|
|
const uint32_t* pages);
|
|
|
|
/**
|
|
* \brief Copies pages from a buffer to a sparse resource
|
|
*
|
|
* \param [in] dstResource Resource to write to
|
|
* \param [in] pageCount Number of pages to copy
|
|
* \param [in] pages Page indices to copy
|
|
* \param [in] srcBuffer Source buffer
|
|
* \param [in] srcOffset Buffer offset
|
|
*/
|
|
void copySparsePagesFromBuffer(
|
|
const Rc<DxvkPagedResource>& dstResource,
|
|
uint32_t pageCount,
|
|
const uint32_t* pages,
|
|
const Rc<DxvkBuffer>& srcBuffer,
|
|
VkDeviceSize srcOffset);
|
|
|
|
/**
|
|
* \brief Discards contents of an image view
|
|
*
|
|
* Discards the current contents of the image
|
|
* and performs a fast layout transition. This
|
|
* may improve performance in some cases.
|
|
* \param [in] imageView View to discard
|
|
* \param [in] discardAspects Image aspects to discard
|
|
*/
|
|
void discardImageView(
|
|
const Rc<DxvkImageView>& imageView,
|
|
VkImageAspectFlags discardAspects);
|
|
|
|
/**
|
|
* \brief Discards contents of an image
|
|
*
|
|
* \param [in] image Image to discard
|
|
*/
|
|
void discardImage(
|
|
const Rc<DxvkImage>& image);
|
|
|
|
/**
|
|
* \brief Starts compute jobs
|
|
*
|
|
* \param [in] x Number of threads in X direction
|
|
* \param [in] y Number of threads in Y direction
|
|
* \param [in] z Number of threads in Z direction
|
|
*/
|
|
void dispatch(
|
|
uint32_t x,
|
|
uint32_t y,
|
|
uint32_t z);
|
|
|
|
/**
|
|
* \brief Indirect dispatch call
|
|
*
|
|
* Takes arguments from a buffer. The buffer must contain
|
|
* a structure of the type \c VkDispatchIndirectCommand.
|
|
* \param [in] offset Draw buffer offset
|
|
*/
|
|
void dispatchIndirect(
|
|
VkDeviceSize offset);
|
|
|
|
/**
|
|
* \brief Draws primitive without using an index buffer
|
|
*
|
|
* \param [in] vertexCount Number of vertices to draw
|
|
* \param [in] instanceCount Number of instances to render
|
|
* \param [in] firstVertex First vertex in vertex buffer
|
|
* \param [in] firstInstance First instance ID
|
|
*/
|
|
void draw(
|
|
uint32_t vertexCount,
|
|
uint32_t instanceCount,
|
|
uint32_t firstVertex,
|
|
uint32_t firstInstance);
|
|
|
|
/**
|
|
* \brief Indirect draw call
|
|
*
|
|
* Takes arguments from a buffer. The structure stored
|
|
* in the buffer must be of type \c VkDrawIndirectCommand.
|
|
* \param [in] offset Draw buffer offset
|
|
* \param [in] count Number of draws
|
|
* \param [in] stride Stride between dispatch calls
|
|
*/
|
|
void drawIndirect(
|
|
VkDeviceSize offset,
|
|
uint32_t count,
|
|
uint32_t stride);
|
|
|
|
/**
|
|
* \brief Indirect draw call
|
|
*
|
|
* Takes arguments from a buffer. The structure stored
|
|
* in the buffer must be of type \c VkDrawIndirectCommand.
|
|
* \param [in] offset Draw buffer offset
|
|
* \param [in] countOffset Draw count offset
|
|
* \param [in] maxCount Maximum number of draws
|
|
* \param [in] stride Stride between dispatch calls
|
|
*/
|
|
void drawIndirectCount(
|
|
VkDeviceSize offset,
|
|
VkDeviceSize countOffset,
|
|
uint32_t maxCount,
|
|
uint32_t stride);
|
|
|
|
/**
|
|
* \brief Draws primitives using an index buffer
|
|
*
|
|
* \param [in] indexCount Number of indices to draw
|
|
* \param [in] instanceCount Number of instances to render
|
|
* \param [in] firstIndex First index within the index buffer
|
|
* \param [in] vertexOffset Vertex ID that corresponds to index 0
|
|
* \param [in] firstInstance First instance ID
|
|
*/
|
|
void drawIndexed(
|
|
uint32_t indexCount,
|
|
uint32_t instanceCount,
|
|
uint32_t firstIndex,
|
|
int32_t vertexOffset,
|
|
uint32_t firstInstance);
|
|
|
|
/**
|
|
* \brief Indirect indexed draw call
|
|
*
|
|
* Takes arguments from a buffer. The structure type for
|
|
* the draw buffer is \c VkDrawIndexedIndirectCommand.
|
|
* \param [in] offset Draw buffer offset
|
|
* \param [in] count Number of draws
|
|
* \param [in] stride Stride between dispatch calls
|
|
*/
|
|
void drawIndexedIndirect(
|
|
VkDeviceSize offset,
|
|
uint32_t count,
|
|
uint32_t stride);
|
|
|
|
/**
|
|
* \brief Indirect indexed draw call
|
|
*
|
|
* Takes arguments from a buffer. The structure type for
|
|
* the draw buffer is \c VkDrawIndexedIndirectCommand.
|
|
* \param [in] offset Draw buffer offset
|
|
* \param [in] countOffset Draw count offset
|
|
* \param [in] maxCount Maximum number of draws
|
|
* \param [in] stride Stride between dispatch calls
|
|
*/
|
|
void drawIndexedIndirectCount(
|
|
VkDeviceSize offset,
|
|
VkDeviceSize countOffset,
|
|
uint32_t maxCount,
|
|
uint32_t stride);
|
|
|
|
/**
|
|
* \brief Transform feddback draw call
|
|
|
|
* \param [in] counterBuffer Xfb counter buffer
|
|
* \param [in] counterDivisor Vertex stride
|
|
* \param [in] counterBias Counter bias
|
|
*/
|
|
void drawIndirectXfb(
|
|
const DxvkBufferSlice& counterBuffer,
|
|
uint32_t counterDivisor,
|
|
uint32_t counterBias);
|
|
|
|
/**
|
|
* \brief Emits graphics barrier
|
|
*
|
|
* Needs to be used when the fragment shader reads a bound
|
|
* render target, or when subsequent draw calls access any
|
|
* given resource for writing. It is assumed that no hazards
|
|
* can happen between storage descriptors and other resources.
|
|
* \param [in] srcStages Source pipeline stages
|
|
* \param [in] srcAccess Source access
|
|
* \param [in] dstStages Destination pipeline stages
|
|
* \param [in] dstAccess Destination access
|
|
*/
|
|
void emitGraphicsBarrier(
|
|
VkPipelineStageFlags srcStages,
|
|
VkAccessFlags srcAccess,
|
|
VkPipelineStageFlags dstStages,
|
|
VkAccessFlags dstAccess);
|
|
|
|
/**
|
|
* \brief Emits buffer barrier
|
|
*
|
|
* Can be used to transition foreign resources
|
|
* into a state that DXVK can work with.
|
|
* \param [in] resource Buffer resource
|
|
* \param [in] srcStages Source pipeline stages
|
|
* \param [in] srcAccess Source access
|
|
* \param [in] dstStages Destination pipeline stages
|
|
* \param [in] dstAccess Destination access
|
|
*/
|
|
void emitBufferBarrier(
|
|
const Rc<DxvkBuffer>& resource,
|
|
VkPipelineStageFlags srcStages,
|
|
VkAccessFlags srcAccess,
|
|
VkPipelineStageFlags dstStages,
|
|
VkAccessFlags dstAccess);
|
|
|
|
/**
|
|
* \brief Emits image barrier
|
|
*
|
|
* Can be used to transition foreign resources
|
|
* into a state that DXVK can work with.
|
|
* \param [in] resource Image resource
|
|
* \param [in] srcLayout Current image layout
|
|
* \param [in] srcStages Source pipeline stages
|
|
* \param [in] srcAccess Source access
|
|
* \param [in] dstLayout New image layout
|
|
* \param [in] dstStages Destination pipeline stages
|
|
* \param [in] dstAccess Destination access
|
|
*/
|
|
void emitImageBarrier(
|
|
const Rc<DxvkImage>& resource,
|
|
VkImageLayout srcLayout,
|
|
VkPipelineStageFlags srcStages,
|
|
VkAccessFlags srcAccess,
|
|
VkImageLayout dstLayout,
|
|
VkPipelineStageFlags dstStages,
|
|
VkAccessFlags dstAccess);
|
|
|
|
/**
|
|
* \brief Generates mip maps
|
|
*
|
|
* Uses blitting to generate lower mip levels from
|
|
* the top-most mip level passed to this method.
|
|
* \param [in] imageView The image to generate mips for
|
|
* \param [in] filter The filter to use for generation
|
|
*/
|
|
void generateMipmaps(
|
|
const Rc<DxvkImageView>& imageView,
|
|
VkFilter filter);
|
|
|
|
/**
|
|
* \brief Initializes a buffer
|
|
*
|
|
* Clears the given buffer to zero. Only safe to call
|
|
* if the buffer is not currently in use by the GPU.
|
|
* \param [in] buffer Buffer to clear
|
|
*/
|
|
void initBuffer(
|
|
const Rc<DxvkBuffer>& buffer);
|
|
|
|
/**
|
|
* \brief Initializes an image
|
|
*
|
|
* Transitions the image into its default layout, and clears
|
|
* it to black unless the initial layout is preinitialized.
|
|
* Only safe to call if the image is not in use by the GPU.
|
|
* \param [in] image The image to initialize
|
|
* \param [in] subresources Image subresources
|
|
* \param [in] initialLayout Initial image layout
|
|
*/
|
|
void initImage(
|
|
const Rc<DxvkImage>& image,
|
|
const VkImageSubresourceRange& subresources,
|
|
VkImageLayout initialLayout);
|
|
|
|
/**
|
|
* \brief Initializes sparse image
|
|
*
|
|
* Binds any metadata aspects that the image might
|
|
* have, and performs the initial layout transition.
|
|
* \param [in] image Image to initialize
|
|
*/
|
|
void initSparseImage(
|
|
const Rc<DxvkImage>& image);
|
|
|
|
/**
|
|
* \brief Invalidates a buffer's contents
|
|
*
|
|
* Discards a buffer's contents by replacing the
|
|
* backing resource. This allows the host to access
|
|
* the buffer while the GPU is still accessing the
|
|
* original backing resource.
|
|
* \param [in] buffer The buffer to invalidate
|
|
* \param [in] slice New buffer slice
|
|
*/
|
|
void invalidateBuffer(
|
|
const Rc<DxvkBuffer>& buffer,
|
|
Rc<DxvkResourceAllocation>&& slice);
|
|
|
|
/**
|
|
* \brief Ensures that buffer will not be relocated
|
|
*
|
|
* This guarantees that the buffer's GPU address remains the same
|
|
* throughout its lifetime. Only prevents implicit invalidation or
|
|
* relocation by the backend, client APIs must take care to respect
|
|
* this too.
|
|
* \param [in] buffer Buffer to lock in place
|
|
*/
|
|
void ensureBufferAddress(
|
|
const Rc<DxvkBuffer>& buffer);
|
|
|
|
/**
|
|
* \brief Invalidates image content
|
|
*
|
|
* Replaces the backing storage of an image.
|
|
* \param [in] buffer The buffer to invalidate
|
|
* \param [in] slice New buffer slice
|
|
*/
|
|
void invalidateImage(
|
|
const Rc<DxvkImage>& image,
|
|
Rc<DxvkResourceAllocation>&& slice);
|
|
|
|
/**
|
|
* \brief Invalidates image content and add usage flag
|
|
*
|
|
* Replaces the backing storage of an image.
|
|
* \param [in] buffer The buffer to invalidate
|
|
* \param [in] slice New buffer slice
|
|
* \param [in] usageInfo Added usage info
|
|
*/
|
|
void invalidateImageWithUsage(
|
|
const Rc<DxvkImage>& image,
|
|
Rc<DxvkResourceAllocation>&& slice,
|
|
const DxvkImageUsageInfo& usageInfo);
|
|
|
|
/**
|
|
* \brief Ensures that an image supports the given usage
|
|
*
|
|
* No-op if the image already supports the requested properties.
|
|
* Otherwise, this will allocate a new backing resource with the
|
|
* requested properties and copy the current contents to it.
|
|
* \param [in] image Image resource
|
|
* \param [in] usageInfo Usage info to add
|
|
* \returns \c true if the image can support the given usage
|
|
*/
|
|
bool ensureImageCompatibility(
|
|
const Rc<DxvkImage>& image,
|
|
const DxvkImageUsageInfo& usageInfo);
|
|
|
|
/**
|
|
* \brief Updates push constants
|
|
*
|
|
* Updates the given push constant range.
|
|
* \param [in] offset Byte offset of data to update
|
|
* \param [in] size Number of bytes to update
|
|
* \param [in] data Pointer to raw data
|
|
*/
|
|
void pushConstants(
|
|
uint32_t offset,
|
|
uint32_t size,
|
|
const void* data) {
|
|
std::memcpy(&m_state.pc.data[offset], data, size);
|
|
|
|
m_flags.set(DxvkContextFlag::DirtyPushConstants);
|
|
}
|
|
|
|
/**
|
|
* \brief Resolves a multisampled image resource
|
|
*
|
|
* Resolves a multisampled image into a non-multisampled
|
|
* image. The subresources of both images must have the
|
|
* same size and compatible formats.
|
|
* A format can be specified for the resolve operation.
|
|
* If it is \c VK_FORMAT_UNDEFINED, the resolve operation
|
|
* will use the source image format.
|
|
* \param [in] dstImage Destination image
|
|
* \param [in] srcImage Source image
|
|
* \param [in] region Region to resolve
|
|
* \param [in] format Format for the resolve operation
|
|
*/
|
|
void resolveImage(
|
|
const Rc<DxvkImage>& dstImage,
|
|
const Rc<DxvkImage>& srcImage,
|
|
const VkImageResolve& region,
|
|
VkFormat format);
|
|
|
|
/**
|
|
* \brief Resolves a multisampled depth-stencil resource
|
|
*
|
|
* \param [in] dstImage Destination image
|
|
* \param [in] srcImage Source image
|
|
* \param [in] region Region to resolve
|
|
* \param [in] depthMode Resolve mode for depth aspect
|
|
* \param [in] stencilMode Resolve mode for stencil aspect
|
|
*/
|
|
void resolveDepthStencilImage(
|
|
const Rc<DxvkImage>& dstImage,
|
|
const Rc<DxvkImage>& srcImage,
|
|
const VkImageResolve& region,
|
|
VkResolveModeFlagBits depthMode,
|
|
VkResolveModeFlagBits stencilMode);
|
|
|
|
/**
|
|
* \brief Transforms image subresource layouts
|
|
*
|
|
* \param [in] dstImage Image to transform
|
|
* \param [in] dstSubresources Subresources
|
|
* \param [in] srcLayout Current layout
|
|
* \param [in] dstLayout Desired layout
|
|
*/
|
|
void transformImage(
|
|
const Rc<DxvkImage>& dstImage,
|
|
const VkImageSubresourceRange& dstSubresources,
|
|
VkImageLayout srcLayout,
|
|
VkImageLayout dstLayout);
|
|
|
|
/**
|
|
* \brief Updates a buffer
|
|
*
|
|
* Copies data from the host into a buffer.
|
|
* \param [in] buffer Destination buffer
|
|
* \param [in] offset Offset of sub range to update
|
|
* \param [in] size Length of sub range to update
|
|
* \param [in] data Data to upload
|
|
*/
|
|
void updateBuffer(
|
|
const Rc<DxvkBuffer>& buffer,
|
|
VkDeviceSize offset,
|
|
VkDeviceSize size,
|
|
const void* data);
|
|
|
|
/**
|
|
* \brief Uses transfer queue to initialize buffer
|
|
*
|
|
* Always replaces the entire buffer. Only safe to use
|
|
* if the buffer is currently not in use by the GPU.
|
|
* \param [in] buffer The buffer to initialize
|
|
* \param [in] source Staging buffer containing data
|
|
* \param [in] sourceOffset Offset into staging buffer
|
|
*/
|
|
void uploadBuffer(
|
|
const Rc<DxvkBuffer>& buffer,
|
|
const Rc<DxvkBuffer>& source,
|
|
VkDeviceSize sourceOffset);
|
|
|
|
/**
|
|
* \brief Uses transfer queue to initialize image
|
|
*
|
|
* Only safe to use if the image is not in use by the GPU.
|
|
* Data for each subresource is tightly packed, but individual
|
|
* subresources must be aligned to \c subresourceAlignment in
|
|
* order to meet Vulkan requirements when using transfer queues.
|
|
* \param [in] image The image to initialize
|
|
* \param [in] source Staging buffer containing data
|
|
* \param [in] sourceOffset Offset into staging buffer
|
|
* \param [in] subresourceAlignment Subresource alignment
|
|
* \param [in] format Actual data format
|
|
*/
|
|
void uploadImage(
|
|
const Rc<DxvkImage>& image,
|
|
const Rc<DxvkBuffer>& source,
|
|
VkDeviceSize sourceOffset,
|
|
VkDeviceSize subresourceAlignment,
|
|
VkFormat format);
|
|
|
|
/**
|
|
* \brief Sets viewports
|
|
*
|
|
* \param [in] viewportCount Number of viewports
|
|
* \param [in] viewports The viewports
|
|
* \param [in] scissorRects Schissor rectangles
|
|
*/
|
|
void setViewports(
|
|
uint32_t viewportCount,
|
|
const VkViewport* viewports,
|
|
const VkRect2D* scissorRects);
|
|
|
|
/**
|
|
* \brief Sets blend constants
|
|
*
|
|
* Blend constants are a set of four floating
|
|
* point numbers that may be used as an input
|
|
* for blending operations.
|
|
* \param [in] blendConstants Blend constants
|
|
*/
|
|
void setBlendConstants(
|
|
DxvkBlendConstants blendConstants);
|
|
|
|
/**
|
|
* \brief Sets depth bias
|
|
*
|
|
* Depth bias has to be enabled explicitly in
|
|
* the rasterizer state to have any effect.
|
|
* \param [in] depthBias Depth bias values
|
|
*/
|
|
void setDepthBias(
|
|
DxvkDepthBias depthBias);
|
|
|
|
/**
|
|
* \brief Sets depth bias representation
|
|
*
|
|
* \param [in] depthBiasRepresentation Depth bias representation
|
|
*/
|
|
void setDepthBiasRepresentation(
|
|
DxvkDepthBiasRepresentation depthBiasRepresentation);
|
|
|
|
/**
|
|
* \brief Sets depth bounds
|
|
*
|
|
* Enables or disables the depth bounds test,
|
|
* and updates the values if necessary.
|
|
* \param [in] depthBounds Depth bounds
|
|
*/
|
|
void setDepthBounds(
|
|
DxvkDepthBounds depthBounds);
|
|
|
|
/**
|
|
* \brief Sets stencil reference
|
|
*
|
|
* Sets the reference value for stencil compare operations.
|
|
* \param [in] reference Reference value
|
|
*/
|
|
void setStencilReference(
|
|
uint32_t reference);
|
|
|
|
/**
|
|
* \brief Sets input assembly state
|
|
* \param [in] ia New state object
|
|
*/
|
|
void setInputAssemblyState(
|
|
const DxvkInputAssemblyState& ia);
|
|
|
|
/**
|
|
* \brief Sets input layout
|
|
*
|
|
* \param [in] attributeCount Number of vertex attributes
|
|
* \param [in] attributes The vertex attributes
|
|
* \param [in] bindingCount Number of buffer bindings
|
|
* \param [in] bindings Vertex buffer bindigs
|
|
*/
|
|
void setInputLayout(
|
|
uint32_t attributeCount,
|
|
const DxvkVertexAttribute* attributes,
|
|
uint32_t bindingCount,
|
|
const DxvkVertexBinding* bindings);
|
|
|
|
/**
|
|
* \brief Sets rasterizer state
|
|
* \param [in] rs New state object
|
|
*/
|
|
void setRasterizerState(
|
|
const DxvkRasterizerState& rs);
|
|
|
|
/**
|
|
* \brief Sets multisample state
|
|
* \param [in] ms New state object
|
|
*/
|
|
void setMultisampleState(
|
|
const DxvkMultisampleState& ms);
|
|
|
|
/**
|
|
* \brief Sets depth stencil state
|
|
* \param [in] ds New state object
|
|
*/
|
|
void setDepthStencilState(
|
|
const DxvkDepthStencilState& ds);
|
|
|
|
/**
|
|
* \brief Sets logic op state
|
|
* \param [in] lo New state object
|
|
*/
|
|
void setLogicOpState(
|
|
const DxvkLogicOpState& lo);
|
|
|
|
/**
|
|
* \brief Sets blend mode for an attachment
|
|
*
|
|
* \param [in] attachment The attachment index
|
|
* \param [in] blendMode The blend mode
|
|
*/
|
|
void setBlendMode(
|
|
uint32_t attachment,
|
|
const DxvkBlendMode& blendMode);
|
|
|
|
/**
|
|
* \brief Sets specialization constants
|
|
*
|
|
* Replaces current specialization constants
|
|
* with the given list of constant entries.
|
|
* \param [in] pipeline Graphics or Compute pipeline
|
|
* \param [in] index Constant index
|
|
* \param [in] value Constant value
|
|
*/
|
|
void setSpecConstant(
|
|
VkPipelineBindPoint pipeline,
|
|
uint32_t index,
|
|
uint32_t value) {
|
|
auto& scState = pipeline == VK_PIPELINE_BIND_POINT_GRAPHICS
|
|
? m_state.gp.constants : m_state.cp.constants;
|
|
|
|
if (scState.data[index] != value) {
|
|
scState.data[index] = value;
|
|
|
|
if (scState.mask & (1u << index)) {
|
|
m_flags.set(pipeline == VK_PIPELINE_BIND_POINT_GRAPHICS
|
|
? DxvkContextFlag::GpDirtySpecConstants
|
|
: DxvkContextFlag::CpDirtySpecConstants);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Sets barrier control flags
|
|
*
|
|
* Barrier control flags can be used to control
|
|
* implicit synchronization of compute shaders.
|
|
* \param [in] control New barrier control flags
|
|
*/
|
|
void setBarrierControl(
|
|
DxvkBarrierControlFlags control);
|
|
|
|
/**
|
|
* \brief Updates page table for a given sparse resource
|
|
*
|
|
* Note that this is a very high overhead operation.
|
|
* \param [in] bindInfo Sparse bind info
|
|
* \param [in] flags Sparse bind flags
|
|
*/
|
|
void updatePageTable(
|
|
const DxvkSparseBindInfo& bindInfo,
|
|
DxvkSparseBindFlags flags);
|
|
|
|
/**
|
|
* \brief Launches a Cuda kernel
|
|
*
|
|
* Since the kernel is launched with an opaque set of
|
|
* kernel-specific parameters which may reference
|
|
* resources bindlessly, such resources must be listed by
|
|
* the caller in the 'buffers' and 'images' parameters so
|
|
* that their access may be tracked appropriately.
|
|
* \param [in] nvxLaunchInfo Kernel launch parameter struct
|
|
* \param [in] buffers List of {buffer,read,write} used by kernel
|
|
* \param [in] images List of {image,read,write} used by kernel
|
|
*/
|
|
void launchCuKernelNVX(
|
|
const VkCuLaunchInfoNVX& nvxLaunchInfo,
|
|
const std::vector<std::pair<Rc<DxvkBuffer>, DxvkAccessFlags>>& buffers,
|
|
const std::vector<std::pair<Rc<DxvkImage>, DxvkAccessFlags>>& images);
|
|
|
|
/**
|
|
* \brief Signals a GPU event
|
|
* \param [in] event The event
|
|
*/
|
|
void signalGpuEvent(
|
|
const Rc<DxvkEvent>& event);
|
|
|
|
/**
|
|
* \brief Writes to a timestamp query
|
|
* \param [in] query The timestamp query
|
|
*/
|
|
void writeTimestamp(
|
|
const Rc<DxvkQuery>& query);
|
|
|
|
/**
|
|
* \brief Queues a signal
|
|
*
|
|
* The signal will be notified after all
|
|
* previously submitted commands have
|
|
* finished execution on the GPU.
|
|
* \param [in] signal The signal
|
|
* \param [in] value Signal value
|
|
*/
|
|
void signal(
|
|
const Rc<sync::Signal>& signal,
|
|
uint64_t value);
|
|
|
|
/**
|
|
* \brief Waits for fence
|
|
*
|
|
* Stalls current command list execution until
|
|
* the fence reaches the given value or higher.
|
|
* \param [in] fence Fence to wait on
|
|
* \param [in] value Value to wait on
|
|
*/
|
|
void waitFence(const Rc<DxvkFence>& fence, uint64_t value);
|
|
|
|
/**
|
|
* \brief Signals fence
|
|
*
|
|
* Signals fence to the given value once the current
|
|
* command list execution completes on the GPU.
|
|
* \param [in] fence Fence to signal
|
|
* \param [in] value Value to signal
|
|
*/
|
|
void signalFence(const Rc<DxvkFence>& fence, uint64_t value);
|
|
|
|
/**
|
|
* \brief Begins a debug label region
|
|
*
|
|
* Marks the start of a debug label region. Used by debugging/profiling
|
|
* tools to mark different workloads within a frame.
|
|
* \param [in] label The debug label
|
|
*/
|
|
void beginDebugLabel(const VkDebugUtilsLabelEXT& label);
|
|
|
|
/**
|
|
* \brief Ends a debug label region
|
|
*
|
|
* Marks the close of a debug label region. Used by debugging/profiling
|
|
* tools to mark different workloads within a frame.
|
|
*/
|
|
void endDebugLabel();
|
|
|
|
/**
|
|
* \brief Inserts a debug label
|
|
*
|
|
* Inserts an instantaneous debug label. Used by debugging/profiling
|
|
* tools to mark different workloads within a frame.
|
|
* \param [in] label The debug label
|
|
*/
|
|
void insertDebugLabel(const VkDebugUtilsLabelEXT& label);
|
|
|
|
/**
|
|
* \brief Increments a given stat counter
|
|
*
|
|
* The stat counters will be merged into the global
|
|
* stat counters upon execution of the command list.
|
|
* \param [in] counter Stat counter to increment
|
|
* \param [in] value Increment value
|
|
*/
|
|
void addStatCtr(DxvkStatCounter counter, uint64_t value) {
|
|
if (m_cmd != nullptr)
|
|
m_cmd->addStatCtr(counter, value);
|
|
}
|
|
|
|
/**
|
|
* \brief Sets new debug name for a resource
|
|
*
|
|
* \param [in] buffer Buffer object
|
|
* \param [in] name New debug name, or \c nullptr
|
|
*/
|
|
void setDebugName(const Rc<DxvkPagedResource>& resource, const char* name);
|
|
|
|
private:
|
|
|
|
Rc<DxvkDevice> m_device;
|
|
DxvkObjects* m_common;
|
|
|
|
uint64_t m_trackingId = 0u;
|
|
uint32_t m_renderPassIndex = 0u;
|
|
|
|
Rc<DxvkCommandList> m_cmd;
|
|
Rc<DxvkBuffer> m_zeroBuffer;
|
|
|
|
DxvkContextFlags m_flags;
|
|
DxvkContextState m_state;
|
|
DxvkContextFeatures m_features;
|
|
DxvkDescriptorState m_descriptorState;
|
|
|
|
Rc<DxvkDescriptorPool> m_descriptorPool;
|
|
Rc<DxvkDescriptorManager> m_descriptorManager;
|
|
|
|
DxvkBarrierBatch m_sdmaAcquires;
|
|
DxvkBarrierBatch m_sdmaBarriers;
|
|
DxvkBarrierBatch m_initAcquires;
|
|
DxvkBarrierBatch m_initBarriers;
|
|
DxvkBarrierBatch m_execBarriers;
|
|
DxvkBarrierTracker m_barrierTracker;
|
|
DxvkBarrierControlFlags m_barrierControl;
|
|
|
|
DxvkGpuQueryManager m_queryManager;
|
|
|
|
DxvkGlobalPipelineBarrier m_globalRoGraphicsBarrier;
|
|
DxvkGlobalPipelineBarrier m_globalRwGraphicsBarrier;
|
|
|
|
DxvkRenderTargetLayouts m_rtLayouts = { };
|
|
|
|
std::vector<DxvkDeferredClear> m_deferredClears;
|
|
std::array<DxvkDeferredResolve, MaxNumRenderTargets + 1u> m_deferredResolves = { };
|
|
|
|
std::vector<VkWriteDescriptorSet> m_descriptorWrites;
|
|
std::vector<DxvkDescriptorInfo> m_descriptors;
|
|
|
|
std::array<DxvkShaderResourceSlot, MaxNumResourceSlots> m_rc;
|
|
std::array<DxvkGraphicsPipeline*, 4096> m_gpLookupCache = { };
|
|
std::array<DxvkComputePipeline*, 256> m_cpLookupCache = { };
|
|
|
|
std::vector<VkImageMemoryBarrier2> m_imageLayoutTransitions;
|
|
|
|
std::vector<util::DxvkDebugLabel> m_debugLabelStack;
|
|
bool m_debugLabelInternalActive = false;
|
|
|
|
Rc<DxvkLatencyTracker> m_latencyTracker;
|
|
uint64_t m_latencyFrameId = 0u;
|
|
bool m_endLatencyTracking = false;
|
|
|
|
void blitImageFb(
|
|
Rc<DxvkImageView> dstView,
|
|
const VkOffset3D* dstOffsets,
|
|
Rc<DxvkImageView> srcView,
|
|
const VkOffset3D* srcOffsets,
|
|
VkFilter filter);
|
|
|
|
void blitImageHw(
|
|
const Rc<DxvkImageView>& dstView,
|
|
const VkOffset3D* dstOffsets,
|
|
const Rc<DxvkImageView>& srcView,
|
|
const VkOffset3D* srcOffsets,
|
|
VkFilter filter);
|
|
|
|
template<bool ToImage>
|
|
void copyImageBufferData(
|
|
DxvkCmdBuffer cmd,
|
|
const Rc<DxvkImage>& image,
|
|
const VkImageSubresourceLayers& imageSubresource,
|
|
VkOffset3D imageOffset,
|
|
VkExtent3D imageExtent,
|
|
VkImageLayout imageLayout,
|
|
const DxvkBufferSliceHandle& bufferSlice,
|
|
VkDeviceSize bufferRowAlignment,
|
|
VkDeviceSize bufferSliceAlignment);
|
|
|
|
void copyBufferToImageHw(
|
|
const Rc<DxvkImage>& image,
|
|
const VkImageSubresourceLayers& imageSubresource,
|
|
VkOffset3D imageOffset,
|
|
VkExtent3D imageExtent,
|
|
const Rc<DxvkBuffer>& buffer,
|
|
VkDeviceSize bufferOffset,
|
|
VkDeviceSize bufferRowAlignment,
|
|
VkDeviceSize bufferSliceAlignment);
|
|
|
|
void copyBufferToImageFb(
|
|
const Rc<DxvkImage>& image,
|
|
const VkImageSubresourceLayers& imageSubresource,
|
|
VkOffset3D imageOffset,
|
|
VkExtent3D imageExtent,
|
|
const Rc<DxvkBuffer>& buffer,
|
|
VkDeviceSize bufferOffset,
|
|
VkDeviceSize bufferRowAlignment,
|
|
VkDeviceSize bufferSliceAlignment,
|
|
VkFormat bufferFormat);
|
|
|
|
void copyImageToBufferHw(
|
|
const Rc<DxvkBuffer>& buffer,
|
|
VkDeviceSize bufferOffset,
|
|
VkDeviceSize bufferRowAlignment,
|
|
VkDeviceSize bufferSliceAlignment,
|
|
const Rc<DxvkImage>& image,
|
|
VkImageSubresourceLayers imageSubresource,
|
|
VkOffset3D imageOffset,
|
|
VkExtent3D imageExtent);
|
|
|
|
void copyImageToBufferCs(
|
|
const Rc<DxvkBuffer>& buffer,
|
|
VkDeviceSize bufferOffset,
|
|
VkDeviceSize bufferRowAlignment,
|
|
VkDeviceSize bufferSliceAlignment,
|
|
VkFormat bufferFormat,
|
|
const Rc<DxvkImage>& image,
|
|
VkImageSubresourceLayers imageSubresource,
|
|
VkOffset3D imageOffset,
|
|
VkExtent3D imageExtent);
|
|
|
|
void clearImageViewFb(
|
|
const Rc<DxvkImageView>& imageView,
|
|
VkOffset3D offset,
|
|
VkExtent3D extent,
|
|
VkImageAspectFlags aspect,
|
|
VkClearValue value);
|
|
|
|
void clearImageViewCs(
|
|
const Rc<DxvkImageView>& imageView,
|
|
VkOffset3D offset,
|
|
VkExtent3D extent,
|
|
VkClearValue value);
|
|
|
|
void copyImageHw(
|
|
const Rc<DxvkImage>& dstImage,
|
|
VkImageSubresourceLayers dstSubresource,
|
|
VkOffset3D dstOffset,
|
|
const Rc<DxvkImage>& srcImage,
|
|
VkImageSubresourceLayers srcSubresource,
|
|
VkOffset3D srcOffset,
|
|
VkExtent3D extent);
|
|
|
|
void copyImageFb(
|
|
const Rc<DxvkImage>& dstImage,
|
|
VkImageSubresourceLayers dstSubresource,
|
|
VkOffset3D dstOffset,
|
|
const Rc<DxvkImage>& srcImage,
|
|
VkImageSubresourceLayers srcSubresource,
|
|
VkOffset3D srcOffset,
|
|
VkExtent3D extent);
|
|
|
|
bool copyImageClear(
|
|
const Rc<DxvkImage>& dstImage,
|
|
VkImageSubresourceLayers dstSubresource,
|
|
VkOffset3D dstOffset,
|
|
VkExtent3D dstExtent,
|
|
const Rc<DxvkImage>& srcImage,
|
|
VkImageSubresourceLayers srcSubresource);
|
|
|
|
template<bool ToBuffer>
|
|
void copySparsePages(
|
|
const Rc<DxvkPagedResource>& sparse,
|
|
uint32_t pageCount,
|
|
const uint32_t* pages,
|
|
const Rc<DxvkBuffer>& buffer,
|
|
VkDeviceSize offset);
|
|
|
|
template<bool ToBuffer>
|
|
void copySparseBufferPages(
|
|
const Rc<DxvkBuffer>& sparse,
|
|
uint32_t pageCount,
|
|
const uint32_t* pages,
|
|
const Rc<DxvkBuffer>& buffer,
|
|
VkDeviceSize offset);
|
|
|
|
template<bool ToBuffer>
|
|
void copySparseImagePages(
|
|
const Rc<DxvkImage>& sparse,
|
|
uint32_t pageCount,
|
|
const uint32_t* pages,
|
|
const Rc<DxvkBuffer>& buffer,
|
|
VkDeviceSize offset);
|
|
|
|
void resolveImageHw(
|
|
const Rc<DxvkImage>& dstImage,
|
|
const Rc<DxvkImage>& srcImage,
|
|
const VkImageResolve& region);
|
|
|
|
void resolveImageDs(
|
|
const Rc<DxvkImage>& dstImage,
|
|
const Rc<DxvkImage>& srcImage,
|
|
const VkImageResolve& region,
|
|
VkResolveModeFlagBits depthMode,
|
|
VkResolveModeFlagBits stencilMode);
|
|
|
|
void resolveImageFb(
|
|
const Rc<DxvkImage>& dstImage,
|
|
const Rc<DxvkImage>& srcImage,
|
|
const VkImageResolve& region,
|
|
VkFormat format,
|
|
VkResolveModeFlagBits depthMode,
|
|
VkResolveModeFlagBits stencilMode);
|
|
|
|
bool resolveImageClear(
|
|
const Rc<DxvkImage>& dstImage,
|
|
const Rc<DxvkImage>& srcImage,
|
|
const VkImageResolve& region,
|
|
VkFormat format);
|
|
|
|
bool resolveImageInline(
|
|
const Rc<DxvkImage>& dstImage,
|
|
const Rc<DxvkImage>& srcImage,
|
|
const VkImageResolve& region,
|
|
VkFormat format,
|
|
VkResolveModeFlagBits depthMode,
|
|
VkResolveModeFlagBits stencilMode);
|
|
|
|
void uploadImageFb(
|
|
const Rc<DxvkImage>& image,
|
|
const Rc<DxvkBuffer>& source,
|
|
VkDeviceSize sourceOffset,
|
|
VkDeviceSize subresourceAlignment,
|
|
VkFormat format);
|
|
|
|
void uploadImageHw(
|
|
const Rc<DxvkImage>& image,
|
|
const Rc<DxvkBuffer>& source,
|
|
VkDeviceSize subresourceAlignment,
|
|
VkDeviceSize sourceOffset);
|
|
|
|
void performClear(
|
|
const Rc<DxvkImageView>& imageView,
|
|
int32_t attachmentIndex,
|
|
VkImageAspectFlags discardAspects,
|
|
VkImageAspectFlags clearAspects,
|
|
VkClearValue clearValue);
|
|
|
|
void deferClear(
|
|
const Rc<DxvkImageView>& imageView,
|
|
VkImageAspectFlags clearAspects,
|
|
VkClearValue clearValue);
|
|
|
|
void deferDiscard(
|
|
const Rc<DxvkImageView>& imageView,
|
|
VkImageAspectFlags discardAspects);
|
|
|
|
void flushClears(
|
|
bool useRenderPass);
|
|
|
|
void flushSharedImages();
|
|
|
|
void flushRenderPassResolves();
|
|
|
|
void flushResolves();
|
|
|
|
void startRenderPass();
|
|
void spillRenderPass(bool suspend);
|
|
|
|
void renderPassEmitInitBarriers(
|
|
const DxvkFramebufferInfo& framebufferInfo,
|
|
const DxvkRenderPassOps& ops);
|
|
|
|
void renderPassEmitPostBarriers(
|
|
const DxvkFramebufferInfo& framebufferInfo,
|
|
const DxvkRenderPassOps& ops);
|
|
|
|
void renderPassBindFramebuffer(
|
|
const DxvkFramebufferInfo& framebufferInfo,
|
|
const DxvkRenderPassOps& ops);
|
|
|
|
void renderPassUnbindFramebuffer();
|
|
|
|
void resetRenderPassOps(
|
|
const DxvkRenderTargets& renderTargets,
|
|
DxvkRenderPassOps& renderPassOps);
|
|
|
|
void startTransformFeedback();
|
|
void pauseTransformFeedback();
|
|
|
|
void unbindComputePipeline();
|
|
bool updateComputePipelineState();
|
|
|
|
void unbindGraphicsPipeline();
|
|
bool updateGraphicsPipeline();
|
|
bool updateGraphicsPipelineState(DxvkGlobalPipelineBarrier srcBarrier);
|
|
|
|
uint32_t getGraphicsPipelineDebugColor() const;
|
|
|
|
template<VkPipelineBindPoint BindPoint>
|
|
void resetSpecConstants(
|
|
uint32_t newMask);
|
|
|
|
template<VkPipelineBindPoint BindPoint>
|
|
void updateSpecConstants();
|
|
|
|
void invalidateState();
|
|
|
|
template<VkPipelineBindPoint BindPoint>
|
|
void updateResourceBindings(const DxvkBindingLayoutObjects* layout);
|
|
|
|
void updateComputeShaderResources();
|
|
void updateGraphicsShaderResources();
|
|
|
|
DxvkFramebufferInfo makeFramebufferInfo(
|
|
const DxvkRenderTargets& renderTargets);
|
|
|
|
void updateFramebuffer();
|
|
|
|
void applyRenderTargetLoadLayouts();
|
|
|
|
void applyRenderTargetStoreLayouts();
|
|
|
|
void transitionRenderTargetLayouts(
|
|
bool sharedOnly);
|
|
|
|
void transitionColorAttachment(
|
|
const DxvkAttachment& attachment,
|
|
VkImageLayout oldLayout);
|
|
|
|
void transitionDepthAttachment(
|
|
const DxvkAttachment& attachment,
|
|
VkImageLayout oldLayout);
|
|
|
|
void updateRenderTargetLayouts(
|
|
const DxvkFramebufferInfo& newFb,
|
|
const DxvkFramebufferInfo& oldFb);
|
|
|
|
void prepareImage(
|
|
const Rc<DxvkImage>& image,
|
|
const VkImageSubresourceRange& subresources,
|
|
bool flushClears = true);
|
|
|
|
DxvkDeferredClear* findDeferredClear(
|
|
const Rc<DxvkImage>& image,
|
|
const VkImageSubresourceRange& subresources);
|
|
|
|
bool updateIndexBufferBinding();
|
|
void updateVertexBufferBindings();
|
|
|
|
void updateTransformFeedbackBuffers();
|
|
void updateTransformFeedbackState();
|
|
|
|
void updateDynamicState();
|
|
|
|
template<VkPipelineBindPoint BindPoint>
|
|
void updatePushConstants();
|
|
|
|
bool commitComputeState();
|
|
|
|
template<bool Indexed, bool Indirect>
|
|
bool commitGraphicsState();
|
|
|
|
template<VkPipelineBindPoint BindPoint>
|
|
bool checkResourceHazards(
|
|
const DxvkBindingLayout& layout,
|
|
uint32_t setMask);
|
|
|
|
bool checkComputeHazards();
|
|
|
|
template<bool Indexed, bool Indirect>
|
|
bool checkGraphicsHazards();
|
|
|
|
template<VkPipelineBindPoint BindPoint>
|
|
bool checkBufferBarrier(
|
|
const DxvkBufferSlice& bufferSlice,
|
|
VkAccessFlags access);
|
|
|
|
template<VkPipelineBindPoint BindPoint>
|
|
bool checkBufferViewBarrier(
|
|
const Rc<DxvkBufferView>& bufferView,
|
|
VkAccessFlags access);
|
|
|
|
template<VkPipelineBindPoint BindPoint>
|
|
bool checkImageViewBarrier(
|
|
const Rc<DxvkImageView>& imageView,
|
|
VkAccessFlags access);
|
|
|
|
template<VkPipelineBindPoint BindPoint>
|
|
bool canIgnoreWawHazards() {
|
|
if (!m_barrierControl.test(DxvkBarrierControl::IgnoreWriteAfterWrite))
|
|
return false;
|
|
|
|
if (BindPoint == VK_PIPELINE_BIND_POINT_COMPUTE) {
|
|
VkPipelineStageFlags2 stageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT
|
|
| VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT;
|
|
return !m_execBarriers.hasPendingStages(~stageMask);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void emitMemoryBarrier(
|
|
VkPipelineStageFlags srcStages,
|
|
VkAccessFlags srcAccess,
|
|
VkPipelineStageFlags dstStages,
|
|
VkAccessFlags dstAccess);
|
|
|
|
void trackDrawBuffer();
|
|
|
|
bool tryInvalidateDeviceLocalBuffer(
|
|
const Rc<DxvkBuffer>& buffer,
|
|
VkDeviceSize copySize);
|
|
|
|
Rc<DxvkImageView> ensureImageViewCompatibility(
|
|
const Rc<DxvkImageView>& view,
|
|
VkImageUsageFlagBits usage);
|
|
|
|
void relocateResources(
|
|
size_t bufferCount,
|
|
const DxvkRelocateBufferInfo* bufferInfos,
|
|
size_t imageCount,
|
|
const DxvkRelocateImageInfo* imageInfos);
|
|
|
|
void relocateQueuedResources();
|
|
|
|
Rc<DxvkSampler> createBlitSampler(
|
|
VkFilter filter);
|
|
|
|
DxvkGraphicsPipeline* lookupGraphicsPipeline(
|
|
const DxvkGraphicsPipelineShaders& shaders);
|
|
|
|
DxvkComputePipeline* lookupComputePipeline(
|
|
const DxvkComputePipelineShaders& shaders);
|
|
|
|
Rc<DxvkBuffer> createZeroBuffer(
|
|
VkDeviceSize size);
|
|
|
|
void resizeDescriptorArrays(
|
|
uint32_t bindingCount);
|
|
|
|
void beginCurrentCommands();
|
|
|
|
void endCurrentCommands();
|
|
|
|
void splitCommands();
|
|
|
|
void discardRenderTarget(
|
|
const DxvkImage& image,
|
|
const VkImageSubresourceRange& subresources);
|
|
|
|
void flushImageLayoutTransitions(
|
|
DxvkCmdBuffer cmdBuffer);
|
|
|
|
void addImageLayoutTransition(
|
|
DxvkImage& image,
|
|
const VkImageSubresourceRange& subresources,
|
|
VkImageLayout srcLayout,
|
|
VkPipelineStageFlags2 srcStages,
|
|
VkAccessFlags2 srcAccess,
|
|
VkImageLayout dstLayout,
|
|
VkPipelineStageFlags2 dstStages,
|
|
VkAccessFlags2 dstAccess);
|
|
|
|
void addImageLayoutTransition(
|
|
DxvkImage& image,
|
|
const VkImageSubresourceRange& subresources,
|
|
VkImageLayout dstLayout,
|
|
VkPipelineStageFlags2 dstStages,
|
|
VkAccessFlags2 dstAccess,
|
|
bool discard);
|
|
|
|
void addImageInitTransition(
|
|
DxvkImage& image,
|
|
const VkImageSubresourceRange& subresources,
|
|
VkImageLayout dstLayout,
|
|
VkPipelineStageFlags2 dstStages,
|
|
VkAccessFlags2 dstAccess);
|
|
|
|
void accessMemory(
|
|
DxvkCmdBuffer cmdBuffer,
|
|
VkPipelineStageFlags2 srcStages,
|
|
VkAccessFlags2 srcAccess,
|
|
VkPipelineStageFlags2 dstStages,
|
|
VkAccessFlags2 dstAccess);
|
|
|
|
void accessImage(
|
|
DxvkCmdBuffer cmdBuffer,
|
|
DxvkImage& image,
|
|
const VkImageSubresourceRange& subresources,
|
|
VkImageLayout srcLayout,
|
|
VkPipelineStageFlags2 srcStages,
|
|
VkAccessFlags2 srcAccess);
|
|
|
|
void accessImage(
|
|
DxvkCmdBuffer cmdBuffer,
|
|
const DxvkImageView& imageView,
|
|
VkPipelineStageFlags2 srcStages,
|
|
VkAccessFlags2 srcAccess);
|
|
|
|
void accessImage(
|
|
DxvkCmdBuffer cmdBuffer,
|
|
DxvkImage& image,
|
|
const VkImageSubresourceRange& subresources,
|
|
VkImageLayout srcLayout,
|
|
VkPipelineStageFlags2 srcStages,
|
|
VkAccessFlags2 srcAccess,
|
|
VkImageLayout dstLayout,
|
|
VkPipelineStageFlags2 dstStages,
|
|
VkAccessFlags2 dstAccess);
|
|
|
|
void accessBuffer(
|
|
DxvkCmdBuffer cmdBuffer,
|
|
DxvkBuffer& buffer,
|
|
VkDeviceSize offset,
|
|
VkDeviceSize size,
|
|
VkPipelineStageFlags2 srcStages,
|
|
VkAccessFlags2 srcAccess);
|
|
|
|
void accessBuffer(
|
|
DxvkCmdBuffer cmdBuffer,
|
|
DxvkBuffer& buffer,
|
|
VkDeviceSize offset,
|
|
VkDeviceSize size,
|
|
VkPipelineStageFlags2 srcStages,
|
|
VkAccessFlags2 srcAccess,
|
|
VkPipelineStageFlags2 dstStages,
|
|
VkAccessFlags2 dstAccess);
|
|
|
|
void accessBuffer(
|
|
DxvkCmdBuffer cmdBuffer,
|
|
const DxvkBufferSlice& bufferSlice,
|
|
VkPipelineStageFlags2 srcStages,
|
|
VkAccessFlags2 srcAccess);
|
|
|
|
void accessBuffer(
|
|
DxvkCmdBuffer cmdBuffer,
|
|
const DxvkBufferSlice& bufferSlice,
|
|
VkPipelineStageFlags2 srcStages,
|
|
VkAccessFlags2 srcAccess,
|
|
VkPipelineStageFlags2 dstStages,
|
|
VkAccessFlags2 dstAccess);
|
|
|
|
void accessBuffer(
|
|
DxvkCmdBuffer cmdBuffer,
|
|
DxvkBufferView& bufferView,
|
|
VkPipelineStageFlags2 srcStages,
|
|
VkAccessFlags2 srcAccess);
|
|
|
|
void accessBuffer(
|
|
DxvkCmdBuffer cmdBuffer,
|
|
DxvkBufferView& bufferView,
|
|
VkPipelineStageFlags2 srcStages,
|
|
VkAccessFlags2 srcAccess,
|
|
VkPipelineStageFlags2 dstStages,
|
|
VkAccessFlags2 dstAccess);
|
|
|
|
void accessDrawBuffer(
|
|
VkDeviceSize offset,
|
|
uint32_t count,
|
|
uint32_t stride,
|
|
uint32_t size);
|
|
|
|
void accessDrawCountBuffer(
|
|
VkDeviceSize offset);
|
|
|
|
void flushPendingAccesses(
|
|
DxvkBuffer& buffer,
|
|
VkDeviceSize offset,
|
|
VkDeviceSize size,
|
|
DxvkAccess access);
|
|
|
|
void flushPendingAccesses(
|
|
DxvkBufferView& bufferView,
|
|
DxvkAccess access);
|
|
|
|
void flushPendingAccesses(
|
|
DxvkImage& image,
|
|
const VkImageSubresourceRange& subresources,
|
|
DxvkAccess access);
|
|
|
|
void flushPendingAccesses(
|
|
DxvkImageView& imageView,
|
|
DxvkAccess access);
|
|
|
|
void flushBarriers();
|
|
|
|
bool resourceHasAccess(
|
|
DxvkBuffer& buffer,
|
|
VkDeviceSize offset,
|
|
VkDeviceSize size,
|
|
DxvkAccess access);
|
|
|
|
bool resourceHasAccess(
|
|
DxvkBufferView& bufferView,
|
|
DxvkAccess access);
|
|
|
|
bool resourceHasAccess(
|
|
DxvkImage& image,
|
|
const VkImageSubresourceRange& subresources,
|
|
DxvkAccess access);
|
|
|
|
bool resourceHasAccess(
|
|
DxvkImageView& imageView,
|
|
DxvkAccess access);
|
|
|
|
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<VkPipelineBindPoint BindPoint, typename Pred>
|
|
bool checkResourceBarrier(
|
|
const Pred& pred,
|
|
VkAccessFlags access) {
|
|
// If we're only reading the resource, only pending
|
|
// writes matter for synchronization purposes.
|
|
bool hasPendingWrite = pred(DxvkAccess::Write);
|
|
|
|
if (!(access & vk::AccessWriteMask))
|
|
return hasPendingWrite;
|
|
|
|
if (hasPendingWrite) {
|
|
// If there is a write-after-write hazard and synchronization
|
|
// for those is not explicitly disabled, insert a barrier.
|
|
if (!canIgnoreWawHazards<BindPoint>())
|
|
return true;
|
|
|
|
// If write-after-write checking is disabled and we're on graphics,
|
|
// be aggressive about avoiding barriers and ignore any reads if we
|
|
// do find a write-after-write hazard. This essentially assumes that
|
|
// back-to-back read-modify-write operations are safe, but will still
|
|
// consider read-only or transform feedback operations as unsafe.
|
|
if (BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS)
|
|
return !(access & VK_ACCESS_SHADER_WRITE_BIT);
|
|
|
|
// On compute, if we are reading the resource, add a barrier.
|
|
if (access & vk::AccessReadMask)
|
|
return true;
|
|
}
|
|
|
|
// Check if there are any pending reads to avoid write-after-read issues.
|
|
return pred(DxvkAccess::Read);
|
|
}
|
|
|
|
void beginRenderPassDebugRegion();
|
|
|
|
void beginInternalDebugRegion(
|
|
const VkDebugUtilsLabelEXT& label);
|
|
|
|
void endInternalDebugRegion();
|
|
|
|
void beginActiveDebugRegions();
|
|
|
|
void endActiveDebugRegions();
|
|
|
|
static bool formatsAreCopyCompatible(
|
|
VkFormat imageFormat,
|
|
VkFormat bufferFormat);
|
|
|
|
static bool formatsAreResolveCompatible(
|
|
VkFormat resolveFormat,
|
|
VkFormat viewFormat);
|
|
|
|
static VkFormat sanitizeTexelBufferFormat(
|
|
VkFormat srcFormat);
|
|
|
|
};
|
|
|
|
}
|