mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-14 04:29:15 +01:00
[dxvk] Major refactoring of graphics pipeline state lookup in order to support more dynamic state
This commit is contained in:
parent
ade00add8d
commit
796c200e32
@ -561,7 +561,8 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
m_context->bindVertexBuffer(
|
||||
StartSlot + i, dxvkBinding);
|
||||
StartSlot + i, dxvkBinding,
|
||||
binding.stride);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
#include <cstring>
|
||||
|
||||
#include "dxvk_constant_state.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
@ -6,7 +6,7 @@ namespace dxvk {
|
||||
|
||||
DxvkContext::DxvkContext(const Rc<DxvkDevice>& device)
|
||||
: m_device(device) {
|
||||
|
||||
Logger::info(str::format(sizeof(DxvkGraphicsPipelineStateInfo)));
|
||||
}
|
||||
|
||||
|
||||
@ -183,11 +183,17 @@ namespace dxvk {
|
||||
|
||||
void DxvkContext::bindVertexBuffer(
|
||||
uint32_t binding,
|
||||
const DxvkBufferBinding& buffer) {
|
||||
const DxvkBufferBinding& buffer,
|
||||
uint32_t stride) {
|
||||
if (m_state.vi.vertexBuffers.at(binding) != buffer) {
|
||||
m_state.vi.vertexBuffers.at(binding) = buffer;
|
||||
m_flags.set(DxvkContextFlag::GpDirtyVertexBuffers);
|
||||
}
|
||||
|
||||
if (m_state.vi.vertexStrides.at(binding) != stride) {
|
||||
m_state.vi.vertexStrides.at(binding) = stride;
|
||||
m_flags.set(DxvkContextFlag::GpDirtyPipelineState);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -499,15 +505,65 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
DxvkGraphicsPipelineStateInfo gpState;
|
||||
gpState.inputAssemblyState = m_state.co.inputAssemblyState;
|
||||
gpState.inputLayout = m_state.co.inputLayout;
|
||||
gpState.rasterizerState = m_state.co.rasterizerState;
|
||||
gpState.multisampleState = m_state.co.multisampleState;
|
||||
gpState.depthStencilState = m_state.co.depthStencilState;
|
||||
gpState.blendState = m_state.co.blendState;
|
||||
gpState.renderPass = m_state.om.framebuffer->renderPass();
|
||||
gpState.viewportCount = m_state.vp.viewportCount;
|
||||
// TODO add vertex buffer strides
|
||||
|
||||
const auto& ia = m_state.co.inputAssemblyState->info();
|
||||
gpState.iaPrimitiveTopology = ia.topology;
|
||||
gpState.iaPrimitiveRestart = ia.primitiveRestartEnable;
|
||||
|
||||
const auto& il = m_state.co.inputLayout->info();
|
||||
gpState.ilAttributeCount = il.vertexAttributeDescriptionCount;
|
||||
gpState.ilBindingCount = il.vertexBindingDescriptionCount;
|
||||
|
||||
for (uint32_t i = 0; i < gpState.ilAttributeCount; i++)
|
||||
gpState.ilAttributes[i] = il.pVertexAttributeDescriptions[i];
|
||||
|
||||
for (uint32_t i = 0; i < gpState.ilBindingCount; i++) {
|
||||
gpState.ilBindings[i] = il.pVertexBindingDescriptions[i];
|
||||
gpState.ilBindings[i].stride = m_state.vi.vertexStrides.at(i);
|
||||
}
|
||||
|
||||
const auto& rs = m_state.co.rasterizerState->info();
|
||||
gpState.rsEnableDepthClamp = rs.depthClampEnable;
|
||||
gpState.rsEnableDiscard = rs.rasterizerDiscardEnable;
|
||||
gpState.rsPolygonMode = rs.polygonMode;
|
||||
gpState.rsCullMode = rs.cullMode;
|
||||
gpState.rsFrontFace = rs.frontFace;
|
||||
gpState.rsDepthBiasEnable = rs.depthBiasEnable;
|
||||
gpState.rsDepthBiasConstant = rs.depthBiasConstantFactor;
|
||||
gpState.rsDepthBiasClamp = rs.depthBiasClamp;
|
||||
gpState.rsDepthBiasSlope = rs.depthBiasSlopeFactor;
|
||||
gpState.rsViewportCount = m_state.vp.viewportCount;
|
||||
|
||||
// TODO implement multisampling support properly
|
||||
const auto& ms = m_state.co.multisampleState->info();
|
||||
gpState.msSampleCount = VK_SAMPLE_COUNT_1_BIT;
|
||||
gpState.msSampleMask = *ms.pSampleMask;
|
||||
gpState.msEnableAlphaToCoverage = ms.alphaToCoverageEnable;
|
||||
gpState.msEnableAlphaToOne = ms.alphaToOneEnable;
|
||||
gpState.msEnableSampleShading = ms.sampleShadingEnable;
|
||||
gpState.msMinSampleShading = ms.minSampleShading;
|
||||
|
||||
const auto& ds = m_state.co.depthStencilState->info();
|
||||
gpState.dsEnableDepthTest = ds.depthTestEnable;
|
||||
gpState.dsEnableDepthWrite = ds.depthWriteEnable;
|
||||
gpState.dsEnableDepthBounds = ds.depthBoundsTestEnable;
|
||||
gpState.dsEnableStencilTest = ds.stencilTestEnable;
|
||||
gpState.dsDepthCompareOp = ds.depthCompareOp;
|
||||
gpState.dsStencilOpFront = ds.front;
|
||||
gpState.dsStencilOpBack = ds.back;
|
||||
gpState.dsDepthBoundsMin = ds.minDepthBounds;
|
||||
gpState.dsDepthBoundsMax = ds.maxDepthBounds;
|
||||
|
||||
const auto& om = m_state.co.blendState->info();
|
||||
gpState.omEnableLogicOp = om.logicOpEnable;
|
||||
gpState.omLogicOp = om.logicOp;
|
||||
gpState.omRenderPass = m_state.om.framebuffer->renderPass();
|
||||
|
||||
const auto& rt = m_state.om.framebuffer->renderTargets();
|
||||
for (uint32_t i = 0; i < DxvkLimits::MaxNumRenderTargets; i++) {
|
||||
if (rt.getColorTarget(i) != nullptr)
|
||||
gpState.omBlendAttachments[i] = om.pAttachments[i];
|
||||
}
|
||||
|
||||
m_cmd->cmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
m_state.gp.pipeline->getPipelineHandle(gpState));
|
||||
|
@ -140,7 +140,8 @@ namespace dxvk {
|
||||
*/
|
||||
void bindVertexBuffer(
|
||||
uint32_t binding,
|
||||
const DxvkBufferBinding& buffer);
|
||||
const DxvkBufferBinding& buffer,
|
||||
uint32_t stride);
|
||||
|
||||
/**
|
||||
* \brief Clears subresources of a color image
|
||||
|
@ -42,6 +42,8 @@ namespace dxvk {
|
||||
|
||||
std::array<DxvkBufferBinding,
|
||||
DxvkLimits::MaxNumVertexBindings> vertexBuffers;
|
||||
std::array<uint32_t,
|
||||
DxvkLimits::MaxNumVertexBindings> vertexStrides;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,40 +1,38 @@
|
||||
#include <cstring>
|
||||
|
||||
#include "dxvk_graphics.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
template<typename T>
|
||||
size_t hashPtr(T* ptr) {
|
||||
return reinterpret_cast<size_t>(ptr);
|
||||
}
|
||||
|
||||
size_t DxvkGraphicsPipelineStateInfo::hash() const {
|
||||
DxvkHashState state;
|
||||
state.add(hashPtr(this->inputAssemblyState.ptr()));
|
||||
state.add(hashPtr(this->inputLayout.ptr()));
|
||||
state.add(hashPtr(this->rasterizerState.ptr()));
|
||||
state.add(hashPtr(this->multisampleState.ptr()));
|
||||
state.add(hashPtr(this->depthStencilState.ptr()));
|
||||
state.add(hashPtr(this->blendState.ptr()));
|
||||
state.add(std::hash<VkRenderPass>()(this->renderPass));
|
||||
state.add(viewportCount);
|
||||
return state;
|
||||
DxvkGraphicsPipelineStateInfo::DxvkGraphicsPipelineStateInfo() {
|
||||
std::memset(this, 0, sizeof(DxvkGraphicsPipelineStateInfo));
|
||||
}
|
||||
|
||||
|
||||
bool DxvkGraphicsPipelineStateInfo::operator == (const DxvkGraphicsPipelineStateInfo& other) const {
|
||||
return this->inputAssemblyState == other.inputAssemblyState
|
||||
&& this->inputLayout == other.inputLayout
|
||||
&& this->rasterizerState == other.rasterizerState
|
||||
&& this->multisampleState == other.multisampleState
|
||||
&& this->depthStencilState == other.depthStencilState
|
||||
&& this->blendState == other.blendState
|
||||
&& this->renderPass == other.renderPass
|
||||
&& this->viewportCount == other.viewportCount;
|
||||
DxvkGraphicsPipelineStateInfo::DxvkGraphicsPipelineStateInfo(
|
||||
const DxvkGraphicsPipelineStateInfo& other) {
|
||||
std::memcpy(this, &other, sizeof(DxvkGraphicsPipelineStateInfo));
|
||||
}
|
||||
|
||||
|
||||
bool DxvkGraphicsPipelineStateInfo::operator != (const DxvkGraphicsPipelineStateInfo& other) const {
|
||||
return !this->operator == (other);
|
||||
DxvkGraphicsPipelineStateInfo& DxvkGraphicsPipelineStateInfo::operator = (
|
||||
const DxvkGraphicsPipelineStateInfo& other) {
|
||||
std::memcpy(this, &other, sizeof(DxvkGraphicsPipelineStateInfo));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
size_t DxvkGraphicsPipelineStateHash::operator () (
|
||||
const DxvkGraphicsPipelineStateInfo& state) const {
|
||||
// TODO implement hash
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
size_t DxvkGraphicsPipelineStateEq::operator () (
|
||||
const DxvkGraphicsPipelineStateInfo& a,
|
||||
const DxvkGraphicsPipelineStateInfo& b) const {
|
||||
return std::memcmp(&a, &b, sizeof(DxvkGraphicsPipelineStateInfo)) == 0;
|
||||
}
|
||||
|
||||
|
||||
@ -101,42 +99,110 @@ namespace dxvk {
|
||||
if (m_gs != nullptr) stages.push_back(m_gs->stageInfo());
|
||||
if (m_fs != nullptr) stages.push_back(m_fs->stageInfo());
|
||||
|
||||
VkPipelineViewportStateCreateInfo vpInfo;
|
||||
vpInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
||||
vpInfo.pNext = nullptr;
|
||||
vpInfo.flags = 0;
|
||||
vpInfo.viewportCount = state.viewportCount;
|
||||
vpInfo.pViewports = nullptr;
|
||||
vpInfo.scissorCount = state.viewportCount;
|
||||
vpInfo.pScissors = nullptr;
|
||||
VkPipelineVertexInputStateCreateInfo viInfo;
|
||||
viInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
||||
viInfo.pNext = nullptr;
|
||||
viInfo.flags = 0;
|
||||
viInfo.vertexBindingDescriptionCount = state.ilBindingCount;
|
||||
viInfo.pVertexBindingDescriptions = state.ilBindings;
|
||||
viInfo.vertexAttributeDescriptionCount = state.ilAttributeCount;
|
||||
viInfo.pVertexAttributeDescriptions = state.ilAttributes;
|
||||
|
||||
VkPipelineDynamicStateCreateInfo dsInfo;
|
||||
dsInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
|
||||
dsInfo.pNext = nullptr;
|
||||
dsInfo.flags = 0;
|
||||
dsInfo.dynamicStateCount = dynamicStates.size();
|
||||
dsInfo.pDynamicStates = dynamicStates.data();
|
||||
VkPipelineInputAssemblyStateCreateInfo iaInfo;
|
||||
iaInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
||||
iaInfo.pNext = nullptr;
|
||||
iaInfo.flags = 0;
|
||||
iaInfo.topology = state.iaPrimitiveTopology;
|
||||
iaInfo.primitiveRestartEnable = state.iaPrimitiveRestart;
|
||||
|
||||
VkPipelineViewportStateCreateInfo vpInfo;
|
||||
vpInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
||||
vpInfo.pNext = nullptr;
|
||||
vpInfo.flags = 0;
|
||||
vpInfo.viewportCount = state.rsViewportCount;
|
||||
vpInfo.pViewports = nullptr;
|
||||
vpInfo.scissorCount = state.rsViewportCount;
|
||||
vpInfo.pScissors = nullptr;
|
||||
|
||||
VkPipelineRasterizationStateCreateInfo rsInfo;
|
||||
rsInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
||||
rsInfo.pNext = nullptr;
|
||||
rsInfo.flags = 0;
|
||||
rsInfo.depthClampEnable = state.rsEnableDepthClamp;
|
||||
rsInfo.rasterizerDiscardEnable= state.rsEnableDiscard;
|
||||
rsInfo.polygonMode = state.rsPolygonMode;
|
||||
rsInfo.cullMode = state.rsCullMode;
|
||||
rsInfo.frontFace = state.rsFrontFace;
|
||||
rsInfo.depthBiasEnable = state.rsDepthBiasEnable;
|
||||
rsInfo.depthBiasConstantFactor= state.rsDepthBiasConstant;
|
||||
rsInfo.depthBiasClamp = state.rsDepthBiasClamp;
|
||||
rsInfo.depthBiasSlopeFactor = state.rsDepthBiasSlope;
|
||||
rsInfo.lineWidth = 1.0f;
|
||||
|
||||
VkPipelineMultisampleStateCreateInfo msInfo;
|
||||
msInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
||||
msInfo.pNext = nullptr;
|
||||
msInfo.flags = 0;
|
||||
msInfo.rasterizationSamples = state.msSampleCount;
|
||||
msInfo.sampleShadingEnable = state.msEnableSampleShading;
|
||||
msInfo.minSampleShading = state.msMinSampleShading;
|
||||
msInfo.pSampleMask = &state.msSampleMask;
|
||||
msInfo.alphaToCoverageEnable = state.msEnableAlphaToCoverage;
|
||||
msInfo.alphaToOneEnable = state.msEnableAlphaToOne;
|
||||
|
||||
VkPipelineDepthStencilStateCreateInfo dsInfo;
|
||||
dsInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
||||
dsInfo.pNext = nullptr;
|
||||
dsInfo.flags = 0;
|
||||
dsInfo.depthTestEnable = state.dsEnableDepthTest;
|
||||
dsInfo.depthWriteEnable = state.dsEnableDepthWrite;
|
||||
dsInfo.depthCompareOp = state.dsDepthCompareOp;
|
||||
dsInfo.depthBoundsTestEnable = state.dsEnableDepthBounds;
|
||||
dsInfo.stencilTestEnable = state.dsEnableStencilTest;
|
||||
dsInfo.front = state.dsStencilOpFront;
|
||||
dsInfo.back = state.dsStencilOpBack;
|
||||
dsInfo.minDepthBounds = state.dsDepthBoundsMin;
|
||||
dsInfo.maxDepthBounds = state.dsDepthBoundsMax;
|
||||
|
||||
VkPipelineColorBlendStateCreateInfo cbInfo;
|
||||
cbInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
||||
cbInfo.pNext = nullptr;
|
||||
cbInfo.flags = 0;
|
||||
cbInfo.logicOpEnable = state.omEnableLogicOp;
|
||||
cbInfo.logicOp = state.omLogicOp;
|
||||
cbInfo.attachmentCount = DxvkLimits::MaxNumRenderTargets;
|
||||
cbInfo.pAttachments = state.omBlendAttachments;
|
||||
|
||||
for (uint32_t i = 0; i < 4; i++)
|
||||
cbInfo.blendConstants[i] = 0.0f;
|
||||
|
||||
VkPipelineDynamicStateCreateInfo dyInfo;
|
||||
dyInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
|
||||
dyInfo.pNext = nullptr;
|
||||
dyInfo.flags = 0;
|
||||
dyInfo.dynamicStateCount = dynamicStates.size();
|
||||
dyInfo.pDynamicStates = dynamicStates.data();
|
||||
|
||||
VkGraphicsPipelineCreateInfo info;
|
||||
info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||
info.pNext = nullptr;
|
||||
info.flags = 0;
|
||||
info.stageCount = stages.size();
|
||||
info.pStages = stages.data();
|
||||
info.pVertexInputState = &state.inputLayout->info();
|
||||
info.pInputAssemblyState = &state.inputAssemblyState->info();
|
||||
info.pTessellationState = nullptr; // TODO implement
|
||||
info.pViewportState = &vpInfo;
|
||||
info.pRasterizationState = &state.rasterizerState->info();
|
||||
info.pMultisampleState = &state.multisampleState->info();
|
||||
info.pDepthStencilState = &state.depthStencilState->info();
|
||||
info.pColorBlendState = &state.blendState->info();
|
||||
info.pDynamicState = &dsInfo;
|
||||
info.layout = m_layout->pipelineLayout();
|
||||
info.renderPass = state.renderPass;
|
||||
info.subpass = 0;
|
||||
info.basePipelineHandle = VK_NULL_HANDLE;
|
||||
info.basePipelineIndex = 0;
|
||||
info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||
info.pNext = nullptr;
|
||||
info.flags = 0;
|
||||
info.stageCount = stages.size();
|
||||
info.pStages = stages.data();
|
||||
info.pVertexInputState = &viInfo;
|
||||
info.pInputAssemblyState = &iaInfo;
|
||||
info.pTessellationState = nullptr; // TODO implement
|
||||
info.pViewportState = &vpInfo;
|
||||
info.pRasterizationState = &rsInfo;
|
||||
info.pMultisampleState = &msInfo;
|
||||
info.pDepthStencilState = &dsInfo;
|
||||
info.pColorBlendState = &cbInfo;
|
||||
info.pDynamicState = &dyInfo;
|
||||
info.layout = m_layout->pipelineLayout();
|
||||
info.renderPass = state.omRenderPass;
|
||||
info.subpass = 0;
|
||||
info.basePipelineHandle = VK_NULL_HANDLE; // TODO use this
|
||||
info.basePipelineIndex = 0;
|
||||
|
||||
VkPipeline pipeline = VK_NULL_HANDLE;
|
||||
if (m_vkd->vkCreateGraphicsPipelines(m_vkd->device(),
|
||||
|
@ -20,20 +20,65 @@ namespace dxvk {
|
||||
* the current pipeline state vector.
|
||||
*/
|
||||
struct DxvkGraphicsPipelineStateInfo {
|
||||
Rc<DxvkInputAssemblyState> inputAssemblyState;
|
||||
Rc<DxvkInputLayout> inputLayout;
|
||||
Rc<DxvkRasterizerState> rasterizerState;
|
||||
Rc<DxvkMultisampleState> multisampleState;
|
||||
Rc<DxvkDepthStencilState> depthStencilState;
|
||||
Rc<DxvkBlendState> blendState;
|
||||
DxvkGraphicsPipelineStateInfo();
|
||||
DxvkGraphicsPipelineStateInfo(
|
||||
const DxvkGraphicsPipelineStateInfo& other);
|
||||
|
||||
VkRenderPass renderPass;
|
||||
uint32_t viewportCount;
|
||||
DxvkGraphicsPipelineStateInfo& operator = (
|
||||
const DxvkGraphicsPipelineStateInfo& other);
|
||||
|
||||
size_t hash() const;
|
||||
VkPrimitiveTopology iaPrimitiveTopology;
|
||||
VkBool32 iaPrimitiveRestart;
|
||||
|
||||
bool operator == (const DxvkGraphicsPipelineStateInfo& other) const;
|
||||
bool operator != (const DxvkGraphicsPipelineStateInfo& other) const;
|
||||
uint32_t ilAttributeCount;
|
||||
uint32_t ilBindingCount;
|
||||
VkVertexInputAttributeDescription ilAttributes[DxvkLimits::MaxNumVertexAttributes];
|
||||
VkVertexInputBindingDescription ilBindings[DxvkLimits::MaxNumVertexBindings];
|
||||
|
||||
VkBool32 rsEnableDepthClamp;
|
||||
VkBool32 rsEnableDiscard;
|
||||
VkPolygonMode rsPolygonMode;
|
||||
VkCullModeFlags rsCullMode;
|
||||
VkFrontFace rsFrontFace;
|
||||
VkBool32 rsDepthBiasEnable;
|
||||
float rsDepthBiasConstant;
|
||||
float rsDepthBiasClamp;
|
||||
float rsDepthBiasSlope;
|
||||
uint32_t rsViewportCount;
|
||||
|
||||
VkSampleCountFlagBits msSampleCount;
|
||||
uint32_t msSampleMask;
|
||||
VkBool32 msEnableAlphaToCoverage;
|
||||
VkBool32 msEnableAlphaToOne;
|
||||
VkBool32 msEnableSampleShading;
|
||||
float msMinSampleShading;
|
||||
|
||||
VkBool32 dsEnableDepthTest;
|
||||
VkBool32 dsEnableDepthWrite;
|
||||
VkBool32 dsEnableDepthBounds;
|
||||
VkBool32 dsEnableStencilTest;
|
||||
VkCompareOp dsDepthCompareOp;
|
||||
VkStencilOpState dsStencilOpFront;
|
||||
VkStencilOpState dsStencilOpBack;
|
||||
float dsDepthBoundsMin;
|
||||
float dsDepthBoundsMax;
|
||||
|
||||
VkBool32 omEnableLogicOp;
|
||||
VkLogicOp omLogicOp;
|
||||
VkRenderPass omRenderPass;
|
||||
VkPipelineColorBlendAttachmentState omBlendAttachments[DxvkLimits::MaxNumRenderTargets];
|
||||
};
|
||||
|
||||
|
||||
struct DxvkGraphicsPipelineStateHash {
|
||||
size_t operator () (const DxvkGraphicsPipelineStateInfo& state) const;
|
||||
};
|
||||
|
||||
|
||||
struct DxvkGraphicsPipelineStateEq {
|
||||
size_t operator () (
|
||||
const DxvkGraphicsPipelineStateInfo& a,
|
||||
const DxvkGraphicsPipelineStateInfo& b) const;
|
||||
};
|
||||
|
||||
|
||||
@ -91,7 +136,9 @@ namespace dxvk {
|
||||
|
||||
std::unordered_map<
|
||||
DxvkGraphicsPipelineStateInfo,
|
||||
VkPipeline, DxvkHash> m_pipelines;
|
||||
VkPipeline,
|
||||
DxvkGraphicsPipelineStateHash,
|
||||
DxvkGraphicsPipelineStateEq> m_pipelines;
|
||||
|
||||
VkPipeline compilePipeline(
|
||||
const DxvkGraphicsPipelineStateInfo& state) const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user