mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-31 14:52:11 +01:00
[dxvk] Remove render pass and framebuffer objects
This commit is contained in:
parent
e3a63d4faa
commit
e8f3d9b040
@ -259,14 +259,6 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void cmdBeginRenderPass(
|
|
||||||
const VkRenderPassBeginInfo* pRenderPassBegin,
|
|
||||||
VkSubpassContents contents) {
|
|
||||||
m_vkd->vkCmdBeginRenderPass(m_execBuffer,
|
|
||||||
pRenderPassBegin, contents);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void cmdBeginTransformFeedback(
|
void cmdBeginTransformFeedback(
|
||||||
uint32_t firstBuffer,
|
uint32_t firstBuffer,
|
||||||
uint32_t bufferCount,
|
uint32_t bufferCount,
|
||||||
@ -600,11 +592,6 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void cmdEndRenderPass() {
|
|
||||||
m_vkd->vkCmdEndRenderPass(m_execBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void cmdEndTransformFeedback(
|
void cmdEndTransformFeedback(
|
||||||
uint32_t firstBuffer,
|
uint32_t firstBuffer,
|
||||||
uint32_t bufferCount,
|
uint32_t bufferCount,
|
||||||
|
@ -4420,8 +4420,7 @@ namespace dxvk {
|
|||||||
: DxvkContextFlag::GpDirtyStencilRef);
|
: DxvkContextFlag::GpDirtyStencilRef);
|
||||||
|
|
||||||
// Retrieve and bind actual Vulkan pipeline handle
|
// Retrieve and bind actual Vulkan pipeline handle
|
||||||
VkPipeline pipeline = m_state.gp.pipeline->getPipelineHandle(
|
VkPipeline pipeline = m_state.gp.pipeline->getPipelineHandle(m_state.gp.state);
|
||||||
m_state.gp.state, m_state.om.framebufferInfo.renderPass());
|
|
||||||
|
|
||||||
if (unlikely(!pipeline))
|
if (unlikely(!pipeline))
|
||||||
return false;
|
return false;
|
||||||
@ -4660,10 +4659,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxvkFramebufferInfo DxvkContext::makeFramebufferInfo(
|
DxvkFramebufferInfo DxvkContext::makeFramebufferInfo(
|
||||||
const DxvkRenderTargets& renderTargets) {
|
const DxvkRenderTargets& renderTargets) {
|
||||||
auto renderPassFormat = DxvkFramebufferInfo::getRenderPassFormat(renderTargets);
|
return DxvkFramebufferInfo(renderTargets, m_device->getDefaultFramebufferSize());
|
||||||
auto renderPassObject = m_common->renderPassPool().getRenderPass(renderPassFormat);
|
|
||||||
|
|
||||||
return DxvkFramebufferInfo(renderTargets, m_device->getDefaultFramebufferSize(), renderPassObject);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -5527,18 +5523,6 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Rc<DxvkFramebuffer> DxvkContext::lookupFramebuffer(
|
|
||||||
const DxvkFramebufferInfo& framebufferInfo) {
|
|
||||||
DxvkFramebufferKey key = framebufferInfo.key();
|
|
||||||
size_t idx = key.hash() % m_framebufferCache.size();
|
|
||||||
|
|
||||||
if (m_framebufferCache[idx] == nullptr || !m_framebufferCache[idx]->key().eq(key))
|
|
||||||
m_framebufferCache[idx] = m_device->createFramebuffer(framebufferInfo);
|
|
||||||
|
|
||||||
return m_framebufferCache[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Rc<DxvkBuffer> DxvkContext::createZeroBuffer(
|
Rc<DxvkBuffer> DxvkContext::createZeroBuffer(
|
||||||
VkDeviceSize size) {
|
VkDeviceSize size) {
|
||||||
if (m_zeroBuffer != nullptr && m_zeroBuffer->info().size >= size)
|
if (m_zeroBuffer != nullptr && m_zeroBuffer->info().size >= size)
|
||||||
|
@ -1156,7 +1156,6 @@ namespace dxvk {
|
|||||||
std::array<DxvkShaderResourceSlot, MaxNumResourceSlots> m_rc;
|
std::array<DxvkShaderResourceSlot, MaxNumResourceSlots> m_rc;
|
||||||
std::array<DxvkGraphicsPipeline*, 4096> m_gpLookupCache = { };
|
std::array<DxvkGraphicsPipeline*, 4096> m_gpLookupCache = { };
|
||||||
std::array<DxvkComputePipeline*, 256> m_cpLookupCache = { };
|
std::array<DxvkComputePipeline*, 256> m_cpLookupCache = { };
|
||||||
std::array<Rc<DxvkFramebuffer>, 512> m_framebufferCache = { };
|
|
||||||
|
|
||||||
void blitImageFb(
|
void blitImageFb(
|
||||||
const Rc<DxvkImage>& dstImage,
|
const Rc<DxvkImage>& dstImage,
|
||||||
@ -1411,9 +1410,6 @@ namespace dxvk {
|
|||||||
DxvkComputePipeline* lookupComputePipeline(
|
DxvkComputePipeline* lookupComputePipeline(
|
||||||
const DxvkComputePipelineShaders& shaders);
|
const DxvkComputePipelineShaders& shaders);
|
||||||
|
|
||||||
Rc<DxvkFramebuffer> lookupFramebuffer(
|
|
||||||
const DxvkFramebufferInfo& framebufferInfo);
|
|
||||||
|
|
||||||
Rc<DxvkBuffer> createZeroBuffer(
|
Rc<DxvkBuffer> createZeroBuffer(
|
||||||
VkDeviceSize size);
|
VkDeviceSize size);
|
||||||
|
|
||||||
|
@ -102,12 +102,6 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Rc<DxvkFramebuffer> DxvkDevice::createFramebuffer(
|
|
||||||
const DxvkFramebufferInfo& info) {
|
|
||||||
return new DxvkFramebuffer(m_vkd, info);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Rc<DxvkBuffer> DxvkDevice::createBuffer(
|
Rc<DxvkBuffer> DxvkDevice::createBuffer(
|
||||||
const DxvkBufferCreateInfo& createInfo,
|
const DxvkBufferCreateInfo& createInfo,
|
||||||
VkMemoryPropertyFlags memoryType) {
|
VkMemoryPropertyFlags memoryType) {
|
||||||
|
@ -258,15 +258,6 @@ namespace dxvk {
|
|||||||
VkQueryControlFlags flags,
|
VkQueryControlFlags flags,
|
||||||
uint32_t index);
|
uint32_t index);
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Creates framebuffer for a set of render targets
|
|
||||||
*
|
|
||||||
* \param [in] info Framebuffer info
|
|
||||||
* \returns The framebuffer object
|
|
||||||
*/
|
|
||||||
Rc<DxvkFramebuffer> createFramebuffer(
|
|
||||||
const DxvkFramebufferInfo& info);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Creates a buffer object
|
* \brief Creates a buffer object
|
||||||
*
|
*
|
||||||
|
@ -9,11 +9,9 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxvkFramebufferInfo::DxvkFramebufferInfo(
|
DxvkFramebufferInfo::DxvkFramebufferInfo(
|
||||||
const DxvkRenderTargets& renderTargets,
|
const DxvkRenderTargets& renderTargets,
|
||||||
const DxvkFramebufferSize& defaultSize,
|
const DxvkFramebufferSize& defaultSize)
|
||||||
DxvkRenderPass* renderPass)
|
|
||||||
: m_renderTargets (renderTargets),
|
: m_renderTargets (renderTargets),
|
||||||
m_renderSize (computeRenderSize(defaultSize)),
|
m_renderSize (computeRenderSize(defaultSize)) {
|
||||||
m_renderPass (renderPass) {
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
||||||
if (m_renderTargets.color[i].view != nullptr) {
|
if (m_renderTargets.color[i].view != nullptr) {
|
||||||
@ -70,24 +68,6 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DxvkFramebufferKey DxvkFramebufferInfo::key() const {
|
|
||||||
DxvkFramebufferKey result = { };
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
|
||||||
if (m_renderTargets.color[i].view != nullptr)
|
|
||||||
result.colorViews[i] = m_renderTargets.color[i].view->cookie();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_renderTargets.depth.view != nullptr)
|
|
||||||
result.depthView = m_renderTargets.depth.view->cookie();
|
|
||||||
|
|
||||||
if (result.renderPass)
|
|
||||||
result.renderPass = m_renderPass->getDefaultHandle();
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DxvkRtInfo DxvkFramebufferInfo::getRtInfo() const {
|
DxvkRtInfo DxvkFramebufferInfo::getRtInfo() const {
|
||||||
VkFormat depthStencilFormat = VK_FORMAT_UNDEFINED;
|
VkFormat depthStencilFormat = VK_FORMAT_UNDEFINED;
|
||||||
VkImageAspectFlags depthStencilReadOnlyAspects = 0;
|
VkImageAspectFlags depthStencilReadOnlyAspects = 0;
|
||||||
@ -109,27 +89,6 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DxvkRenderPassFormat DxvkFramebufferInfo::getRenderPassFormat(const DxvkRenderTargets& renderTargets) {
|
|
||||||
DxvkRenderPassFormat format;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
|
||||||
if (renderTargets.color[i].view != nullptr) {
|
|
||||||
format.sampleCount = renderTargets.color[i].view->imageInfo().sampleCount;
|
|
||||||
format.color[i].format = renderTargets.color[i].view->info().format;
|
|
||||||
format.color[i].layout = renderTargets.color[i].layout;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (renderTargets.depth.view != nullptr) {
|
|
||||||
format.sampleCount = renderTargets.depth.view->imageInfo().sampleCount;
|
|
||||||
format.depth.format = renderTargets.depth.view->info().format;
|
|
||||||
format.depth.layout = renderTargets.depth.layout;
|
|
||||||
}
|
|
||||||
|
|
||||||
return format;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DxvkFramebufferSize DxvkFramebufferInfo::computeRenderSize(
|
DxvkFramebufferSize DxvkFramebufferInfo::computeRenderSize(
|
||||||
const DxvkFramebufferSize& defaultSize) const {
|
const DxvkFramebufferSize& defaultSize) const {
|
||||||
// Some games bind render targets of a different size and
|
// Some games bind render targets of a different size and
|
||||||
@ -163,40 +122,4 @@ namespace dxvk {
|
|||||||
return DxvkFramebufferSize { extent.width, extent.height, layers };
|
return DxvkFramebufferSize { extent.width, extent.height, layers };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DxvkFramebuffer::DxvkFramebuffer(
|
|
||||||
const Rc<vk::DeviceFn>& vkd,
|
|
||||||
const DxvkFramebufferInfo& info)
|
|
||||||
: m_vkd(vkd), m_key(info.key()) {
|
|
||||||
std::array<VkImageView, MaxNumRenderTargets + 1> views;
|
|
||||||
uint32_t attachmentCount = 0;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
|
||||||
if (info.getColorTarget(i).view != nullptr)
|
|
||||||
views[attachmentCount++] = info.getColorTarget(i).view->handle();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info.getDepthTarget().view != nullptr)
|
|
||||||
views[attachmentCount++] = info.getDepthTarget().view->handle();
|
|
||||||
|
|
||||||
VkFramebufferCreateInfo fbInfo;
|
|
||||||
fbInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
|
||||||
fbInfo.pNext = nullptr;
|
|
||||||
fbInfo.flags = 0;
|
|
||||||
fbInfo.renderPass = info.renderPass()->getDefaultHandle();
|
|
||||||
fbInfo.attachmentCount = attachmentCount;
|
|
||||||
fbInfo.pAttachments = views.data();
|
|
||||||
fbInfo.width = info.size().width;
|
|
||||||
fbInfo.height = info.size().height;
|
|
||||||
fbInfo.layers = info.size().layers;
|
|
||||||
|
|
||||||
if (m_vkd->vkCreateFramebuffer(m_vkd->device(), &fbInfo, nullptr, &m_handle) != VK_SUCCESS)
|
|
||||||
Logger::err("DxvkFramebuffer: Failed to create framebuffer object");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DxvkFramebuffer::~DxvkFramebuffer() {
|
|
||||||
m_vkd->vkDestroyFramebuffer(m_vkd->device(), m_handle, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -94,8 +94,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxvkFramebufferInfo(
|
DxvkFramebufferInfo(
|
||||||
const DxvkRenderTargets& renderTargets,
|
const DxvkRenderTargets& renderTargets,
|
||||||
const DxvkFramebufferSize& defaultSize,
|
const DxvkFramebufferSize& defaultSize);
|
||||||
DxvkRenderPass* renderPass);
|
|
||||||
|
|
||||||
~DxvkFramebufferInfo();
|
~DxvkFramebufferInfo();
|
||||||
|
|
||||||
@ -115,14 +114,6 @@ namespace dxvk {
|
|||||||
return m_renderSize;
|
return m_renderSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Render pass
|
|
||||||
* \returns Render pass
|
|
||||||
*/
|
|
||||||
DxvkRenderPass* renderPass() const {
|
|
||||||
return m_renderPass;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Framebuffer sample count
|
* \brief Framebuffer sample count
|
||||||
*
|
*
|
||||||
@ -220,35 +211,17 @@ namespace dxvk {
|
|||||||
*/
|
*/
|
||||||
bool isWritable(uint32_t attachmentIndex, VkImageAspectFlags aspects) const;
|
bool isWritable(uint32_t attachmentIndex, VkImageAspectFlags aspects) const;
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Generates framebuffer key
|
|
||||||
* \returns Framebuffer key
|
|
||||||
*/
|
|
||||||
DxvkFramebufferKey key() const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Generates render target state
|
* \brief Generates render target state
|
||||||
* \returns Render target state info
|
* \returns Render target state info
|
||||||
*/
|
*/
|
||||||
DxvkRtInfo getRtInfo() const;
|
DxvkRtInfo getRtInfo() const;
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Generatess render pass format
|
|
||||||
*
|
|
||||||
* This render pass format can be used to
|
|
||||||
* look up a compatible render pass.
|
|
||||||
* \param [in] renderTargets Render targets
|
|
||||||
* \returns The render pass format
|
|
||||||
*/
|
|
||||||
static DxvkRenderPassFormat getRenderPassFormat(
|
|
||||||
const DxvkRenderTargets& renderTargets);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
DxvkRenderTargets m_renderTargets;
|
DxvkRenderTargets m_renderTargets;
|
||||||
DxvkFramebufferSize m_renderSize = { 0u, 0u, 0u };
|
DxvkFramebufferSize m_renderSize = { 0u, 0u, 0u };
|
||||||
VkSampleCountFlags m_sampleCount = 0;
|
VkSampleCountFlags m_sampleCount = 0;
|
||||||
DxvkRenderPass* m_renderPass;
|
|
||||||
|
|
||||||
uint32_t m_attachmentCount = 0;
|
uint32_t m_attachmentCount = 0;
|
||||||
std::array<int32_t, MaxNumRenderTargets + 1> m_attachments;
|
std::array<int32_t, MaxNumRenderTargets + 1> m_attachments;
|
||||||
@ -260,47 +233,5 @@ namespace dxvk {
|
|||||||
const Rc<DxvkImageView>& renderTarget) const;
|
const Rc<DxvkImageView>& renderTarget) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Framebuffer
|
|
||||||
*
|
|
||||||
* A framebuffer either stores a set of image views
|
|
||||||
* that will be used as render targets, or in case
|
|
||||||
* no render targets are attached, fixed dimensions.
|
|
||||||
*/
|
|
||||||
class DxvkFramebuffer : public DxvkResource {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
DxvkFramebuffer(
|
|
||||||
const Rc<vk::DeviceFn>& vkd,
|
|
||||||
const DxvkFramebufferInfo& info);
|
|
||||||
|
|
||||||
~DxvkFramebuffer();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Framebuffer handle
|
|
||||||
* \returns Framebuffer handle
|
|
||||||
*/
|
|
||||||
VkFramebuffer handle() const {
|
|
||||||
return m_handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Framebuffer key
|
|
||||||
*/
|
|
||||||
const DxvkFramebufferKey& key() const {
|
|
||||||
return m_key;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
Rc<vk::DeviceFn> m_vkd;
|
|
||||||
VkFramebuffer m_handle;
|
|
||||||
DxvkFramebufferKey m_key;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
@ -49,8 +49,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
VkPipeline DxvkGraphicsPipeline::getPipelineHandle(
|
VkPipeline DxvkGraphicsPipeline::getPipelineHandle(
|
||||||
const DxvkGraphicsPipelineStateInfo& state,
|
const DxvkGraphicsPipelineStateInfo& state) {
|
||||||
const DxvkRenderPass* renderPass) {
|
|
||||||
DxvkGraphicsPipelineInstance* instance = this->findInstance(state);
|
DxvkGraphicsPipelineInstance* instance = this->findInstance(state);
|
||||||
|
|
||||||
if (unlikely(!instance)) {
|
if (unlikely(!instance)) {
|
||||||
|
@ -106,7 +106,6 @@ namespace dxvk {
|
|||||||
* \brief Checks for matching pipeline state
|
* \brief Checks for matching pipeline state
|
||||||
*
|
*
|
||||||
* \param [in] stateVector Graphics pipeline state
|
* \param [in] stateVector Graphics pipeline state
|
||||||
* \param [in] renderPass Render pass handle
|
|
||||||
* \returns \c true if the specialization is compatible
|
* \returns \c true if the specialization is compatible
|
||||||
*/
|
*/
|
||||||
bool isCompatible(
|
bool isCompatible(
|
||||||
@ -193,12 +192,10 @@ namespace dxvk {
|
|||||||
* Retrieves a pipeline handle for the given pipeline
|
* Retrieves a pipeline handle for the given pipeline
|
||||||
* state. If necessary, a new pipeline will be created.
|
* state. If necessary, a new pipeline will be created.
|
||||||
* \param [in] state Pipeline state vector
|
* \param [in] state Pipeline state vector
|
||||||
* \param [in] renderPass The render pass
|
|
||||||
* \returns Pipeline handle
|
* \returns Pipeline handle
|
||||||
*/
|
*/
|
||||||
VkPipeline getPipelineHandle(
|
VkPipeline getPipelineHandle(
|
||||||
const DxvkGraphicsPipelineStateInfo& state,
|
const DxvkGraphicsPipelineStateInfo& state);
|
||||||
const DxvkRenderPass* renderPass);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Compiles a pipeline
|
* \brief Compiles a pipeline
|
||||||
|
@ -24,8 +24,7 @@ namespace dxvk {
|
|||||||
DxvkObjects(DxvkDevice* device)
|
DxvkObjects(DxvkDevice* device)
|
||||||
: m_device (device),
|
: m_device (device),
|
||||||
m_memoryManager (device),
|
m_memoryManager (device),
|
||||||
m_renderPassPool (device),
|
m_pipelineManager (device),
|
||||||
m_pipelineManager (device, &m_renderPassPool),
|
|
||||||
m_eventPool (device),
|
m_eventPool (device),
|
||||||
m_queryPool (device),
|
m_queryPool (device),
|
||||||
m_dummyResources (device) {
|
m_dummyResources (device) {
|
||||||
@ -36,10 +35,6 @@ namespace dxvk {
|
|||||||
return m_memoryManager;
|
return m_memoryManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
DxvkRenderPassPool& renderPassPool() {
|
|
||||||
return m_renderPassPool;
|
|
||||||
}
|
|
||||||
|
|
||||||
DxvkPipelineManager& pipelineManager() {
|
DxvkPipelineManager& pipelineManager() {
|
||||||
return m_pipelineManager;
|
return m_pipelineManager;
|
||||||
}
|
}
|
||||||
@ -81,7 +76,6 @@ namespace dxvk {
|
|||||||
DxvkDevice* m_device;
|
DxvkDevice* m_device;
|
||||||
|
|
||||||
DxvkMemoryAllocator m_memoryManager;
|
DxvkMemoryAllocator m_memoryManager;
|
||||||
DxvkRenderPassPool m_renderPassPool;
|
|
||||||
DxvkPipelineManager m_pipelineManager;
|
DxvkPipelineManager m_pipelineManager;
|
||||||
|
|
||||||
DxvkGpuEventPool m_eventPool;
|
DxvkGpuEventPool m_eventPool;
|
||||||
|
@ -5,14 +5,13 @@
|
|||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
DxvkPipelineManager::DxvkPipelineManager(
|
DxvkPipelineManager::DxvkPipelineManager(
|
||||||
DxvkDevice* device,
|
DxvkDevice* device)
|
||||||
DxvkRenderPassPool* passManager)
|
|
||||||
: m_device (device),
|
: m_device (device),
|
||||||
m_cache (new DxvkPipelineCache(device->vkd())) {
|
m_cache (new DxvkPipelineCache(device->vkd())) {
|
||||||
std::string useStateCache = env::getEnvVar("DXVK_STATE_CACHE");
|
std::string useStateCache = env::getEnvVar("DXVK_STATE_CACHE");
|
||||||
|
|
||||||
if (useStateCache != "0" && device->config().enableStateCache)
|
if (useStateCache != "0" && device->config().enableStateCache)
|
||||||
m_stateCache = new DxvkStateCache(device, this, passManager);
|
m_stateCache = new DxvkStateCache(device, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,8 +38,7 @@ namespace dxvk {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
DxvkPipelineManager(
|
DxvkPipelineManager(
|
||||||
DxvkDevice* device,
|
DxvkDevice* device);
|
||||||
DxvkRenderPassPool* passManager);
|
|
||||||
|
|
||||||
~DxvkPipelineManager();
|
~DxvkPipelineManager();
|
||||||
|
|
||||||
|
@ -1,332 +0,0 @@
|
|||||||
#include <algorithm>
|
|
||||||
|
|
||||||
#include "dxvk_device.h"
|
|
||||||
#include "dxvk_renderpass.h"
|
|
||||||
|
|
||||||
namespace dxvk {
|
|
||||||
|
|
||||||
bool DxvkRenderPassFormat::eq(const DxvkRenderPassFormat& fmt) const {
|
|
||||||
bool eq = sampleCount == fmt.sampleCount;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < MaxNumRenderTargets && eq; i++) {
|
|
||||||
eq &= color[i].format == fmt.color[i].format
|
|
||||||
&& color[i].layout == fmt.color[i].layout;
|
|
||||||
}
|
|
||||||
|
|
||||||
eq &= depth.format == fmt.depth.format
|
|
||||||
&& depth.layout == fmt.depth.layout;
|
|
||||||
|
|
||||||
return eq;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t DxvkRenderPassFormat::hash() const {
|
|
||||||
DxvkHashState state;
|
|
||||||
state.add(uint32_t(sampleCount));
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
|
||||||
state.add(uint32_t(color[i].format));
|
|
||||||
state.add(uint32_t(color[i].layout));
|
|
||||||
}
|
|
||||||
|
|
||||||
state.add(uint32_t(depth.format));
|
|
||||||
state.add(uint32_t(depth.layout));
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DxvkRenderPass::DxvkRenderPass(
|
|
||||||
const Rc<vk::DeviceFn>& vkd,
|
|
||||||
const DxvkRenderPassFormat& fmt)
|
|
||||||
: m_vkd(vkd), m_format(fmt),
|
|
||||||
m_default(createRenderPass(DxvkRenderPassOps())) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DxvkRenderPass::~DxvkRenderPass() {
|
|
||||||
m_vkd->vkDestroyRenderPass(m_vkd->device(), m_default, nullptr);
|
|
||||||
|
|
||||||
for (const auto& i : m_instances) {
|
|
||||||
m_vkd->vkDestroyRenderPass(
|
|
||||||
m_vkd->device(), i.handle, nullptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool DxvkRenderPass::hasCompatibleFormat(const DxvkRenderPassFormat& fmt) const {
|
|
||||||
return m_format.eq(fmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VkRenderPass DxvkRenderPass::getHandle(const DxvkRenderPassOps& ops) {
|
|
||||||
VkRenderPass handle = this->findHandle(ops);
|
|
||||||
|
|
||||||
if (unlikely(!handle)) {
|
|
||||||
std::lock_guard<dxvk::mutex> lock(m_mutex);
|
|
||||||
handle = this->findHandle(ops);
|
|
||||||
|
|
||||||
if (!handle) {
|
|
||||||
handle = this->createRenderPass(ops);
|
|
||||||
m_instances.insert({ ops, handle });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VkRenderPass DxvkRenderPass::findHandle(const DxvkRenderPassOps& ops) {
|
|
||||||
for (const auto& i : m_instances) {
|
|
||||||
if (compareOps(i.ops, ops))
|
|
||||||
return i.handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
return VK_NULL_HANDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VkRenderPass DxvkRenderPass::createRenderPass(const DxvkRenderPassOps& ops) {
|
|
||||||
std::vector<VkAttachmentDescription> attachments;
|
|
||||||
|
|
||||||
VkAttachmentReference depthRef;
|
|
||||||
std::array<VkAttachmentReference, MaxNumRenderTargets> colorRef;
|
|
||||||
|
|
||||||
// Render passes may not require the previous
|
|
||||||
// contents of the attachments to be preserved.
|
|
||||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
|
||||||
if (m_format.color[i].format != VK_FORMAT_UNDEFINED) {
|
|
||||||
VkAttachmentDescription desc;
|
|
||||||
desc.flags = 0;
|
|
||||||
desc.format = m_format.color[i].format;
|
|
||||||
desc.samples = m_format.sampleCount;
|
|
||||||
desc.loadOp = ops.colorOps[i].loadOp;
|
|
||||||
desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
|
||||||
desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
|
||||||
desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
|
||||||
desc.initialLayout = ops.colorOps[i].loadLayout;
|
|
||||||
desc.finalLayout = ops.colorOps[i].storeLayout;
|
|
||||||
|
|
||||||
colorRef[i].attachment = attachments.size();
|
|
||||||
colorRef[i].layout = m_format.color[i].layout;
|
|
||||||
|
|
||||||
attachments.push_back(desc);
|
|
||||||
} else {
|
|
||||||
colorRef[i].attachment = VK_ATTACHMENT_UNUSED;
|
|
||||||
colorRef[i].layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_format.depth.format != VK_FORMAT_UNDEFINED) {
|
|
||||||
VkAttachmentDescription desc;
|
|
||||||
desc.flags = 0;
|
|
||||||
desc.format = m_format.depth.format;
|
|
||||||
desc.samples = m_format.sampleCount;
|
|
||||||
desc.loadOp = ops.depthOps.loadOpD;
|
|
||||||
desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
|
||||||
desc.stencilLoadOp = ops.depthOps.loadOpS;
|
|
||||||
desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
|
|
||||||
desc.initialLayout = ops.depthOps.loadLayout;
|
|
||||||
desc.finalLayout = ops.depthOps.storeLayout;
|
|
||||||
|
|
||||||
depthRef.attachment = attachments.size();
|
|
||||||
depthRef.layout = m_format.depth.layout;
|
|
||||||
|
|
||||||
attachments.push_back(desc);
|
|
||||||
} else {
|
|
||||||
depthRef.attachment = VK_ATTACHMENT_UNUSED;
|
|
||||||
depthRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkSubpassDescription subpass;
|
|
||||||
subpass.flags = 0;
|
|
||||||
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
|
||||||
subpass.inputAttachmentCount = 0;
|
|
||||||
subpass.pInputAttachments = nullptr;
|
|
||||||
subpass.colorAttachmentCount = colorRef.size();
|
|
||||||
subpass.pColorAttachments = colorRef.data();
|
|
||||||
subpass.pResolveAttachments = nullptr;
|
|
||||||
subpass.pDepthStencilAttachment = &depthRef;
|
|
||||||
subpass.preserveAttachmentCount = 0;
|
|
||||||
subpass.pPreserveAttachments = nullptr;
|
|
||||||
|
|
||||||
if (m_format.depth.format == VK_FORMAT_UNDEFINED)
|
|
||||||
subpass.pDepthStencilAttachment = nullptr;
|
|
||||||
|
|
||||||
std::array<VkSubpassDependency, 3> subpassDeps;
|
|
||||||
uint32_t subpassDepCount = 0;
|
|
||||||
|
|
||||||
VkPipelineStageFlags renderStages = 0;
|
|
||||||
VkAccessFlags renderAccess = 0;
|
|
||||||
|
|
||||||
if (m_format.depth.format) {
|
|
||||||
renderStages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
|
|
||||||
| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
|
|
||||||
|
|
||||||
VkImageAspectFlags loadAspects = 0;
|
|
||||||
|
|
||||||
if (ops.depthOps.loadOpD == VK_ATTACHMENT_LOAD_OP_LOAD)
|
|
||||||
loadAspects |= VK_IMAGE_ASPECT_DEPTH_BIT;
|
|
||||||
if (ops.depthOps.loadOpS == VK_ATTACHMENT_LOAD_OP_LOAD)
|
|
||||||
loadAspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
|
||||||
|
|
||||||
if (loadAspects & imageFormatInfo(m_format.depth.format)->aspectMask)
|
|
||||||
renderAccess |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
|
|
||||||
|
|
||||||
if (m_format.depth.layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL)
|
|
||||||
renderAccess |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
|
||||||
|
|
||||||
if (m_format.depth.layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
|
|
||||||
renderStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
|
||||||
renderAccess |= VK_ACCESS_SHADER_READ_BIT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
|
||||||
if (!m_format.color[i].format)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
renderStages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
|
||||||
renderAccess |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
|
||||||
|
|
||||||
if (ops.colorOps[i].loadOp == VK_ATTACHMENT_LOAD_OP_LOAD)
|
|
||||||
renderAccess |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (renderStages) {
|
|
||||||
subpassDeps[subpassDepCount++] = {
|
|
||||||
VK_SUBPASS_EXTERNAL, 0,
|
|
||||||
renderStages, renderStages,
|
|
||||||
0, renderAccess };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ops.barrier.srcStages & (
|
|
||||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
|
|
||||||
VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT |
|
|
||||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT)) {
|
|
||||||
subpassDeps[subpassDepCount++] = { 0, 0,
|
|
||||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
|
||||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
|
||||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
|
||||||
VK_ACCESS_SHADER_READ_BIT,
|
|
||||||
VK_DEPENDENCY_BY_REGION_BIT };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ops.barrier.srcStages && ops.barrier.dstStages) {
|
|
||||||
subpassDeps[subpassDepCount++] = {
|
|
||||||
0, VK_SUBPASS_EXTERNAL,
|
|
||||||
ops.barrier.srcStages,
|
|
||||||
ops.barrier.dstStages,
|
|
||||||
ops.barrier.srcAccess,
|
|
||||||
ops.barrier.dstAccess, 0 };
|
|
||||||
}
|
|
||||||
|
|
||||||
VkRenderPassCreateInfo info;
|
|
||||||
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
|
||||||
info.pNext = nullptr;
|
|
||||||
info.flags = 0;
|
|
||||||
info.attachmentCount = attachments.size();
|
|
||||||
info.pAttachments = attachments.data();
|
|
||||||
info.subpassCount = 1;
|
|
||||||
info.pSubpasses = &subpass;
|
|
||||||
info.dependencyCount = subpassDepCount;
|
|
||||||
info.pDependencies = subpassDepCount ? subpassDeps.data() : nullptr;
|
|
||||||
|
|
||||||
VkRenderPass renderPass = VK_NULL_HANDLE;
|
|
||||||
|
|
||||||
if (m_vkd->vkCreateRenderPass(m_vkd->device(), &info, nullptr, &renderPass) != VK_SUCCESS) {
|
|
||||||
Logger::err("DxvkRenderPass: Failed to create render pass object");
|
|
||||||
return VK_NULL_HANDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return renderPass;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool DxvkRenderPass::compareOps(
|
|
||||||
const DxvkRenderPassOps& a,
|
|
||||||
const DxvkRenderPassOps& b) {
|
|
||||||
bool eq = a.barrier.srcStages == b.barrier.srcStages
|
|
||||||
&& a.barrier.srcAccess == b.barrier.srcAccess
|
|
||||||
&& a.barrier.dstStages == b.barrier.dstStages
|
|
||||||
&& a.barrier.dstAccess == b.barrier.dstAccess;
|
|
||||||
|
|
||||||
if (eq) {
|
|
||||||
eq &= a.depthOps.loadOpD == b.depthOps.loadOpD
|
|
||||||
&& a.depthOps.loadOpS == b.depthOps.loadOpS
|
|
||||||
&& a.depthOps.loadLayout == b.depthOps.loadLayout
|
|
||||||
&& a.depthOps.storeLayout == b.depthOps.storeLayout;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < MaxNumRenderTargets && eq; i++) {
|
|
||||||
eq &= a.colorOps[i].loadOp == b.colorOps[i].loadOp
|
|
||||||
&& a.colorOps[i].loadLayout == b.colorOps[i].loadLayout
|
|
||||||
&& a.colorOps[i].storeLayout == b.colorOps[i].storeLayout;
|
|
||||||
}
|
|
||||||
|
|
||||||
return eq;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DxvkRenderPassPool::DxvkRenderPassPool(const DxvkDevice* device)
|
|
||||||
: m_device(device) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DxvkRenderPassPool::~DxvkRenderPassPool() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DxvkRenderPass* DxvkRenderPassPool::getRenderPass(const DxvkRenderPassFormat& fmt) {
|
|
||||||
std::lock_guard<dxvk::mutex> lock(m_mutex);
|
|
||||||
|
|
||||||
auto entry = m_renderPasses.find(fmt);
|
|
||||||
if (entry != m_renderPasses.end())
|
|
||||||
return &entry->second;
|
|
||||||
|
|
||||||
auto result = m_renderPasses.emplace(std::piecewise_construct,
|
|
||||||
std::tuple(fmt),
|
|
||||||
std::tuple(m_device->vkd(), fmt));
|
|
||||||
return &result.first->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool DxvkRenderPassPool::validateRenderPassFormat(
|
|
||||||
const DxvkRenderPassFormat& fmt) {
|
|
||||||
Rc<DxvkAdapter> adapter = m_device->adapter();
|
|
||||||
|
|
||||||
if (fmt.depth.format) {
|
|
||||||
VkFormatProperties depthInfo = adapter->formatProperties(fmt.depth.format);
|
|
||||||
VkFormatFeatureFlags depthFlags = depthInfo.linearTilingFeatures | depthInfo.optimalTilingFeatures;
|
|
||||||
|
|
||||||
if (!(depthFlags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (fmt.depth.layout != VK_IMAGE_LAYOUT_GENERAL
|
|
||||||
&& fmt.depth.layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
|
|
||||||
&& fmt.depth.layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL
|
|
||||||
&& fmt.depth.layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
|
|
||||||
&& fmt.depth.layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
|
||||||
if (fmt.color[i].format) {
|
|
||||||
VkFormatProperties colorInfo = adapter->formatProperties(fmt.color[i].format);
|
|
||||||
VkFormatFeatureFlags colorFlags = colorInfo.linearTilingFeatures | colorInfo.optimalTilingFeatures;
|
|
||||||
|
|
||||||
if (!(colorFlags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (fmt.color[i].layout != VK_IMAGE_LAYOUT_GENERAL
|
|
||||||
&& fmt.color[i].layout != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -14,35 +14,6 @@ namespace dxvk {
|
|||||||
|
|
||||||
class DxvkDevice;
|
class DxvkDevice;
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Format and layout for a render target
|
|
||||||
*
|
|
||||||
* Stores the image format of the attachment and
|
|
||||||
* the image layout that is used while rendering.
|
|
||||||
*/
|
|
||||||
struct DxvkAttachmentFormat {
|
|
||||||
VkFormat format = VK_FORMAT_UNDEFINED;
|
|
||||||
VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Render pass format
|
|
||||||
*
|
|
||||||
* Stores the attachment formats for all depth and
|
|
||||||
* color attachments, as well as the sample count.
|
|
||||||
*/
|
|
||||||
struct DxvkRenderPassFormat {
|
|
||||||
VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
|
|
||||||
DxvkAttachmentFormat depth;
|
|
||||||
DxvkAttachmentFormat color[MaxNumRenderTargets];
|
|
||||||
|
|
||||||
bool eq(const DxvkRenderPassFormat& fmt) const;
|
|
||||||
|
|
||||||
size_t hash() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Color attachment transitions
|
* \brief Color attachment transitions
|
||||||
*
|
*
|
||||||
@ -96,149 +67,5 @@ namespace dxvk {
|
|||||||
DxvkDepthAttachmentOps depthOps;
|
DxvkDepthAttachmentOps depthOps;
|
||||||
DxvkColorAttachmentOps colorOps[MaxNumRenderTargets];
|
DxvkColorAttachmentOps colorOps[MaxNumRenderTargets];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Render pass object
|
|
||||||
*
|
|
||||||
* Manages a set of compatible render passes, i.e.
|
|
||||||
* render passes which share the same format but
|
|
||||||
* may differ in their attachment operations.
|
|
||||||
*/
|
|
||||||
class DxvkRenderPass {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
DxvkRenderPass(
|
|
||||||
const Rc<vk::DeviceFn>& vkd,
|
|
||||||
const DxvkRenderPassFormat& fmt);
|
|
||||||
|
|
||||||
~DxvkRenderPass();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Retrieves render pass format
|
|
||||||
* \returns The render pass format
|
|
||||||
*/
|
|
||||||
DxvkRenderPassFormat format() const {
|
|
||||||
return m_format;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Checks whether a format is compatible
|
|
||||||
*
|
|
||||||
* Two render pass formats are considered compatible
|
|
||||||
* if all the relevant attachment formats match.
|
|
||||||
* \param [in] fmt The render pass format to check
|
|
||||||
* \returns \c true if this render pass is compatible.
|
|
||||||
*/
|
|
||||||
bool hasCompatibleFormat(
|
|
||||||
const DxvkRenderPassFormat& fmt) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Retrieves sample count
|
|
||||||
*
|
|
||||||
* If no sample count has been explicitly specitied,
|
|
||||||
* this will return \c VK_SAMPLE_COUNT_1_BIT.
|
|
||||||
* \returns Sample count
|
|
||||||
*/
|
|
||||||
VkSampleCountFlagBits getSampleCount() const {
|
|
||||||
return m_format.sampleCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Returns handle of default render pass
|
|
||||||
*
|
|
||||||
* The default render pass handle should be used to
|
|
||||||
* create pipelines and framebuffer objects. It can
|
|
||||||
* \e not be used for \c vkCmdBeginRenderPass calls.
|
|
||||||
* \returns The default render pass handle
|
|
||||||
*/
|
|
||||||
VkRenderPass getDefaultHandle() const {
|
|
||||||
return m_default;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Returns handle to a specialized render pass
|
|
||||||
*
|
|
||||||
* Returns a handle to a render pass with the given
|
|
||||||
* set of parameters. This should be used for calls
|
|
||||||
* to \c vkCmdBeginRenderPass.
|
|
||||||
* \param [in] ops Attachment ops
|
|
||||||
* \returns Render pass handle
|
|
||||||
*/
|
|
||||||
VkRenderPass getHandle(
|
|
||||||
const DxvkRenderPassOps& ops);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
struct Instance {
|
|
||||||
DxvkRenderPassOps ops;
|
|
||||||
VkRenderPass handle;
|
|
||||||
};
|
|
||||||
|
|
||||||
Rc<vk::DeviceFn> m_vkd;
|
|
||||||
DxvkRenderPassFormat m_format;
|
|
||||||
VkRenderPass m_default;
|
|
||||||
|
|
||||||
dxvk::mutex m_mutex;
|
|
||||||
sync::List<Instance> m_instances;
|
|
||||||
|
|
||||||
VkRenderPass findHandle(
|
|
||||||
const DxvkRenderPassOps& ops);
|
|
||||||
|
|
||||||
VkRenderPass createRenderPass(
|
|
||||||
const DxvkRenderPassOps& ops);
|
|
||||||
|
|
||||||
static bool compareOps(
|
|
||||||
const DxvkRenderPassOps& a,
|
|
||||||
const DxvkRenderPassOps& b);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Render pass pool
|
|
||||||
*
|
|
||||||
* Manages render pass objects. For each render
|
|
||||||
* pass format, a new render pass object will
|
|
||||||
* be created, but no two render pass objects
|
|
||||||
* will have the same format.
|
|
||||||
*/
|
|
||||||
class DxvkRenderPassPool {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
DxvkRenderPassPool(const DxvkDevice* device);
|
|
||||||
~DxvkRenderPassPool();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Retrieves a render pass object
|
|
||||||
*
|
|
||||||
* \param [in] fmt The render pass format
|
|
||||||
* \returns Matching render pass object
|
|
||||||
*/
|
|
||||||
DxvkRenderPass* getRenderPass(
|
|
||||||
const DxvkRenderPassFormat& fmt);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Validates render pass format
|
|
||||||
*
|
|
||||||
* \param [in] fmt The render pass format
|
|
||||||
* \returns \c true if the format is supported
|
|
||||||
*/
|
|
||||||
bool validateRenderPassFormat(
|
|
||||||
const DxvkRenderPassFormat& fmt);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
const DxvkDevice* m_device;
|
|
||||||
|
|
||||||
dxvk::mutex m_mutex;
|
|
||||||
std::unordered_map<
|
|
||||||
DxvkRenderPassFormat,
|
|
||||||
DxvkRenderPass,
|
|
||||||
DxvkHash, DxvkEq> m_renderPasses;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
@ -200,11 +200,9 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxvkStateCache::DxvkStateCache(
|
DxvkStateCache::DxvkStateCache(
|
||||||
DxvkDevice* device,
|
DxvkDevice* device,
|
||||||
DxvkPipelineManager* pipeManager,
|
DxvkPipelineManager* pipeManager)
|
||||||
DxvkRenderPassPool* passManager)
|
|
||||||
: m_device (device),
|
: m_device (device),
|
||||||
m_pipeManager (pipeManager),
|
m_pipeManager (pipeManager) {
|
||||||
m_passManager (passManager) {
|
|
||||||
bool newFile = !readCacheFile();
|
bool newFile = !readCacheFile();
|
||||||
|
|
||||||
if (newFile) {
|
if (newFile) {
|
||||||
|
@ -29,8 +29,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxvkStateCache(
|
DxvkStateCache(
|
||||||
DxvkDevice* device,
|
DxvkDevice* device,
|
||||||
DxvkPipelineManager* pipeManager,
|
DxvkPipelineManager* pipeManager);
|
||||||
DxvkRenderPassPool* passManager);
|
|
||||||
|
|
||||||
~DxvkStateCache();
|
~DxvkStateCache();
|
||||||
|
|
||||||
@ -94,7 +93,6 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxvkDevice* m_device;
|
DxvkDevice* m_device;
|
||||||
DxvkPipelineManager* m_pipeManager;
|
DxvkPipelineManager* m_pipeManager;
|
||||||
DxvkRenderPassPool* m_passManager;
|
|
||||||
|
|
||||||
std::vector<DxvkStateCacheEntry> m_entries;
|
std::vector<DxvkStateCacheEntry> m_entries;
|
||||||
std::atomic<bool> m_stopThreads = { false };
|
std::atomic<bool> m_stopThreads = { false };
|
||||||
|
@ -93,7 +93,6 @@ dxvk_src = files([
|
|||||||
'dxvk_pipelayout.cpp',
|
'dxvk_pipelayout.cpp',
|
||||||
'dxvk_pipemanager.cpp',
|
'dxvk_pipemanager.cpp',
|
||||||
'dxvk_queue.cpp',
|
'dxvk_queue.cpp',
|
||||||
'dxvk_renderpass.cpp',
|
|
||||||
'dxvk_resource.cpp',
|
'dxvk_resource.cpp',
|
||||||
'dxvk_sampler.cpp',
|
'dxvk_sampler.cpp',
|
||||||
'dxvk_shader.cpp',
|
'dxvk_shader.cpp',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user