"Dynamic viewport state not set for this command buffer");
result |= validate_status(dev_data, pCB, CBSTATUS_SCISSOR_SET, VK_DEBUG_REPORT_ERROR_BIT_EXT, DRAWSTATE_SCISSOR_NOT_BOUND,
"Dynamic scissor state not set for this command buffer");
- if ((pPipe->iaStateCI.topology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST) ||
- (pPipe->iaStateCI.topology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP)) {
+ if (pPipe->graphicsPipelineCI.pInputAssemblyState &&
+ ((pPipe->graphicsPipelineCI.pInputAssemblyState->topology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST) ||
+ (pPipe->graphicsPipelineCI.pInputAssemblyState->topology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP))) {
result |= validate_status(dev_data, pCB, CBSTATUS_LINE_WIDTH_SET, VK_DEBUG_REPORT_ERROR_BIT_EXT,
DRAWSTATE_LINE_WIDTH_NOT_BOUND, "Dynamic line width state not set for this command buffer");
}
- if (pPipe->rsStateCI.depthBiasEnable) {
+ if (pPipe->graphicsPipelineCI.pRasterizationState && pPipe->graphicsPipelineCI.pRasterizationState->depthBiasEnable) {
result |= validate_status(dev_data, pCB, CBSTATUS_DEPTH_BIAS_SET, VK_DEBUG_REPORT_ERROR_BIT_EXT,
DRAWSTATE_DEPTH_BIAS_NOT_BOUND, "Dynamic depth bias state not set for this command buffer");
}
result |= validate_status(dev_data, pCB, CBSTATUS_BLEND_CONSTANTS_SET, VK_DEBUG_REPORT_ERROR_BIT_EXT,
DRAWSTATE_BLEND_NOT_BOUND, "Dynamic blend constants state not set for this command buffer");
}
- if (pPipe->dsStateCI.depthBoundsTestEnable) {
+ if (pPipe->graphicsPipelineCI.pDepthStencilState && pPipe->graphicsPipelineCI.pDepthStencilState->depthBoundsTestEnable) {
result |= validate_status(dev_data, pCB, CBSTATUS_DEPTH_BOUNDS_SET, VK_DEBUG_REPORT_ERROR_BIT_EXT,
DRAWSTATE_DEPTH_BOUNDS_NOT_BOUND, "Dynamic depth bounds state not set for this command buffer");
}
- if (pPipe->dsStateCI.stencilTestEnable) {
+ if (pPipe->graphicsPipelineCI.pDepthStencilState && pPipe->graphicsPipelineCI.pDepthStencilState->stencilTestEnable) {
result |= validate_status(dev_data, pCB, CBSTATUS_STENCIL_READ_MASK_SET, VK_DEBUG_REPORT_ERROR_BIT_EXT,
DRAWSTATE_STENCIL_NOT_BOUND, "Dynamic stencil read mask state not set for this command buffer");
result |= validate_status(dev_data, pCB, CBSTATUS_STENCIL_WRITE_MASK_SET, VK_DEBUG_REPORT_ERROR_BIT_EXT,
// Validate that the shaders used by the given pipeline and store the active_slots
// that are actually used by the pipeline into pPipeline->active_slots
static VkBool32 validate_and_capture_pipeline_shader_state(layer_data *my_data, PIPELINE_NODE *pPipeline) {
- VkGraphicsPipelineCreateInfo const *pCreateInfo = &pPipeline->graphicsPipelineCI;
+ auto pCreateInfo = reinterpret_cast<VkGraphicsPipelineCreateInfo const *>(&pPipeline->graphicsPipelineCI);
int vertex_stage = get_shader_stage_id(VK_SHADER_STAGE_VERTEX_BIT);
int fragment_stage = get_shader_stage_id(VK_SHADER_STAGE_FRAGMENT_BIT);
auto pipelineLayout = pCreateInfo->layout != VK_NULL_HANDLE ? &my_data->pipelineLayoutMap[pCreateInfo->layout] : nullptr;
for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
- VkPipelineShaderStageCreateInfo const *pStage = &pCreateInfo->pStages[i];
+ VkPipelineShaderStageCreateInfo const *pStage =
+ reinterpret_cast<VkPipelineShaderStageCreateInfo const *>(&pCreateInfo->pStages[i]);
auto stage_id = get_shader_stage_id(pStage->stage);
pass &= validate_pipeline_shader_stage(my_data, pStage, pPipeline, pipelineLayout,
&shaders[stage_id], &entrypoints[stage_id]);
}
static VkBool32 validate_compute_pipeline(layer_data *my_data, PIPELINE_NODE *pPipeline) {
- VkComputePipelineCreateInfo const *pCreateInfo = &pPipeline->computePipelineCI;
+ auto pCreateInfo = reinterpret_cast<VkComputePipelineCreateInfo const *>(&pPipeline->computePipelineCI);
auto pipelineLayout = pCreateInfo->layout != VK_NULL_HANDLE ? &my_data->pipelineLayoutMap[pCreateInfo->layout] : nullptr;
// VK_PRIMITIVE_TOPOLOGY_PATCH_LIST primitive topology is only valid for tessellation pipelines.
// Mismatching primitive topology and tessellation fails graphics pipeline creation.
if (pPipeline->active_shaders & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) &&
- (pPipeline->iaStateCI.topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST)) {
+ (!pPipeline->graphicsPipelineCI.pInputAssemblyState ||
+ pPipeline->graphicsPipelineCI.pInputAssemblyState->topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST)) {
skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS", "Invalid Pipeline CreateInfo State: "
"VK_PRIMITIVE_TOPOLOGY_PATCH_LIST must be set as IA "
"topology for tessellation pipelines");
}
- if (pPipeline->iaStateCI.topology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) {
+ if (pPipeline->graphicsPipelineCI.pInputAssemblyState &&
+ pPipeline->graphicsPipelineCI.pInputAssemblyState->topology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) {
if (~pPipeline->active_shaders & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) {
skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS", "Invalid Pipeline CreateInfo State: "
"VK_PRIMITIVE_TOPOLOGY_PATCH_LIST primitive "
"topology is only valid for tessellation pipelines");
}
- if (!pPipeline->tessStateCI.patchControlPoints || (pPipeline->tessStateCI.patchControlPoints > 32)) {
+ if (!pPipeline->graphicsPipelineCI.pTessellationState) {
+ skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+ DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS",
+ "Invalid Pipeline CreateInfo State: "
+ "pTessellationState is NULL when VK_PRIMITIVE_TOPOLOGY_PATCH_LIST primitive "
+ "topology used. pTessellationState must not be NULL in this case.");
+ } else if (!pPipeline->graphicsPipelineCI.pTessellationState->patchControlPoints ||
+ (pPipeline->graphicsPipelineCI.pTessellationState->patchControlPoints > 32)) {
skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS", "Invalid Pipeline CreateInfo State: "
"VK_PRIMITIVE_TOPOLOGY_PATCH_LIST primitive "
"topology used with patchControlPoints value %u."
" patchControlPoints should be >0 and <=32.",
- pPipeline->tessStateCI.patchControlPoints);
+ pPipeline->graphicsPipelineCI.pTessellationState->patchControlPoints);
}
}
// Viewport state must be included if rasterization is enabled.
skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, "DS",
"Gfx Pipeline viewport count (%u) must match scissor count (%u).",
- pPipeline->vpStateCI.viewportCount, pPipeline->vpStateCI.scissorCount);
+ pPipeline->graphicsPipelineCI.pViewportState->viewportCount,
+ pPipeline->graphicsPipelineCI.pViewportState->scissorCount);
} else {
// If viewport or scissor are not dynamic, then verify that data is appropriate for count
VkBool32 dynViewport = isDynamic(pPipeline, VK_DYNAMIC_STATE_VIEWPORT);
return skipCall;
}
-// Init the pipeline mapping info based on pipeline create info LL tree
-// Threading note : Calls to this function should wrapped in mutex
-// TODO : this should really just be in the constructor for PIPELINE_NODE
-static PIPELINE_NODE *initGraphicsPipeline(layer_data *dev_data, const VkGraphicsPipelineCreateInfo *pCreateInfo) {
- PIPELINE_NODE *pPipeline = new PIPELINE_NODE;
-
- // First init create info
- memcpy(&pPipeline->graphicsPipelineCI, pCreateInfo, sizeof(VkGraphicsPipelineCreateInfo));
-
- size_t bufferSize = 0;
- const VkPipelineVertexInputStateCreateInfo *pVICI = NULL;
- const VkPipelineColorBlendStateCreateInfo *pCBCI = NULL;
-
- for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
- const VkPipelineShaderStageCreateInfo *pPSSCI = &pCreateInfo->pStages[i];
-
- switch (pPSSCI->stage) {
- case VK_SHADER_STAGE_VERTEX_BIT:
- memcpy(&pPipeline->vsCI, pPSSCI, sizeof(VkPipelineShaderStageCreateInfo));
- pPipeline->active_shaders |= VK_SHADER_STAGE_VERTEX_BIT;
- break;
- case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
- memcpy(&pPipeline->tcsCI, pPSSCI, sizeof(VkPipelineShaderStageCreateInfo));
- pPipeline->active_shaders |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
- break;
- case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
- memcpy(&pPipeline->tesCI, pPSSCI, sizeof(VkPipelineShaderStageCreateInfo));
- pPipeline->active_shaders |= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
- break;
- case VK_SHADER_STAGE_GEOMETRY_BIT:
- memcpy(&pPipeline->gsCI, pPSSCI, sizeof(VkPipelineShaderStageCreateInfo));
- pPipeline->active_shaders |= VK_SHADER_STAGE_GEOMETRY_BIT;
- break;
- case VK_SHADER_STAGE_FRAGMENT_BIT:
- memcpy(&pPipeline->fsCI, pPSSCI, sizeof(VkPipelineShaderStageCreateInfo));
- pPipeline->active_shaders |= VK_SHADER_STAGE_FRAGMENT_BIT;
- break;
- case VK_SHADER_STAGE_COMPUTE_BIT:
- // TODO : Flag error, CS is specified through VkComputePipelineCreateInfo
- pPipeline->active_shaders |= VK_SHADER_STAGE_COMPUTE_BIT;
- break;
- default:
- // TODO : Flag error
- break;
- }
- }
- // Copy over GraphicsPipelineCreateInfo structure embedded pointers
- if (pCreateInfo->stageCount != 0) {
- pPipeline->graphicsPipelineCI.pStages = new VkPipelineShaderStageCreateInfo[pCreateInfo->stageCount];
- bufferSize = pCreateInfo->stageCount * sizeof(VkPipelineShaderStageCreateInfo);
- memcpy((void *)pPipeline->graphicsPipelineCI.pStages, pCreateInfo->pStages, bufferSize);
- }
- if (pCreateInfo->pVertexInputState != NULL) {
- pPipeline->vertexInputCI = *pCreateInfo->pVertexInputState;
- // Copy embedded ptrs
- pVICI = pCreateInfo->pVertexInputState;
- if (pVICI->vertexBindingDescriptionCount) {
- pPipeline->vertexBindingDescriptions = std::vector<VkVertexInputBindingDescription>(
- pVICI->pVertexBindingDescriptions, pVICI->pVertexBindingDescriptions + pVICI->vertexBindingDescriptionCount);
- }
- if (pVICI->vertexAttributeDescriptionCount) {
- pPipeline->vertexAttributeDescriptions = std::vector<VkVertexInputAttributeDescription>(
- pVICI->pVertexAttributeDescriptions, pVICI->pVertexAttributeDescriptions + pVICI->vertexAttributeDescriptionCount);
- }
- pPipeline->graphicsPipelineCI.pVertexInputState = &pPipeline->vertexInputCI;
- }
- if (pCreateInfo->pInputAssemblyState != NULL) {
- pPipeline->iaStateCI = *pCreateInfo->pInputAssemblyState;
- pPipeline->graphicsPipelineCI.pInputAssemblyState = &pPipeline->iaStateCI;
- }
- if (pCreateInfo->pTessellationState != NULL) {
- pPipeline->tessStateCI = *pCreateInfo->pTessellationState;
- pPipeline->graphicsPipelineCI.pTessellationState = &pPipeline->tessStateCI;
- }
- if (pCreateInfo->pViewportState != NULL) {
- pPipeline->vpStateCI = *pCreateInfo->pViewportState;
- pPipeline->graphicsPipelineCI.pViewportState = &pPipeline->vpStateCI;
- }
- if (pCreateInfo->pRasterizationState != NULL) {
- pPipeline->rsStateCI = *pCreateInfo->pRasterizationState;
- pPipeline->graphicsPipelineCI.pRasterizationState = &pPipeline->rsStateCI;
- }
- if (pCreateInfo->pMultisampleState != NULL) {
- pPipeline->msStateCI = *pCreateInfo->pMultisampleState;
- pPipeline->graphicsPipelineCI.pMultisampleState = &pPipeline->msStateCI;
- }
- if (pCreateInfo->pDepthStencilState != NULL) {
- pPipeline->dsStateCI = *pCreateInfo->pDepthStencilState;
- pPipeline->graphicsPipelineCI.pDepthStencilState = &pPipeline->dsStateCI;
- }
- if (pCreateInfo->pColorBlendState != NULL) {
- pPipeline->cbStateCI = *pCreateInfo->pColorBlendState;
- // Copy embedded ptrs
- pCBCI = pCreateInfo->pColorBlendState;
- if (pCBCI->attachmentCount) {
- pPipeline->attachments = std::vector<VkPipelineColorBlendAttachmentState>(
- pCBCI->pAttachments, pCBCI->pAttachments + pCBCI->attachmentCount);
- }
- pPipeline->graphicsPipelineCI.pColorBlendState = &pPipeline->cbStateCI;
- }
- if (pCreateInfo->pDynamicState != NULL) {
- pPipeline->dynStateCI = *pCreateInfo->pDynamicState;
- if (pPipeline->dynStateCI.dynamicStateCount) {
- pPipeline->dynStateCI.pDynamicStates = new VkDynamicState[pPipeline->dynStateCI.dynamicStateCount];
- bufferSize = pPipeline->dynStateCI.dynamicStateCount * sizeof(VkDynamicState);
- memcpy((void *)pPipeline->dynStateCI.pDynamicStates, pCreateInfo->pDynamicState->pDynamicStates, bufferSize);
- }
- pPipeline->graphicsPipelineCI.pDynamicState = &pPipeline->dynStateCI;
- }
- return pPipeline;
-}
-
// Free the Pipeline nodes
static void deletePipelines(layer_data *my_data) {
if (my_data->pipelineMap.size() <= 0)
return;
- for (auto ii = my_data->pipelineMap.begin(); ii != my_data->pipelineMap.end(); ++ii) {
- if ((*ii).second->graphicsPipelineCI.stageCount != 0) {
- delete[](*ii).second->graphicsPipelineCI.pStages;
- }
- if ((*ii).second->dynStateCI.dynamicStateCount != 0) {
- delete[](*ii).second->dynStateCI.pDynamicStates;
- }
- delete (*ii).second;
+ for (auto &pipe_map_pair : my_data->pipelineMap) {
+ delete pipe_map_pair.second;
}
my_data->pipelineMap.clear();
}
// For given pipeline, return number of MSAA samples, or one if MSAA disabled
static VkSampleCountFlagBits getNumSamples(layer_data *my_data, const VkPipeline pipeline) {
PIPELINE_NODE *pPipe = my_data->pipelineMap[pipeline];
- if (VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO == pPipe->msStateCI.sType) {
- return pPipe->msStateCI.rasterizationSamples;
+ if (pPipe->graphicsPipelineCI.pMultisampleState &&
+ (VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO == pPipe->graphicsPipelineCI.pMultisampleState->sType)) {
+ return pPipe->graphicsPipelineCI.pMultisampleState->rasterizationSamples;
}
return VK_SAMPLE_COUNT_1_BIT;
}
// Set PSO-related status bits for CB, including dynamic state set via PSO
static void set_cb_pso_status(GLOBAL_CB_NODE *pCB, const PIPELINE_NODE *pPipe) {
// Account for any dynamic state not set via this PSO
- if (!pPipe->dynStateCI.dynamicStateCount) { // All state is static
+ if (!pPipe->graphicsPipelineCI.pDynamicState ||
+ !pPipe->graphicsPipelineCI.pDynamicState->dynamicStateCount) { // All state is static
pCB->status = CBSTATUS_ALL;
} else {
// First consider all state on
// Then unset any state that's noted as dynamic in PSO
// Finally OR that into CB statemask
CBStatusFlags psoDynStateMask = CBSTATUS_ALL;
- for (uint32_t i = 0; i < pPipe->dynStateCI.dynamicStateCount; i++) {
- switch (pPipe->dynStateCI.pDynamicStates[i]) {
+ for (uint32_t i = 0; i < pPipe->graphicsPipelineCI.pDynamicState->dynamicStateCount; i++) {
+ switch (pPipe->graphicsPipelineCI.pDynamicState->pDynamicStates[i]) {
case VK_DYNAMIC_STATE_VIEWPORT:
psoDynStateMask &= ~CBSTATUS_VIEWPORT_SET;
break;
} else {
skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
__LINE__, DRAWSTATE_NONE, "DS", "%s",
- vk_print_vkgraphicspipelinecreateinfo(&pPipeTrav->graphicsPipelineCI, "{DS}").c_str());
+ vk_print_vkgraphicspipelinecreateinfo(
+ reinterpret_cast<const VkGraphicsPipelineCreateInfo *>(&pPipeTrav->graphicsPipelineCI), "{DS}")
+ .c_str());
}
}
return skipCall;
loader_platform_thread_lock_mutex(&globalLock);
for (i = 0; i < count; i++) {
- pPipeNode[i] = initGraphicsPipeline(dev_data, &pCreateInfos[i]);
+ pPipeNode[i] = new PIPELINE_NODE;
+ pPipeNode[i]->initGraphicsPipeline(&pCreateInfos[i]);
skipCall |= verifyPipelineCreateState(dev_data, device, pPipeNode, i);
}
// Create and initialize internal tracking data structure
pPipeNode[i] = new PIPELINE_NODE;
- memcpy(&pPipeNode[i]->computePipelineCI, (const void *)&pCreateInfos[i], sizeof(VkComputePipelineCreateInfo));
+ pPipeNode[i]->initComputePipeline(&pCreateInfos[i]);
+ // memcpy(&pPipeNode[i]->computePipelineCI, (const void *)&pCreateInfos[i], sizeof(VkComputePipelineCreateInfo));
// TODO: Add Compute Pipeline Verification
// skipCall |= verifyPipelineCreateState(dev_data, device, pPipeNode[i]);
#define MTMERGE 1
#pragma once
+#include "vk_safe_struct.h"
#include "vulkan/vk_layer.h"
#include <atomic>
#include <vector>
const void *pNext;
} GENERIC_HEADER;
-typedef struct _PIPELINE_NODE {
+class PIPELINE_NODE {
+ public:
VkPipeline pipeline;
- VkGraphicsPipelineCreateInfo graphicsPipelineCI;
- VkPipelineVertexInputStateCreateInfo vertexInputCI;
- VkPipelineInputAssemblyStateCreateInfo iaStateCI;
- VkPipelineTessellationStateCreateInfo tessStateCI;
- VkPipelineViewportStateCreateInfo vpStateCI;
- VkPipelineRasterizationStateCreateInfo rsStateCI;
- VkPipelineMultisampleStateCreateInfo msStateCI;
- VkPipelineColorBlendStateCreateInfo cbStateCI;
- VkPipelineDepthStencilStateCreateInfo dsStateCI;
- VkPipelineDynamicStateCreateInfo dynStateCI;
- VkPipelineShaderStageCreateInfo vsCI;
- VkPipelineShaderStageCreateInfo tcsCI;
- VkPipelineShaderStageCreateInfo tesCI;
- VkPipelineShaderStageCreateInfo gsCI;
- VkPipelineShaderStageCreateInfo fsCI;
- // Compute shader is include in VkComputePipelineCreateInfo
- VkComputePipelineCreateInfo computePipelineCI;
+ safe_VkGraphicsPipelineCreateInfo graphicsPipelineCI;
+ safe_VkComputePipelineCreateInfo computePipelineCI;
// Flag of which shader stages are active for this pipeline
uint32_t active_shaders;
// Capture which slots (set#->bindings) are actually used by the shaders of this pipeline
std::vector<VkPipelineColorBlendAttachmentState> attachments;
bool blendConstantsEnabled; // Blend constants enabled for any attachments
// Default constructor
- _PIPELINE_NODE()
- : pipeline{}, graphicsPipelineCI{}, vertexInputCI{}, iaStateCI{}, tessStateCI{}, vpStateCI{}, rsStateCI{}, msStateCI{},
- cbStateCI{}, dsStateCI{}, dynStateCI{}, vsCI{}, tcsCI{}, tesCI{}, gsCI{}, fsCI{}, computePipelineCI{}, active_shaders(0),
- active_slots(), vertexBindingDescriptions(), vertexAttributeDescriptions(), attachments(), blendConstantsEnabled(false) {}
-} PIPELINE_NODE;
+ PIPELINE_NODE()
+ : pipeline{}, graphicsPipelineCI{}, computePipelineCI{}, active_shaders(0), active_slots(), vertexBindingDescriptions(),
+ vertexAttributeDescriptions(), attachments(), blendConstantsEnabled(false) {}
+
+ void initGraphicsPipeline(const VkGraphicsPipelineCreateInfo *pCreateInfo) {
+ graphicsPipelineCI.initialize(pCreateInfo);
+ // Make sure compute pipeline is null
+ VkComputePipelineCreateInfo emptyComputeCI = {};
+ computePipelineCI.initialize(&emptyComputeCI);
+ for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
+ const VkPipelineShaderStageCreateInfo *pPSSCI = &pCreateInfo->pStages[i];
+
+ switch (pPSSCI->stage) {
+ case VK_SHADER_STAGE_VERTEX_BIT:
+ this->active_shaders |= VK_SHADER_STAGE_VERTEX_BIT;
+ break;
+ case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
+ this->active_shaders |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
+ break;
+ case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
+ this->active_shaders |= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
+ break;
+ case VK_SHADER_STAGE_GEOMETRY_BIT:
+ this->active_shaders |= VK_SHADER_STAGE_GEOMETRY_BIT;
+ break;
+ case VK_SHADER_STAGE_FRAGMENT_BIT:
+ this->active_shaders |= VK_SHADER_STAGE_FRAGMENT_BIT;
+ break;
+ case VK_SHADER_STAGE_COMPUTE_BIT:
+ // TODO : Flag error, CS is specified through VkComputePipelineCreateInfo
+ this->active_shaders |= VK_SHADER_STAGE_COMPUTE_BIT;
+ break;
+ default:
+ // TODO : Flag error
+ break;
+ }
+ }
+ if (pCreateInfo->pVertexInputState) {
+ const VkPipelineVertexInputStateCreateInfo *pVICI = pCreateInfo->pVertexInputState;
+ if (pVICI->vertexBindingDescriptionCount) {
+ this->vertexBindingDescriptions = std::vector<VkVertexInputBindingDescription>(
+ pVICI->pVertexBindingDescriptions, pVICI->pVertexBindingDescriptions + pVICI->vertexBindingDescriptionCount);
+ }
+ if (pVICI->vertexAttributeDescriptionCount) {
+ this->vertexAttributeDescriptions = std::vector<VkVertexInputAttributeDescription>(
+ pVICI->pVertexAttributeDescriptions,
+ pVICI->pVertexAttributeDescriptions + pVICI->vertexAttributeDescriptionCount);
+ }
+ }
+ if (pCreateInfo->pColorBlendState) {
+ const VkPipelineColorBlendStateCreateInfo *pCBCI = pCreateInfo->pColorBlendState;
+ if (pCBCI->attachmentCount) {
+ this->attachments = std::vector<VkPipelineColorBlendAttachmentState>(pCBCI->pAttachments,
+ pCBCI->pAttachments + pCBCI->attachmentCount);
+ }
+ }
+ }
+ void initComputePipeline(const VkComputePipelineCreateInfo *pCreateInfo) {
+ computePipelineCI.initialize(pCreateInfo);
+ // Make sure gfx pipeline is null
+ VkGraphicsPipelineCreateInfo emptyGraphicsCI = {};
+ graphicsPipelineCI.initialize(&emptyGraphicsCI);
+ switch (computePipelineCI.stage.stage) {
+ case VK_SHADER_STAGE_COMPUTE_BIT:
+ this->active_shaders |= VK_SHADER_STAGE_COMPUTE_BIT;
+ break;
+ default:
+ // TODO : Flag error
+ break;
+ }
+ }
+};
class BASE_NODE {
public: