layers: Add VBO validation to DrawState layer.
diff --git a/layers/draw_state.c b/layers/draw_state.c
index 511ac84..1ad7667 100644
--- a/layers/draw_state.c
+++ b/layers/draw_state.c
@@ -172,6 +172,11 @@
PIPELINE_LL_HEADER *pCreateTree; // Ptr to shadow of data in create tree
// 1st dimension of array is shader type
SHADER_DS_MAPPING dsMapping[XGL_NUM_GRAPHICS_SHADERS][XGL_MAX_DESCRIPTOR_SETS];
+ // Vtx input info (if any)
+ XGL_UINT vtxBindingCount; // number of bindings
+ XGL_VERTEX_INPUT_BINDING_DESCRIPTION* pVertexBindingDescriptions;
+ XGL_UINT vtxAttributeCount; // number of attributes
+ XGL_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION* pVertexAttributeDescriptions;
} PIPELINE_NODE;
typedef struct _SAMPLER_NODE {
@@ -183,6 +188,8 @@
static PIPELINE_NODE *pPipelineHead = NULL;
static SAMPLER_NODE *pSamplerHead = NULL;
static XGL_PIPELINE lastBoundPipeline = NULL;
+#define MAX_BINDING 0xFFFFFFFF
+static XGL_UINT lastVtxBinding = MAX_BINDING;
static PIPELINE_NODE *getPipeline(XGL_PIPELINE pipeline)
{
@@ -221,9 +228,10 @@
// Typically pNext is const so have to cast to avoid warning when we modify it here
memcpy((void*)pShadowTrav->pNext, pTrav, sTypeStructSize(pTrav->sType));
pShadowTrav = (PIPELINE_LL_HEADER*)pShadowTrav->pNext;
+ // TODO : Now that we shadow whole create info, the special copies are just a convenience that can be done away with once shadow is complete and correct
// Special copy of DS Mapping info
if (XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO == pTrav->sType) {
- XGL_PIPELINE_SHADER_STAGE_CREATE_INFO* pSSCI = (XGL_PIPELINE_SHADER_STAGE_CREATE_INFO*)pTrav;
+ XGL_PIPELINE_SHADER_STAGE_CREATE_INFO *pSSCI = (XGL_PIPELINE_SHADER_STAGE_CREATE_INFO*)pTrav;
for (uint32_t i = 0; i < XGL_MAX_DESCRIPTOR_SETS; i++) {
if (pSSCI->shader.descriptorSetMapping[i].descriptorCount > MAX_SLOTS) {
char str[1024];
@@ -237,6 +245,18 @@
memcpy(pPipeline->dsMapping[pSSCI->shader.stage][i].pShaderMappingSlot, pSSCI->shader.descriptorSetMapping[i].pDescriptorInfo, sizeof(XGL_DESCRIPTOR_SLOT_INFO)*pPipeline->dsMapping[pSSCI->shader.stage][i].slotCount);
}
}
+ else if (XGL_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO == pTrav->sType) {
+ // Special copy of Vtx info
+ XGL_PIPELINE_VERTEX_INPUT_CREATE_INFO *pVICI = (XGL_PIPELINE_VERTEX_INPUT_CREATE_INFO*)pTrav;
+ pPipeline->vtxBindingCount = pVICI->bindingCount;
+ uint32_t allocSize = pPipeline->vtxBindingCount * sizeof(XGL_VERTEX_INPUT_BINDING_DESCRIPTION);
+ pPipeline->pVertexBindingDescriptions = (XGL_VERTEX_INPUT_BINDING_DESCRIPTION*)malloc(allocSize);
+ memcpy(pPipeline->pVertexBindingDescriptions, pVICI->pVertexAttributeDescriptions, allocSize);
+ pPipeline->vtxAttributeCount = pVICI->attributeCount;
+ allocSize = pPipeline->vtxAttributeCount * sizeof(XGL_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION);
+ pPipeline->pVertexAttributeDescriptions = (XGL_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION*)malloc(allocSize);
+ memcpy(pPipeline->pVertexAttributeDescriptions, pVICI->pVertexAttributeDescriptions, allocSize);
+ }
pTrav = (PIPELINE_LL_HEADER*)pTrav->pNext;
}
}
@@ -447,6 +467,7 @@
layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NO_PIPELINE_BOUND, "DS", str);
}
else {
+ // Synch Descriptor Set Mapping
for (uint32_t i = 0; i < XGL_MAX_DESCRIPTOR_SETS; i++) {
DS_LL_HEAD *pDS;
if (lastBoundDS[i]) {
@@ -481,11 +502,23 @@
}
}
if (0 == dsUsed) {
- sprintf(str, "It appears that no DS was bound to index %u, but no shaders are using that DS so this is not an issue.", i);
+ sprintf(str, "No DS was bound to index %u, but no shaders are using that DS so this is not an issue.", i);
layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", str);
}
}
}
+ // Verify Vtx binding
+ if (MAX_BINDING != lastVtxBinding) {
+ if (lastVtxBinding >= pPipeTrav->vtxBindingCount) {
+ sprintf(str, "Vtx binding Index of %u exceeds PSO pVertexBindingDescriptions max array index of %u.", lastVtxBinding, (pPipeTrav->vtxBindingCount - 1));
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, "DS", str);
+ }
+ else {
+ char *tmpStr = xgl_print_xgl_vertex_input_binding_description(&pPipeTrav->pVertexBindingDescriptions[lastVtxBinding], "{DS}INFO : ");
+ layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", tmpStr);
+ free(tmpStr);
+ }
+ }
}
}
@@ -1462,6 +1495,7 @@
XGL_LAYER_EXPORT XGL_VOID XGLAPI xglCmdBindVertexData(XGL_CMD_BUFFER cmdBuffer, XGL_GPU_MEMORY mem, XGL_GPU_SIZE offset, XGL_UINT binding)
{
+ lastVtxBinding = binding;
nextTable.CmdBindVertexData(cmdBuffer, mem, offset, binding);
}