From 521d7763bbe74f69d6dfa69dc3e40c5db6c7369c Mon Sep 17 00:00:00 2001 From: Mark Lobodzinski Date: Tue, 23 Jun 2015 15:11:57 -0600 Subject: vulkan.h: V104 -- Unify compute/graphics pipeline shader passing semantics, Bug# 13800 --- demos/cube.c | 52 ++++++------ demos/tri.c | 58 ++++++------- include/vulkan.h | 35 ++++---- layers/draw_state.cpp | 203 ++++++++++++++++++++++------------------------ layers/draw_state.h | 48 +++++------ layers/shader_checker.cpp | 27 +++--- 6 files changed, 209 insertions(+), 214 deletions(-) diff --git a/demos/cube.c b/demos/cube.c index 633cc4c7..dd5a604d 100644 --- a/demos/cube.c +++ b/demos/cube.c @@ -1347,16 +1347,18 @@ static VkShader demo_prepare_fs(struct demo *demo) static void demo_prepare_pipeline(struct demo *demo) { VkGraphicsPipelineCreateInfo pipeline; + + VkPipelineVertexInputStateCreateInfo vi; VkPipelineIaStateCreateInfo ia; VkPipelineRsStateCreateInfo rs; VkPipelineCbStateCreateInfo cb; VkPipelineDsStateCreateInfo ds; - VkPipelineShaderStageCreateInfo vs; - VkPipelineShaderStageCreateInfo fs; VkPipelineVpStateCreateInfo vp; VkPipelineMsStateCreateInfo ms; VkResult U_ASSERT_ONLY err; + memset(&vi, 0, sizeof(vi)); + memset(&pipeline, 0, sizeof(pipeline)); pipeline.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; pipeline.layout = demo->pipeline_layout; @@ -1399,38 +1401,40 @@ static void demo_prepare_pipeline(struct demo *demo) ds.stencilTestEnable = VK_FALSE; ds.front = ds.back; - memset(&vs, 0, sizeof(vs)); - vs.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - vs.shader.stage = VK_SHADER_STAGE_VERTEX; - vs.shader.shader = demo_prepare_vs(demo); - assert(vs.shader.shader != VK_NULL_HANDLE); - - memset(&fs, 0, sizeof(fs)); - fs.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - fs.shader.stage = VK_SHADER_STAGE_FRAGMENT; - fs.shader.shader = demo_prepare_fs(demo); - assert(fs.shader.shader != VK_NULL_HANDLE); - memset(&ms, 0, sizeof(ms)); ms.sType = VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO; ms.sampleMask = 1; ms.multisampleEnable = VK_FALSE; ms.samples = 1; - pipeline.pNext = (const void *) &ia; - ia.pNext = (const void *) &rs; - rs.pNext = (const void *) &cb; - cb.pNext = (const void *) &ms; - ms.pNext = (const void *) &vp; - vp.pNext = (const void *) &ds; - ds.pNext = (const void *) &vs; - vs.pNext = (const void *) &fs; + // Two stages: vs and fs + pipeline.stageCount = 2; + VkPipelineShaderStageCreateInfo shaderStages[2]; + memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo)); + + shaderStages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shaderStages[0].stage = VK_SHADER_STAGE_VERTEX; + shaderStages[0].shader = demo_prepare_vs(demo); + + shaderStages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shaderStages[1].stage = VK_SHADER_STAGE_FRAGMENT; + shaderStages[1].shader = demo_prepare_fs(demo); + + pipeline.pVertexInputState = &vi; + pipeline.pIaState = &ia; + pipeline.pRsState = &rs; + pipeline.pCbState = &cb; + pipeline.pMsState = &ms; + pipeline.pVpState = &vp; + pipeline.pDsState = &ds; + pipeline.pStages = shaderStages; err = vkCreateGraphicsPipeline(demo->device, &pipeline, &demo->pipeline); assert(!err); - vkDestroyObject(demo->device, VK_OBJECT_TYPE_SHADER, vs.shader.shader); - vkDestroyObject(demo->device, VK_OBJECT_TYPE_SHADER, fs.shader.shader); + for (uint32_t i = 0; i < pipeline.stageCount; i++) { + vkDestroyObject(demo->device, VK_OBJECT_TYPE_SHADER, shaderStages[i].shader); + } } static void demo_prepare_dynamic_states(struct demo *demo) diff --git a/demos/tri.c b/demos/tri.c index fd24944e..f36c90e6 100644 --- a/demos/tri.c +++ b/demos/tri.c @@ -153,7 +153,7 @@ struct demo { VkBuffer buf; VkDeviceMemory mem; - VkPipelineVertexInputCreateInfo vi; + VkPipelineVertexInputStateCreateInfo vi; VkVertexInputBindingDescription vi_bindings[1]; VkVertexInputAttributeDescription vi_attrs[2]; } vertices; @@ -782,7 +782,7 @@ static void demo_prepare_vertices(struct demo *demo) demo->vertices.mem, 0); assert(!err); - demo->vertices.vi.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO; + demo->vertices.vi.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; demo->vertices.vi.pNext = NULL; demo->vertices.vi.bindingCount = 1; demo->vertices.vi.pVertexBindingDescriptions = demo->vertices.vi_bindings; @@ -962,15 +962,15 @@ static VkShader demo_prepare_fs(struct demo *demo) static void demo_prepare_pipeline(struct demo *demo) { VkGraphicsPipelineCreateInfo pipeline; - VkPipelineVertexInputCreateInfo vi; + + VkPipelineVertexInputStateCreateInfo vi; VkPipelineIaStateCreateInfo ia; VkPipelineRsStateCreateInfo rs; VkPipelineCbStateCreateInfo cb; VkPipelineDsStateCreateInfo ds; - VkPipelineShaderStageCreateInfo vs; - VkPipelineShaderStageCreateInfo fs; VkPipelineVpStateCreateInfo vp; VkPipelineMsStateCreateInfo ms; + VkResult U_ASSERT_ONLY err; memset(&pipeline, 0, sizeof(pipeline)); @@ -1000,7 +1000,6 @@ static void demo_prepare_pipeline(struct demo *demo) cb.attachmentCount = 1; cb.pAttachments = att_state; - memset(&vp, 0, sizeof(vp)); vp.sType = VK_STRUCTURE_TYPE_PIPELINE_VP_STATE_CREATE_INFO; vp.viewportCount = 1; @@ -1019,38 +1018,41 @@ static void demo_prepare_pipeline(struct demo *demo) ds.stencilTestEnable = VK_FALSE; ds.front = ds.back; - memset(&vs, 0, sizeof(vs)); - vs.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - vs.shader.stage = VK_SHADER_STAGE_VERTEX; - vs.shader.shader = demo_prepare_vs(demo); - vs.shader.linkConstBufferCount = 0; - - memset(&fs, 0, sizeof(fs)); - fs.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - fs.shader.stage = VK_SHADER_STAGE_FRAGMENT; - fs.shader.shader = demo_prepare_fs(demo); - memset(&ms, 0, sizeof(ms)); ms.sType = VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO; ms.sampleMask = 1; ms.multisampleEnable = VK_FALSE; ms.samples = 1; - pipeline.pNext = (const void *) &vi; - vi.pNext = (void *) &ia; - ia.pNext = (const void *) &rs; - rs.pNext = (const void *) &cb; - cb.pNext = (const void *) &ms; - ms.pNext = (const void *) &vp; - vp.pNext = (const void *) &ds; - ds.pNext = (const void *) &vs; - vs.pNext = (const void *) &fs; + // Two stages: vs and fs + pipeline.stageCount = 2; + VkPipelineShaderStageCreateInfo shaderStages[2]; + memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo)); + + shaderStages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shaderStages[0].stage = VK_SHADER_STAGE_VERTEX; + shaderStages[0].shader = demo_prepare_vs(demo); + shaderStages[0].linkConstBufferCount = 0; + + shaderStages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shaderStages[1].stage = VK_SHADER_STAGE_FRAGMENT; + shaderStages[1].shader = demo_prepare_fs(demo); + + pipeline.pVertexInputState = &vi; + pipeline.pIaState = &ia; + pipeline.pRsState = &rs; + pipeline.pCbState = &cb; + pipeline.pMsState = &ms; + pipeline.pVpState = &vp; + pipeline.pDsState = &ds; + pipeline.pStages = shaderStages; err = vkCreateGraphicsPipeline(demo->device, &pipeline, &demo->pipeline); assert(!err); - vkDestroyObject(demo->device, VK_OBJECT_TYPE_SHADER, vs.shader.shader); - vkDestroyObject(demo->device, VK_OBJECT_TYPE_SHADER, fs.shader.shader); + for (uint32_t i = 0; i < pipeline.stageCount; i++) { + vkDestroyObject(demo->device, VK_OBJECT_TYPE_SHADER, shaderStages[i].shader); + } } static void demo_prepare_dynamic_states(struct demo *demo) diff --git a/include/vulkan.h b/include/vulkan.h index 417ca940..cdea6f33 100644 --- a/include/vulkan.h +++ b/include/vulkan.h @@ -33,7 +33,7 @@ #include "vk_platform.h" // Vulkan API version supported by this file -#define VK_API_VERSION VK_MAKE_VERSION(0, 103, 0) +#define VK_API_VERSION VK_MAKE_VERSION(0, 104, 0) #ifdef __cplusplus extern "C" @@ -810,7 +810,7 @@ typedef enum VkStructureType_ VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO = 23, VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO = 24, VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO = 25, - VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO = 26, + VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO = 26, VK_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO = 27, VK_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO = 28, VK_STRUCTURE_TYPE_PIPELINE_VP_STATE_CREATE_INFO = 29, @@ -1688,20 +1688,22 @@ typedef struct VkSpecializationInfo_ const void* pData; } VkSpecializationInfo; -typedef struct VkPipelineShader_ +typedef struct VkPipelineShaderStageCreateInfo_ { + VkStructureType sType; // Must be VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO + const void* pNext; // Pointer to next structure VkShaderStage stage; VkShader shader; uint32_t linkConstBufferCount; const VkLinkConstBuffer* pLinkConstBufferInfo; const VkSpecializationInfo* pSpecializationInfo; -} VkPipelineShader; +} VkPipelineShaderStageCreateInfo; typedef struct VkComputePipelineCreateInfo_ { VkStructureType sType; // Must be VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO const void* pNext; // Pointer to next structure - VkPipelineShader cs; + VkPipelineShaderStageCreateInfo cs; VkPipelineCreateFlags flags; // Pipeline creation flags VkPipelineLayout layout; // Interface layout of the pipeline } VkComputePipelineCreateInfo; @@ -1724,9 +1726,9 @@ typedef struct VkVertexInputAttributeDescription_ uint32_t offsetInBytes; // Offset of first element in bytes from base of vertex } VkVertexInputAttributeDescription; -typedef struct VkPipelineVertexInputCreateInfo_ +typedef struct VkPipelineVertexInputStateCreateInfo_ { - VkStructureType sType; // Should be VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO + VkStructureType sType; // Should be VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO const void* pNext; // Pointer to next structure uint32_t bindingCount; // number of bindings @@ -1734,7 +1736,7 @@ typedef struct VkPipelineVertexInputCreateInfo_ uint32_t attributeCount; // number of attributes const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; -} VkPipelineVertexInputCreateInfo; +} VkPipelineVertexInputStateCreateInfo; typedef struct VkPipelineIaStateCreateInfo_ { @@ -1832,17 +1834,20 @@ typedef struct VkPipelineDsStateCreateInfo_ VkStencilOpState back; } VkPipelineDsStateCreateInfo; -typedef struct VkPipelineShaderStageCreateInfo_ -{ - VkStructureType sType; // Must be VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO - const void* pNext; // Pointer to next structure - VkPipelineShader shader; -} VkPipelineShaderStageCreateInfo; - typedef struct VkGraphicsPipelineCreateInfo_ { VkStructureType sType; // Must be VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO const void* pNext; // Pointer to next structure + uint32_t stageCount; + const VkPipelineShaderStageCreateInfo* pStages; // One entry for each active shader stage + const VkPipelineVertexInputStateCreateInfo* pVertexInputState; + const VkPipelineIaStateCreateInfo* pIaState; + const VkPipelineTessStateCreateInfo* pTessState; + const VkPipelineVpStateCreateInfo* pVpState; + const VkPipelineRsStateCreateInfo* pRsState; + const VkPipelineMsStateCreateInfo* pMsState; + const VkPipelineDsStateCreateInfo* pDsState; + const VkPipelineCbStateCreateInfo* pCbState; VkPipelineCreateFlags flags; // Pipeline creation flags VkPipelineLayout layout; // Interface layout of the pipeline } VkGraphicsPipelineCreateInfo; diff --git a/layers/draw_state.cpp b/layers/draw_state.cpp index a74af764..992c85d3 100644 --- a/layers/draw_state.cpp +++ b/layers/draw_state.cpp @@ -487,135 +487,122 @@ static PIPELINE_NODE* initPipeline(const VkGraphicsPipelineCreateInfo* pCreateIn } else { memset((void*)pPipeline, 0, sizeof(PIPELINE_NODE)); } - // First init create info, we'll shadow the structs as we go down the tree + // First init create info // TODO : Validate that no create info is incorrectly replicated memcpy(&pPipeline->graphicsPipelineCI, pCreateInfo, sizeof(VkGraphicsPipelineCreateInfo)); - GENERIC_HEADER* pTrav = (GENERIC_HEADER*)pCreateInfo->pNext; - GENERIC_HEADER* pPrev = (GENERIC_HEADER*)&pPipeline->graphicsPipelineCI; // Hold prev ptr to tie chain of structs together + size_t bufferSize = 0; - VkPipelineVertexInputCreateInfo* pVICI = NULL; - VkPipelineCbStateCreateInfo* pCBCI = NULL; - VkPipelineShaderStageCreateInfo* pTmpPSSCI = NULL; - while (pTrav) { - switch (pTrav->sType) { - case VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO: - pTmpPSSCI = (VkPipelineShaderStageCreateInfo*)pTrav; - switch (pTmpPSSCI->shader.stage) { - case VK_SHADER_STAGE_VERTEX: - pPrev->pNext = &pPipeline->vsCI; - pPrev = (GENERIC_HEADER*)&pPipeline->vsCI; - memcpy(&pPipeline->vsCI, pTmpPSSCI, sizeof(VkPipelineShaderStageCreateInfo)); - pPipeline->active_shaders |= VK_SHADER_STAGE_VERTEX_BIT; - break; - case VK_SHADER_STAGE_TESS_CONTROL: - pPrev->pNext = &pPipeline->tcsCI; - pPrev = (GENERIC_HEADER*)&pPipeline->tcsCI; - memcpy(&pPipeline->tcsCI, pTmpPSSCI, sizeof(VkPipelineShaderStageCreateInfo)); - pPipeline->active_shaders |= VK_SHADER_STAGE_TESS_CONTROL_BIT; - break; - case VK_SHADER_STAGE_TESS_EVALUATION: - pPrev->pNext = &pPipeline->tesCI; - pPrev = (GENERIC_HEADER*)&pPipeline->tesCI; - memcpy(&pPipeline->tesCI, pTmpPSSCI, sizeof(VkPipelineShaderStageCreateInfo)); - pPipeline->active_shaders |= VK_SHADER_STAGE_TESS_EVALUATION_BIT; - break; - case VK_SHADER_STAGE_GEOMETRY: - pPrev->pNext = &pPipeline->gsCI; - pPrev = (GENERIC_HEADER*)&pPipeline->gsCI; - memcpy(&pPipeline->gsCI, pTmpPSSCI, sizeof(VkPipelineShaderStageCreateInfo)); - pPipeline->active_shaders |= VK_SHADER_STAGE_GEOMETRY_BIT; - break; - case VK_SHADER_STAGE_FRAGMENT: - pPrev->pNext = &pPipeline->fsCI; - pPrev = (GENERIC_HEADER*)&pPipeline->fsCI; - memcpy(&pPipeline->fsCI, pTmpPSSCI, sizeof(VkPipelineShaderStageCreateInfo)); - pPipeline->active_shaders |= VK_SHADER_STAGE_FRAGMENT_BIT; - break; - case VK_SHADER_STAGE_COMPUTE: - // TODO : Flag error, CS is specified through VkComputePipelineCreateInfo - pPipeline->active_shaders |= VK_SHADER_STAGE_COMPUTE_BIT; - break; - default: - // TODO : Flag error - break; - } - break; - case VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO: - pPrev->pNext = &pPipeline->vertexInputCI; - pPrev = (GENERIC_HEADER*)&pPipeline->vertexInputCI; - memcpy((void*)&pPipeline->vertexInputCI, pTrav, sizeof(VkPipelineVertexInputCreateInfo)); - // Copy embedded ptrs - pVICI = (VkPipelineVertexInputCreateInfo*)pTrav; - pPipeline->vtxBindingCount = pVICI->bindingCount; - if (pPipeline->vtxBindingCount) { - pPipeline->pVertexBindingDescriptions = new VkVertexInputBindingDescription[pPipeline->vtxBindingCount]; - bufferSize = pPipeline->vtxBindingCount * sizeof(VkVertexInputBindingDescription); - memcpy((void*)pPipeline->pVertexBindingDescriptions, ((VkPipelineVertexInputCreateInfo*)pTrav)->pVertexBindingDescriptions, bufferSize); - } - pPipeline->vtxAttributeCount = pVICI->attributeCount; - if (pPipeline->vtxAttributeCount) { - pPipeline->pVertexAttributeDescriptions = new VkVertexInputAttributeDescription[pPipeline->vtxAttributeCount]; - bufferSize = pPipeline->vtxAttributeCount * sizeof(VkVertexInputAttributeDescription); - memcpy((void*)pPipeline->pVertexAttributeDescriptions, ((VkPipelineVertexInputCreateInfo*)pTrav)->pVertexAttributeDescriptions, bufferSize); - } - break; - case VK_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO: - pPrev->pNext = &pPipeline->iaStateCI; - pPrev = (GENERIC_HEADER*)&pPipeline->iaStateCI; - memcpy((void*)&pPipeline->iaStateCI, pTrav, sizeof(VkPipelineIaStateCreateInfo)); - break; - case VK_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO: - pPrev->pNext = &pPipeline->tessStateCI; - pPrev = (GENERIC_HEADER*)&pPipeline->tessStateCI; - memcpy((void*)&pPipeline->tessStateCI, pTrav, sizeof(VkPipelineTessStateCreateInfo)); + const VkPipelineVertexInputStateCreateInfo* pVICI = NULL; + const VkPipelineCbStateCreateInfo* 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: + memcpy(&pPipeline->vsCI, pPSSCI, sizeof(VkPipelineShaderStageCreateInfo)); + pPipeline->active_shaders |= VK_SHADER_STAGE_VERTEX_BIT; break; - case VK_STRUCTURE_TYPE_PIPELINE_VP_STATE_CREATE_INFO: - pPrev->pNext = &pPipeline->vpStateCI; - pPrev = (GENERIC_HEADER*)&pPipeline->vpStateCI; - memcpy((void*)&pPipeline->vpStateCI, pTrav, sizeof(VkPipelineVpStateCreateInfo)); + case VK_SHADER_STAGE_TESS_CONTROL: + memcpy(&pPipeline->tcsCI, pPSSCI, sizeof(VkPipelineShaderStageCreateInfo)); + pPipeline->active_shaders |= VK_SHADER_STAGE_TESS_CONTROL_BIT; break; - case VK_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO: - pPrev->pNext = &pPipeline->rsStateCI; - pPrev = (GENERIC_HEADER*)&pPipeline->rsStateCI; - memcpy((void*)&pPipeline->rsStateCI, pTrav, sizeof(VkPipelineRsStateCreateInfo)); + case VK_SHADER_STAGE_TESS_EVALUATION: + memcpy(&pPipeline->tesCI, pPSSCI, sizeof(VkPipelineShaderStageCreateInfo)); + pPipeline->active_shaders |= VK_SHADER_STAGE_TESS_EVALUATION_BIT; break; - case VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO: - pPrev->pNext = &pPipeline->msStateCI; - pPrev = (GENERIC_HEADER*)&pPipeline->msStateCI; - memcpy((void*)&pPipeline->msStateCI, pTrav, sizeof(VkPipelineMsStateCreateInfo)); + case VK_SHADER_STAGE_GEOMETRY: + memcpy(&pPipeline->gsCI, pPSSCI, sizeof(VkPipelineShaderStageCreateInfo)); + pPipeline->active_shaders |= VK_SHADER_STAGE_GEOMETRY_BIT; break; - case VK_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO: - pPrev->pNext = &pPipeline->cbStateCI; - pPrev = (GENERIC_HEADER*)&pPipeline->cbStateCI; - memcpy((void*)&pPipeline->cbStateCI, pTrav, sizeof(VkPipelineCbStateCreateInfo)); - // Copy embedded ptrs - pCBCI = (VkPipelineCbStateCreateInfo*)pTrav; - pPipeline->attachmentCount = pCBCI->attachmentCount; - if (pPipeline->attachmentCount) { - pPipeline->pAttachments = new VkPipelineCbAttachmentState[pPipeline->attachmentCount]; - bufferSize = pPipeline->attachmentCount * sizeof(VkPipelineCbAttachmentState); - memcpy((void*)pPipeline->pAttachments, ((VkPipelineCbStateCreateInfo*)pTrav)->pAttachments, bufferSize); - } + case VK_SHADER_STAGE_FRAGMENT: + memcpy(&pPipeline->fsCI, pPSSCI, sizeof(VkPipelineShaderStageCreateInfo)); + pPipeline->active_shaders |= VK_SHADER_STAGE_FRAGMENT_BIT; break; - case VK_STRUCTURE_TYPE_PIPELINE_DS_STATE_CREATE_INFO: - pPrev->pNext = &pPipeline->dsStateCI; - pPrev = (GENERIC_HEADER*)&pPipeline->dsStateCI; - memcpy((void*)&pPipeline->dsStateCI, pTrav, sizeof(VkPipelineDsStateCreateInfo)); + case VK_SHADER_STAGE_COMPUTE: + // TODO : Flag error, CS is specified through VkComputePipelineCreateInfo + pPipeline->active_shaders |= VK_SHADER_STAGE_COMPUTE_BIT; break; default: - assert(0); + // TODO : Flag error break; } - pTrav = (GENERIC_HEADER*)pTrav->pNext; } + + if (pCreateInfo->pVertexInputState != NULL) { + memcpy((void*)&pPipeline->vertexInputCI, pCreateInfo->pVertexInputState , sizeof(VkPipelineVertexInputStateCreateInfo)); + // Copy embedded ptrs + pVICI = pCreateInfo->pVertexInputState; + pPipeline->vtxBindingCount = pVICI->bindingCount; + if (pPipeline->vtxBindingCount) { + pPipeline->pVertexBindingDescriptions = new VkVertexInputBindingDescription[pPipeline->vtxBindingCount]; + bufferSize = pPipeline->vtxBindingCount * sizeof(VkVertexInputBindingDescription); + memcpy((void*)pPipeline->pVertexBindingDescriptions, pVICI->pVertexBindingDescriptions, bufferSize); + } + pPipeline->vtxAttributeCount = pVICI->attributeCount; + if (pPipeline->vtxAttributeCount) { + pPipeline->pVertexAttributeDescriptions = new VkVertexInputAttributeDescription[pPipeline->vtxAttributeCount]; + bufferSize = pPipeline->vtxAttributeCount * sizeof(VkVertexInputAttributeDescription); + memcpy((void*)pPipeline->pVertexAttributeDescriptions, pVICI->pVertexAttributeDescriptions, bufferSize); + } + pPipeline->graphicsPipelineCI.pVertexInputState = &pPipeline->vertexInputCI; + } + if (pCreateInfo->pIaState != NULL) { + memcpy((void*)&pPipeline->iaStateCI, pCreateInfo->pIaState, sizeof(VkPipelineIaStateCreateInfo)); + pPipeline->graphicsPipelineCI.pIaState = &pPipeline->iaStateCI; + } + if (pCreateInfo->pTessState != NULL) { + memcpy((void*)&pPipeline->tessStateCI, pCreateInfo->pTessState, sizeof(VkPipelineTessStateCreateInfo)); + pPipeline->graphicsPipelineCI.pTessState = &pPipeline->tessStateCI; + } + if (pCreateInfo->pVpState != NULL) { + memcpy((void*)&pPipeline->vpStateCI, pCreateInfo->pVpState, sizeof(VkPipelineVpStateCreateInfo)); + pPipeline->graphicsPipelineCI.pVpState = &pPipeline->vpStateCI; + } + if (pCreateInfo->pRsState != NULL) { + memcpy((void*)&pPipeline->rsStateCI, pCreateInfo->pRsState, sizeof(VkPipelineRsStateCreateInfo)); + pPipeline->graphicsPipelineCI.pRsState = &pPipeline->rsStateCI; + } + if (pCreateInfo->pMsState != NULL) { + memcpy((void*)&pPipeline->msStateCI, pCreateInfo->pMsState, sizeof(VkPipelineMsStateCreateInfo)); + pPipeline->graphicsPipelineCI.pMsState = &pPipeline->msStateCI; + } + if (pCreateInfo->pCbState != NULL) { + memcpy((void*)&pPipeline->cbStateCI, pCreateInfo->pCbState, sizeof(VkPipelineCbStateCreateInfo)); + // Copy embedded ptrs + pCBCI = pCreateInfo->pCbState; + pPipeline->attachmentCount = pCBCI->attachmentCount; + if (pPipeline->attachmentCount) { + pPipeline->pAttachments = new VkPipelineCbAttachmentState[pPipeline->attachmentCount]; + bufferSize = pPipeline->attachmentCount * sizeof(VkPipelineCbAttachmentState); + memcpy((void*)pPipeline->pAttachments, pCBCI->pAttachments, bufferSize); + } + pPipeline->graphicsPipelineCI.pCbState = &pPipeline->cbStateCI; + } + if (pCreateInfo->pDsState != NULL) { + memcpy((void*)&pPipeline->dsStateCI, pCreateInfo->pDsState, sizeof(VkPipelineDsStateCreateInfo)); + pPipeline->graphicsPipelineCI.pDsState = &pPipeline->dsStateCI; + } + + // 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); + } + return pPipeline; } + // Free the Pipeline nodes static void deletePipelines() { if (pipelineMap.size() <= 0) return; for (unordered_map::iterator ii=pipelineMap.begin(); ii!=pipelineMap.end(); ++ii) { + if ((*ii).second->graphicsPipelineCI.stageCount != 0) { + delete[] (*ii).second->graphicsPipelineCI.pStages; + } if ((*ii).second->pVertexBindingDescriptions) { delete[] (*ii).second->pVertexBindingDescriptions; } diff --git a/layers/draw_state.h b/layers/draw_state.h index 668d644a..40f7f9d1 100644 --- a/layers/draw_state.h +++ b/layers/draw_state.h @@ -79,33 +79,33 @@ typedef struct _GENERIC_HEADER { } GENERIC_HEADER; typedef struct _PIPELINE_NODE { - VkPipeline pipeline; - VkGraphicsPipelineCreateInfo graphicsPipelineCI; - VkPipelineVertexInputCreateInfo vertexInputCI; - VkPipelineIaStateCreateInfo iaStateCI; - VkPipelineTessStateCreateInfo tessStateCI; - VkPipelineVpStateCreateInfo vpStateCI; - VkPipelineRsStateCreateInfo rsStateCI; - VkPipelineMsStateCreateInfo msStateCI; - VkPipelineCbStateCreateInfo cbStateCI; - VkPipelineDsStateCreateInfo dsStateCI; - VkPipelineShaderStageCreateInfo vsCI; - VkPipelineShaderStageCreateInfo tcsCI; - VkPipelineShaderStageCreateInfo tesCI; - VkPipelineShaderStageCreateInfo gsCI; - VkPipelineShaderStageCreateInfo fsCI; + VkPipeline pipeline; + VkGraphicsPipelineCreateInfo graphicsPipelineCI; + VkPipelineVertexInputStateCreateInfo vertexInputCI; + VkPipelineIaStateCreateInfo iaStateCI; + VkPipelineTessStateCreateInfo tessStateCI; + VkPipelineVpStateCreateInfo vpStateCI; + VkPipelineRsStateCreateInfo rsStateCI; + VkPipelineMsStateCreateInfo msStateCI; + VkPipelineCbStateCreateInfo cbStateCI; + VkPipelineDsStateCreateInfo dsStateCI; + VkPipelineShaderStageCreateInfo vsCI; + VkPipelineShaderStageCreateInfo tcsCI; + VkPipelineShaderStageCreateInfo tesCI; + VkPipelineShaderStageCreateInfo gsCI; + VkPipelineShaderStageCreateInfo fsCI; // Compute shader is include in VkComputePipelineCreateInfo - VkComputePipelineCreateInfo computePipelineCI; + VkComputePipelineCreateInfo computePipelineCI; // Flag of which shader stages are active for this pipeline - uint32_t active_shaders; - VkGraphicsPipelineCreateInfo* pCreateTree; // Ptr to shadow of data in create tree + uint32_t active_shaders; + VkGraphicsPipelineCreateInfo* pCreateTree; // Ptr to shadow of data in create tree // Vtx input info (if any) - uint32_t vtxBindingCount; // number of bindings - VkVertexInputBindingDescription* pVertexBindingDescriptions; - uint32_t vtxAttributeCount; // number of attributes - VkVertexInputAttributeDescription* pVertexAttributeDescriptions; - uint32_t attachmentCount; // number of CB attachments - VkPipelineCbAttachmentState* pAttachments; + uint32_t vtxBindingCount; // number of bindings + VkVertexInputBindingDescription* pVertexBindingDescriptions; + uint32_t vtxAttributeCount; // number of attributes + VkVertexInputAttributeDescription* pVertexAttributeDescriptions; + uint32_t attachmentCount; // number of CB attachments + VkPipelineCbAttachmentState* pAttachments; } PIPELINE_NODE; typedef struct _SAMPLER_NODE { diff --git a/layers/shader_checker.cpp b/layers/shader_checker.cpp index e0ab544f..4ab46c3c 100644 --- a/layers/shader_checker.cpp +++ b/layers/shader_checker.cpp @@ -628,7 +628,7 @@ get_fundamental_type(shader_source const *src, unsigned type) static bool -validate_vi_consistency(VkPipelineVertexInputCreateInfo const *vi) +validate_vi_consistency(VkPipelineVertexInputStateCreateInfo const *vi) { /* walk the binding descriptions, which describe the step rate and stride of each vertex buffer. * each binding should be specified only once. @@ -655,7 +655,7 @@ validate_vi_consistency(VkPipelineVertexInputCreateInfo const *vi) static bool -validate_vi_against_vs_inputs(VkPipelineVertexInputCreateInfo const *vi, shader_source const *vs) +validate_vi_against_vs_inputs(VkPipelineVertexInputStateCreateInfo const *vi, shader_source const *vs) { std::map inputs; /* we collect builtin inputs, but they will never appear in the VI state -- @@ -819,32 +819,29 @@ validate_graphics_pipeline(VkGraphicsPipelineCreateInfo const *pCreateInfo) shader_source const *shaders[VK_SHADER_STAGE_FRAGMENT + 1]; /* exclude CS */ memset(shaders, 0, sizeof(shaders)); VkPipelineCbStateCreateInfo const *cb = 0; - VkPipelineVertexInputCreateInfo const *vi = 0; + VkPipelineVertexInputStateCreateInfo const *vi = 0; char str[1024]; bool pass = true; loader_platform_thread_lock_mutex(&globalLock); - for (auto stage = pCreateInfo; stage; stage = (decltype(stage))stage->pNext) { - if (stage->sType == VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO) { - auto shader_stage = (VkPipelineShaderStageCreateInfo const *)stage; + for (auto i = 0; i < pCreateInfo->stageCount; i++) { + VkPipelineShaderStageCreateInfo const *pStage = &pCreateInfo->pStages[i]; + if (pStage->sType == VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO) { - if (shader_stage->shader.stage < VK_SHADER_STAGE_VERTEX || shader_stage->shader.stage > VK_SHADER_STAGE_FRAGMENT) { - sprintf(str, "Unknown shader stage %d\n", shader_stage->shader.stage); + if (pStage->stage < VK_SHADER_STAGE_VERTEX || pStage->stage > VK_SHADER_STAGE_FRAGMENT) { + sprintf(str, "Unknown shader stage %d\n", pStage->stage); layerCbMsg(VK_DBG_REPORT_WARN_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_UNKNOWN_STAGE, "SC", str); } else { - shaders[shader_stage->shader.stage] = shader_map[(void *)(shader_stage->shader.shader)]; + shaders[pStage->stage] = shader_map[(void *)(pStage->shader)]; } } - else if (stage->sType == VK_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO) { - cb = (VkPipelineCbStateCreateInfo const *)stage; - } - else if (stage->sType == VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO) { - vi = (VkPipelineVertexInputCreateInfo const *)stage; - } } + cb = pCreateInfo->pCbState; + vi = pCreateInfo->pVertexInputState; + if (vi) { pass = validate_vi_consistency(vi) && pass; } -- cgit v1.2.3