aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--demos/cube.c15
-rw-r--r--demos/tri.c15
-rw-r--r--demos/xglinfo.c8
-rw-r--r--layers/draw_state.cpp211
-rw-r--r--layers/draw_state.h24
-rw-r--r--loader/loader.c8
6 files changed, 226 insertions, 55 deletions
diff --git a/demos/cube.c b/demos/cube.c
index dca54328..920a542f 100644
--- a/demos/cube.c
+++ b/demos/cube.c
@@ -1700,7 +1700,14 @@ static void demo_init_xgl(struct demo *demo)
uint32_t i;
err = xglCreateInstance(&app, NULL, &demo->inst);
- assert(!err);
+ if (err == XGL_ERROR_INCOMPATIBLE_DRIVER) {
+ printf("Cannot find a compatible Vulkan installable client driver "
+ "(ICD).\nExiting ...\n");
+ fflush(stdout);
+ exit(1);
+ } else {
+ assert(!err);
+ }
err = xglEnumerateGpus(demo->inst, 1, &gpu_count, &demo->gpu);
assert(!err && gpu_count == 1);
@@ -1727,6 +1734,12 @@ static void demo_init_connection(struct demo *demo)
int scr;
demo->connection = xcb_connect(NULL, &scr);
+ if (demo->connection == NULL) {
+ printf("Cannot find a compatible Vulkan installable client driver "
+ "(ICD).\nExiting ...\n");
+ fflush(stdout);
+ exit(1);
+ }
setup = xcb_get_setup(demo->connection);
iter = xcb_setup_roots_iterator(setup);
diff --git a/demos/tri.c b/demos/tri.c
index dfee0634..23c601ba 100644
--- a/demos/tri.c
+++ b/demos/tri.c
@@ -1323,7 +1323,14 @@ static void demo_init_xgl(struct demo *demo)
uint32_t i;
err = xglCreateInstance(&app, NULL, &demo->inst);
- assert(!err);
+ if (err == XGL_ERROR_INCOMPATIBLE_DRIVER) {
+ printf("Cannot find a compatible Vulkan installable client driver "
+ "(ICD).\nExiting ...\n");
+ fflush(stdout);
+ exit(1);
+ } else {
+ assert(!err);
+ }
err = xglEnumerateGpus(demo->inst, 1, &gpu_count, &demo->gpu);
assert(!err && gpu_count == 1);
@@ -1353,6 +1360,12 @@ static void demo_init_connection(struct demo *demo)
int scr;
demo->connection = xcb_connect(NULL, &scr);
+ if (demo->connection == NULL) {
+ printf("Cannot find a compatible Vulkan installable client driver "
+ "(ICD).\nExiting ...\n");
+ fflush(stdout);
+ exit(1);
+ }
setup = xcb_get_setup(demo->connection);
iter = xcb_setup_roots_iterator(setup);
diff --git a/demos/xglinfo.c b/demos/xglinfo.c
index 4544c23d..e0887a20 100644
--- a/demos/xglinfo.c
+++ b/demos/xglinfo.c
@@ -659,8 +659,14 @@ int main(int argc, char **argv)
XGL_RESULT err;
err = xglCreateInstance(&app_info, NULL, &inst);
- if (err)
+ if (err == XGL_ERROR_INCOMPATIBLE_DRIVER) {
+ printf("Cannot find a compatible Vulkan installable client driver "
+ "(ICD).\nExiting ...\n");
+ fflush(stdout);
+ exit(1);
+ } else if (err) {
ERR_EXIT(err);
+ }
err = xglEnumerateGpus(inst, MAX_GPUS, &gpu_count, objs);
if (err)
ERR_EXIT(err);
diff --git a/layers/draw_state.cpp b/layers/draw_state.cpp
index 4d58a945..9dbabae9 100644
--- a/layers/draw_state.cpp
+++ b/layers/draw_state.cpp
@@ -50,6 +50,8 @@ unordered_map<XGL_DESCRIPTOR_REGION, REGION_NODE*> regionMap;
unordered_map<XGL_DESCRIPTOR_SET, SET_NODE*> setMap;
unordered_map<XGL_DESCRIPTOR_SET_LAYOUT, LAYOUT_NODE*> layoutMap;
unordered_map<XGL_CMD_BUFFER, GLOBAL_CB_NODE*> cmdBufferMap;
+unordered_map<XGL_RENDER_PASS, XGL_RENDER_PASS_CREATE_INFO*> renderPassMap;
+unordered_map<XGL_FRAMEBUFFER, XGL_FRAMEBUFFER_CREATE_INFO*> frameBufferMap;
static XGL_LAYER_DISPATCH_TABLE nextTable;
static XGL_BASE_LAYER_OBJECT *pCurObj;
@@ -357,22 +359,56 @@ static XGL_SAMPLER_CREATE_INFO* getSamplerCreateInfo(const XGL_SAMPLER sampler)
static void initPipeline(PIPELINE_NODE* pPipeline, const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo)
{
// First init create info, we'll shadow the structs as we go down the tree
- pPipeline->pCreateTree = new XGL_GRAPHICS_PIPELINE_CREATE_INFO;
- memcpy(pPipeline->pCreateTree, pCreateInfo, sizeof(XGL_GRAPHICS_PIPELINE_CREATE_INFO));
- GENERIC_HEADER* pShadowTrav = (GENERIC_HEADER*)pPipeline->pCreateTree;
+ // TODO : Validate that no create info is incorrectly replicated
+ memcpy(&pPipeline->graphicsPipelineCI, pCreateInfo, sizeof(XGL_GRAPHICS_PIPELINE_CREATE_INFO));
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;
XGL_PIPELINE_VERTEX_INPUT_CREATE_INFO* pVICI = NULL;
XGL_PIPELINE_CB_STATE_CREATE_INFO* pCBCI = NULL;
+ XGL_PIPELINE_SHADER_STAGE_CREATE_INFO* pTmpPSSCI = NULL;
while (pTrav) {
switch (pTrav->sType) {
case XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO:
- pShadowTrav->pNext = new XGL_PIPELINE_SHADER_STAGE_CREATE_INFO;
- memcpy((void*)pShadowTrav->pNext, pTrav, sizeof(XGL_PIPELINE_SHADER_STAGE_CREATE_INFO));
+ pTmpPSSCI = (XGL_PIPELINE_SHADER_STAGE_CREATE_INFO*)pTrav;
+ switch (pTmpPSSCI->shader.stage) {
+ case XGL_SHADER_STAGE_VERTEX:
+ pPrev->pNext = &pPipeline->vsCI;
+ pPrev = (GENERIC_HEADER*)&pPipeline->vsCI;
+ memcpy(&pPipeline->vsCI, pTmpPSSCI, sizeof(XGL_PIPELINE_SHADER_STAGE_CREATE_INFO));
+ break;
+ case XGL_SHADER_STAGE_TESS_CONTROL:
+ pPrev->pNext = &pPipeline->tcsCI;
+ pPrev = (GENERIC_HEADER*)&pPipeline->tcsCI;
+ memcpy(&pPipeline->tcsCI, pTmpPSSCI, sizeof(XGL_PIPELINE_SHADER_STAGE_CREATE_INFO));
+ break;
+ case XGL_SHADER_STAGE_TESS_EVALUATION:
+ pPrev->pNext = &pPipeline->tesCI;
+ pPrev = (GENERIC_HEADER*)&pPipeline->tesCI;
+ memcpy(&pPipeline->tesCI, pTmpPSSCI, sizeof(XGL_PIPELINE_SHADER_STAGE_CREATE_INFO));
+ break;
+ case XGL_SHADER_STAGE_GEOMETRY:
+ pPrev->pNext = &pPipeline->gsCI;
+ pPrev = (GENERIC_HEADER*)&pPipeline->gsCI;
+ memcpy(&pPipeline->gsCI, pTmpPSSCI, sizeof(XGL_PIPELINE_SHADER_STAGE_CREATE_INFO));
+ break;
+ case XGL_SHADER_STAGE_FRAGMENT:
+ pPrev->pNext = &pPipeline->fsCI;
+ pPrev = (GENERIC_HEADER*)&pPipeline->fsCI;
+ memcpy(&pPipeline->fsCI, pTmpPSSCI, sizeof(XGL_PIPELINE_SHADER_STAGE_CREATE_INFO));
+ break;
+ case XGL_SHADER_STAGE_COMPUTE:
+ // TODO : Flag error, CS is specified through XGL_COMPUTE_PIPELINE_CREATE_INFO
+ break;
+ default:
+ // TODO : Flag error
+ break;
+ }
break;
case XGL_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO:
- pShadowTrav->pNext = new XGL_PIPELINE_VERTEX_INPUT_CREATE_INFO;
- memcpy((void*)pShadowTrav->pNext, pTrav, sizeof(XGL_PIPELINE_VERTEX_INPUT_CREATE_INFO));
+ pPrev->pNext = &pPipeline->vertexInputCI;
+ pPrev = (GENERIC_HEADER*)&pPipeline->vertexInputCI;
+ memcpy((void*)&pPipeline->vertexInputCI, pTrav, sizeof(XGL_PIPELINE_VERTEX_INPUT_CREATE_INFO));
// Copy embedded ptrs
pVICI = (XGL_PIPELINE_VERTEX_INPUT_CREATE_INFO*)pTrav;
pPipeline->vtxBindingCount = pVICI->bindingCount;
@@ -389,28 +425,34 @@ static void initPipeline(PIPELINE_NODE* pPipeline, const XGL_GRAPHICS_PIPELINE_C
}
break;
case XGL_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO:
- pShadowTrav->pNext = new XGL_PIPELINE_IA_STATE_CREATE_INFO;
- memcpy((void*)pShadowTrav->pNext, pTrav, sizeof(XGL_PIPELINE_IA_STATE_CREATE_INFO));
+ pPrev->pNext = &pPipeline->iaStateCI;
+ pPrev = (GENERIC_HEADER*)&pPipeline->iaStateCI;
+ memcpy((void*)&pPipeline->iaStateCI, pTrav, sizeof(XGL_PIPELINE_IA_STATE_CREATE_INFO));
break;
case XGL_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO:
- pShadowTrav->pNext = new XGL_PIPELINE_TESS_STATE_CREATE_INFO;
- memcpy((void*)pShadowTrav->pNext, pTrav, sizeof(XGL_PIPELINE_TESS_STATE_CREATE_INFO));
+ pPrev->pNext = &pPipeline->tessStateCI;
+ pPrev = (GENERIC_HEADER*)&pPipeline->tessStateCI;
+ memcpy((void*)&pPipeline->tessStateCI, pTrav, sizeof(XGL_PIPELINE_TESS_STATE_CREATE_INFO));
break;
case XGL_STRUCTURE_TYPE_PIPELINE_VP_STATE_CREATE_INFO:
- pShadowTrav->pNext = new XGL_PIPELINE_VP_STATE_CREATE_INFO;
- memcpy((void*)pShadowTrav->pNext, pTrav, sizeof(XGL_PIPELINE_VP_STATE_CREATE_INFO));
+ pPrev->pNext = &pPipeline->vpStateCI;
+ pPrev = (GENERIC_HEADER*)&pPipeline->vpStateCI;
+ memcpy((void*)&pPipeline->vpStateCI, pTrav, sizeof(XGL_PIPELINE_VP_STATE_CREATE_INFO));
break;
case XGL_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO:
- pShadowTrav->pNext = new XGL_PIPELINE_RS_STATE_CREATE_INFO;
- memcpy((void*)pShadowTrav->pNext, pTrav, sizeof(XGL_PIPELINE_RS_STATE_CREATE_INFO));
+ pPrev->pNext = &pPipeline->rsStateCI;
+ pPrev = (GENERIC_HEADER*)&pPipeline->rsStateCI;
+ memcpy((void*)&pPipeline->rsStateCI, pTrav, sizeof(XGL_PIPELINE_RS_STATE_CREATE_INFO));
break;
case XGL_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO:
- pShadowTrav->pNext = new XGL_PIPELINE_MS_STATE_CREATE_INFO;
- memcpy((void*)pShadowTrav->pNext, pTrav, sizeof(XGL_PIPELINE_MS_STATE_CREATE_INFO));
+ pPrev->pNext = &pPipeline->msStateCI;
+ pPrev = (GENERIC_HEADER*)&pPipeline->msStateCI;
+ memcpy((void*)&pPipeline->msStateCI, pTrav, sizeof(XGL_PIPELINE_MS_STATE_CREATE_INFO));
break;
case XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO:
- pShadowTrav->pNext = new XGL_PIPELINE_CB_STATE_CREATE_INFO;
- memcpy((void*)pShadowTrav->pNext, pTrav, sizeof(XGL_PIPELINE_CB_STATE_CREATE_INFO));
+ pPrev->pNext = &pPipeline->cbStateCI;
+ pPrev = (GENERIC_HEADER*)&pPipeline->cbStateCI;
+ memcpy((void*)&pPipeline->cbStateCI, pTrav, sizeof(XGL_PIPELINE_CB_STATE_CREATE_INFO));
// Copy embedded ptrs
pCBCI = (XGL_PIPELINE_CB_STATE_CREATE_INFO*)pTrav;
pPipeline->attachmentCount = pCBCI->attachmentCount;
@@ -421,14 +463,14 @@ static void initPipeline(PIPELINE_NODE* pPipeline, const XGL_GRAPHICS_PIPELINE_C
}
break;
case XGL_STRUCTURE_TYPE_PIPELINE_DS_STATE_CREATE_INFO:
- pShadowTrav->pNext = new XGL_PIPELINE_DS_STATE_CREATE_INFO;
- memcpy((void*)pShadowTrav->pNext, pTrav, sizeof(XGL_PIPELINE_DS_STATE_CREATE_INFO));
+ pPrev->pNext = &pPipeline->dsStateCI;
+ pPrev = (GENERIC_HEADER*)&pPipeline->dsStateCI;
+ memcpy((void*)&pPipeline->dsStateCI, pTrav, sizeof(XGL_PIPELINE_DS_STATE_CREATE_INFO));
break;
default:
assert(0);
break;
}
- pShadowTrav = (GENERIC_HEADER*)pShadowTrav->pNext;
pTrav = (GENERIC_HEADER*)pTrav->pNext;
}
pipelineMap[pPipeline->pipeline] = pPipeline;
@@ -437,31 +479,52 @@ static void initPipeline(PIPELINE_NODE* pPipeline, const XGL_GRAPHICS_PIPELINE_C
static void freePipelines()
{
for (unordered_map<XGL_PIPELINE, PIPELINE_NODE*>::iterator ii=pipelineMap.begin(); ii!=pipelineMap.end(); ++ii) {
- // Delete create tree
- GENERIC_HEADER* pShadowTrav = (GENERIC_HEADER*)((*ii).second->pCreateTree);
- GENERIC_HEADER* pShadowFree = pShadowTrav;
- while (pShadowTrav) {
- pShadowFree = pShadowTrav;
- pShadowTrav = (GENERIC_HEADER*)pShadowTrav->pNext;
- if (XGL_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO == pShadowFree->sType) {
- if ((*ii).second->pVertexBindingDescriptions) {
- delete[] (*ii).second->pVertexBindingDescriptions;
- }
- if ((*ii).second->pVertexAttributeDescriptions) {
- delete[] (*ii).second->pVertexAttributeDescriptions;
- }
- }
- else if (XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO == pShadowFree->sType) {
- // Free attachment data shadowed into pPipeline node
- if ((*ii).second->pAttachments) {
- delete[] (*ii).second->pAttachments;
- }
- }
- delete pShadowFree;
+ if ((*ii).second->pVertexBindingDescriptions) {
+ delete[] (*ii).second->pVertexBindingDescriptions;
+ }
+ if ((*ii).second->pVertexAttributeDescriptions) {
+ delete[] (*ii).second->pVertexAttributeDescriptions;
+ }
+ if ((*ii).second->pAttachments) {
+ delete[] (*ii).second->pAttachments;
}
delete (*ii).second;
}
}
+// For given pipeline, return number of MSAA samples, or one if MSAA disabled
+static uint32_t getNumSamples(const XGL_PIPELINE pipeline)
+{
+ PIPELINE_NODE* pPipe = pipelineMap[pipeline];
+ if (XGL_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO == pPipe->msStateCI.sType) {
+ if (pPipe->msStateCI.multisampleEnable)
+ return pPipe->msStateCI.samples;
+ }
+ return 1;
+}
+// Validate state related to the PSO
+static void validatePipelineState(const GLOBAL_CB_NODE* pCB, const XGL_PIPELINE_BIND_POINT pipelineBindPoint, const XGL_PIPELINE pipeline)
+{
+ if (XGL_PIPELINE_BIND_POINT_GRAPHICS == pipelineBindPoint) {
+ // Verify that any MSAA request in PSO matches sample# in bound FB
+ uint32_t psoNumSamples = getNumSamples(pipeline);
+ if (pCB->activeRenderPass) {
+ XGL_RENDER_PASS_CREATE_INFO* pRPCI = renderPassMap[pCB->activeRenderPass];
+ XGL_FRAMEBUFFER_CREATE_INFO* pFBCI = frameBufferMap[pRPCI->framebuffer];
+ if (psoNumSamples != pFBCI->sampleCount) {
+ char str[1024];
+ sprintf(str, "Num samples mismatche! Binding PSO (%p) with %u samples while current RenderPass (%p) uses FB (%p) with %u samples!", (void*)pipeline, psoNumSamples, (void*)pCB->activeRenderPass, (void*)pRPCI->framebuffer, pFBCI->sampleCount);
+ layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, pipeline, 0, DRAWSTATE_NUM_SAMPLES_MISMATCH, "DS", str);
+ }
+ } else {
+ // TODO : I believe it's an error if we reach this point and don't have an activeRenderPass
+ // Verify and flag error as appropriate
+ }
+ // TODO : Add more checks here
+ } else {
+ // TODO : Validate non-gfx pipeline updates
+ }
+}
+
// Block of code at start here specifically for managing/tracking DSs
// Return Region node ptr for specified region or else NULL
@@ -1013,7 +1076,7 @@ static void printPipeline(const XGL_CMD_BUFFER cb)
// nothing to print
}
else {
- string pipeStr = xgl_print_xgl_graphics_pipeline_create_info(pPipeTrav->pCreateTree, "{DS}").c_str();
+ string pipeStr = xgl_print_xgl_graphics_pipeline_create_info(&pPipeTrav->graphicsPipelineCI, "{DS}").c_str();
layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", pipeStr.c_str());
}
}
@@ -1211,7 +1274,7 @@ static void dumpGlobalDotFile(char *outFileName)
}
fprintf(pOutFile, "}\n"); // close dynamicState subgraph
fprintf(pOutFile, "subgraph cluster_PipelineStateObject\n{\nlabel=\"Pipeline State Object\"\n");
- pGVstr = xgl_gv_print_xgl_graphics_pipeline_create_info(pPipeTrav->pCreateTree, "PSO HEAD");
+ pGVstr = xgl_gv_print_xgl_graphics_pipeline_create_info(&pPipeTrav->graphicsPipelineCI, "PSO HEAD");
fprintf(pOutFile, "%s", pGVstr);
free(pGVstr);
fprintf(pOutFile, "}\n");
@@ -1241,7 +1304,7 @@ static void dumpDotFile(const XGL_CMD_BUFFER cb, string outFileName)
}
fprintf(pOutFile, "}\n"); // close dynamicState subgraph
fprintf(pOutFile, "subgraph cluster_PipelineStateObject\n{\nlabel=\"Pipeline State Object\"\n");
- pGVstr = xgl_gv_print_xgl_graphics_pipeline_create_info(pPipeTrav->pCreateTree, "PSO HEAD");
+ pGVstr = xgl_gv_print_xgl_graphics_pipeline_create_info(&pPipeTrav->graphicsPipelineCI, "PSO HEAD");
fprintf(pOutFile, "%s", pGVstr);
free(pGVstr);
fprintf(pOutFile, "}\n");
@@ -1828,6 +1891,12 @@ XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglBeginCommandBuffer(XGL_CMD_BUFFER cmdBuffe
if (CB_NEW != pCB->state)
resetCB(cmdBuffer);
pCB->state = CB_UPDATE_ACTIVE;
+ if (pBeginInfo->pNext) {
+ XGL_CMD_BUFFER_GRAPHICS_BEGIN_INFO* pCbGfxBI = (XGL_CMD_BUFFER_GRAPHICS_BEGIN_INFO*)pBeginInfo->pNext;
+ if (XGL_STRUCTURE_TYPE_CMD_BUFFER_GRAPHICS_BEGIN_INFO == pCbGfxBI->sType) {
+ pCB->activeRenderPass = pCbGfxBI->renderPass;
+ }
+ }
}
else {
char str[1024];
@@ -1881,6 +1950,7 @@ XGL_LAYER_EXPORT void XGLAPI xglCmdBindPipeline(XGL_CMD_BUFFER cmdBuffer, XGL_PI
loader_platform_thread_lock_mutex(&globalLock);
g_lastBoundPipeline = pPN;
loader_platform_thread_unlock_mutex(&globalLock);
+ validatePipelineState(pCB, pipelineBindPoint, pipeline);
}
else {
char str[1024];
@@ -2429,12 +2499,56 @@ XGL_LAYER_EXPORT void XGLAPI xglCmdSaveAtomicCounters(XGL_CMD_BUFFER cmdBuffer,
nextTable.CmdSaveAtomicCounters(cmdBuffer, pipelineBindPoint, startCounter, counterCount, destBuffer, destOffset);
}
+XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateFramebuffer(XGL_DEVICE device, const XGL_FRAMEBUFFER_CREATE_INFO* pCreateInfo, XGL_FRAMEBUFFER* pFramebuffer)
+{
+ XGL_RESULT result = nextTable.CreateFramebuffer(device, pCreateInfo, pFramebuffer);
+ if (XGL_SUCCESS == result) {
+ // Shadow create info and store in map
+ XGL_FRAMEBUFFER_CREATE_INFO* localFBCI = new XGL_FRAMEBUFFER_CREATE_INFO(*pCreateInfo);
+ if (pCreateInfo->pColorAttachments) {
+ localFBCI->pColorAttachments = new XGL_COLOR_ATTACHMENT_BIND_INFO[localFBCI->colorAttachmentCount];
+ memcpy((void*)localFBCI->pColorAttachments, pCreateInfo->pColorAttachments, localFBCI->colorAttachmentCount*sizeof(XGL_COLOR_ATTACHMENT_BIND_INFO));
+ }
+ if (pCreateInfo->pDepthStencilAttachment) {
+ localFBCI->pDepthStencilAttachment = new XGL_DEPTH_STENCIL_BIND_INFO[localFBCI->colorAttachmentCount];
+ memcpy((void*)localFBCI->pDepthStencilAttachment, pCreateInfo->pDepthStencilAttachment, localFBCI->colorAttachmentCount*sizeof(XGL_DEPTH_STENCIL_BIND_INFO));
+ }
+ frameBufferMap[*pFramebuffer] = localFBCI;
+ }
+ return result;
+}
+
+XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateRenderPass(XGL_DEVICE device, const XGL_RENDER_PASS_CREATE_INFO* pCreateInfo, XGL_RENDER_PASS* pRenderPass)
+{
+ XGL_RESULT result = nextTable.CreateRenderPass(device, pCreateInfo, pRenderPass);
+ if (XGL_SUCCESS == result) {
+ // Shadow create info and store in map
+ XGL_RENDER_PASS_CREATE_INFO* localRPCI = new XGL_RENDER_PASS_CREATE_INFO(*pCreateInfo);
+ if (pCreateInfo->pColorLoadOps) {
+ localRPCI->pColorLoadOps = new XGL_ATTACHMENT_LOAD_OP[localRPCI->colorAttachmentCount];
+ memcpy((void*)localRPCI->pColorLoadOps, pCreateInfo->pColorLoadOps, localRPCI->colorAttachmentCount*sizeof(XGL_ATTACHMENT_LOAD_OP));
+ }
+ if (pCreateInfo->pColorStoreOps) {
+ localRPCI->pColorStoreOps = new XGL_ATTACHMENT_STORE_OP[localRPCI->colorAttachmentCount];
+ memcpy((void*)localRPCI->pColorStoreOps, pCreateInfo->pColorStoreOps, localRPCI->colorAttachmentCount*sizeof(XGL_ATTACHMENT_STORE_OP));
+ }
+ if (pCreateInfo->pColorLoadClearValues) {
+ localRPCI->pColorLoadClearValues = new XGL_CLEAR_COLOR[localRPCI->colorAttachmentCount];
+ memcpy((void*)localRPCI->pColorLoadClearValues, pCreateInfo->pColorLoadClearValues, localRPCI->colorAttachmentCount*sizeof(XGL_CLEAR_COLOR));
+ }
+ renderPassMap[*pRenderPass] = localRPCI;
+ }
+ return result;
+}
+
XGL_LAYER_EXPORT void XGLAPI xglCmdBeginRenderPass(XGL_CMD_BUFFER cmdBuffer, XGL_RENDER_PASS renderPass)
{
GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
if (pCB) {
updateCBTracking(cmdBuffer);
addCmd(pCB, CMD_BEGINRENDERPASS);
+ pCB->activeRenderPass = renderPass;
+ validatePipelineState(pCB, XGL_PIPELINE_BIND_POINT_GRAPHICS, pCB->lastBoundPipeline);
}
else {
char str[1024];
@@ -2450,6 +2564,7 @@ XGL_LAYER_EXPORT void XGLAPI xglCmdEndRenderPass(XGL_CMD_BUFFER cmdBuffer, XGL_R
if (pCB) {
updateCBTracking(cmdBuffer);
addCmd(pCB, CMD_ENDRENDERPASS);
+ pCB->activeRenderPass = 0;
}
else {
char str[1024];
@@ -2705,6 +2820,10 @@ XGL_LAYER_EXPORT void* XGLAPI xglGetProcAddr(XGL_PHYSICAL_GPU gpu, const char* f
return (void*) xglCmdLoadAtomicCounters;
if (!strcmp(funcName, "xglCmdSaveAtomicCounters"))
return (void*) xglCmdSaveAtomicCounters;
+ if (!strcmp(funcName, "xglCreateFramebuffer"))
+ return (void*) xglCreateFramebuffer;
+ if (!strcmp(funcName, "xglCreateRenderPass"))
+ return (void*) xglCreateRenderPass;
if (!strcmp(funcName, "xglCmdBeginRenderPass"))
return (void*) xglCmdBeginRenderPass;
if (!strcmp(funcName, "xglCmdEndRenderPass"))
diff --git a/layers/draw_state.h b/layers/draw_state.h
index 6edee479..f5230f81 100644
--- a/layers/draw_state.h
+++ b/layers/draw_state.h
@@ -48,7 +48,8 @@ typedef enum _DRAW_STATE_ERROR
DRAWSTATE_DESCRIPTOR_TYPE_MISMATCH, // Type in layout vs. update are not the same
DRAWSTATE_DESCRIPTOR_UPDATE_OUT_OF_BOUNDS, // Descriptors set for update out of bounds for corresponding layout section
DRAWSTATE_INVALID_UPDATE_INDEX, // Index of requested update is invalid for specified descriptors set
- DRAWSTATE_INVALID_UPDATE_STRUCT // Struct in DS Update tree is of invalid type
+ DRAWSTATE_INVALID_UPDATE_STRUCT, // Struct in DS Update tree is of invalid type
+ DRAWSTATE_NUM_SAMPLES_MISMATCH // Number of samples in bound PSO does not match number in FB of current RenderPass
} DRAW_STATE_ERROR;
typedef enum _DRAW_TYPE
@@ -74,7 +75,25 @@ typedef struct _GENERIC_HEADER {
typedef struct _PIPELINE_NODE {
XGL_PIPELINE pipeline;
- XGL_GRAPHICS_PIPELINE_CREATE_INFO *pCreateTree; // Ptr to shadow of data in create tree
+
+ XGL_GRAPHICS_PIPELINE_CREATE_INFO graphicsPipelineCI;
+ XGL_PIPELINE_VERTEX_INPUT_CREATE_INFO vertexInputCI;
+ XGL_PIPELINE_IA_STATE_CREATE_INFO iaStateCI;
+ XGL_PIPELINE_TESS_STATE_CREATE_INFO tessStateCI;
+ XGL_PIPELINE_VP_STATE_CREATE_INFO vpStateCI;
+ XGL_PIPELINE_RS_STATE_CREATE_INFO rsStateCI;
+ XGL_PIPELINE_MS_STATE_CREATE_INFO msStateCI;
+ XGL_PIPELINE_CB_STATE_CREATE_INFO cbStateCI;
+ XGL_PIPELINE_DS_STATE_CREATE_INFO dsStateCI;
+ XGL_PIPELINE_SHADER_STAGE_CREATE_INFO vsCI;
+ XGL_PIPELINE_SHADER_STAGE_CREATE_INFO tcsCI;
+ XGL_PIPELINE_SHADER_STAGE_CREATE_INFO tesCI;
+ XGL_PIPELINE_SHADER_STAGE_CREATE_INFO gsCI;
+ XGL_PIPELINE_SHADER_STAGE_CREATE_INFO fsCI;
+ // Compute shader is include in XGL_COMPUTE_PIPELINE_CREATE_INFO
+ XGL_COMPUTE_PIPELINE_CREATE_INFO computePipelineCI;
+
+ XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateTree; // Ptr to shadow of data in create tree
// Vtx input info (if any)
uint32_t vtxBindingCount; // number of bindings
XGL_VERTEX_INPUT_BINDING_DESCRIPTION* pVertexBindingDescriptions;
@@ -217,6 +236,7 @@ typedef struct _GLOBAL_CB_NODE {
uint32_t lastVtxBinding;
DYNAMIC_STATE_NODE* lastBoundDynamicState[XGL_NUM_STATE_BIND_POINT];
XGL_DESCRIPTOR_SET lastBoundDescriptorSet;
+ XGL_RENDER_PASS activeRenderPass;
} GLOBAL_CB_NODE;
//prototypes for extension functions
diff --git a/loader/loader.c b/loader/loader.c
index 6f7ce249..1de7c846 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -179,9 +179,7 @@ static char *loader_get_registry_and_env(const char *env_var,
registry_str = loader_get_registry_string(HKEY_LOCAL_MACHINE,
"Software\\XGL",
registry_value);
- if (registry_str) {
- registry_len = strlen(registry_str);
- }
+ registry_len = (registry_str) ? strlen(registry_str) : 0;
rtn_len = env_len + registry_len + 1;
if (rtn_len <= 2) {
@@ -207,7 +205,9 @@ static char *loader_get_registry_and_env(const char *env_var,
_snprintf(rtn_str, rtn_len, "%s", registry_str);
}
- free(registry_str);
+ if (registry_str) {
+ free(registry_str);
+ }
return(rtn_str);
}