blob: 5148be82bc734e260810c780ac40f9575c3b4f73 [file] [log] [blame]
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001/*
2 * XGL
3 *
4 * Copyright (C) 2014 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070028#include "loader_platform.h"
Chia-I Wuaa4121f2015-01-04 23:11:43 +080029#include "xgl_dispatch_table_helper.h"
Tobin Ehlis296d5d52014-10-27 14:53:17 -060030#include "xgl_struct_string_helper.h"
Tobin Ehlis83562882014-11-27 15:43:39 -070031#include "xgl_struct_graphviz_helper.h"
Tobin Ehlis04112922015-03-16 10:44:40 -060032#include "xgl_struct_size_helper.h"
Tobin Ehlis246ba4d2014-11-18 16:38:08 -070033#include "draw_state.h"
Jon Ashburn892d9182014-12-22 13:38:27 -070034#include "layers_config.h"
Ian Elliott655cad72015-02-12 17:08:34 -070035// The following is #included again to catch certain OS-specific functions
36// being used:
37#include "loader_platform.h"
Jon Ashburn2e672892015-02-16 08:46:53 -070038#include "layers_msg.h"
Tobin Ehlis10ae8c12015-03-17 16:24:32 -060039
Tobin Ehlis97657ce2014-10-24 12:01:45 -060040static XGL_LAYER_DISPATCH_TABLE nextTable;
41static XGL_BASE_LAYER_OBJECT *pCurObj;
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070042static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(g_initOnce);
Tobin Ehlis8c2ed212015-02-20 09:30:06 -070043// TODO : This can be much smarter, using separate locks for separate global data
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070044static int globalLockInitialized = 0;
45static loader_platform_thread_mutex globalLock;
Tobin Ehlis03d7a092015-02-17 16:27:03 -070046#define ALLOC_DEBUG 0
47#if ALLOC_DEBUG
48static uint64_t g_alloc_count = 0;
49static uint64_t g_free_count = 0;
50#endif
Tobin Ehlisea189f12015-02-23 09:06:28 -070051#define MAX_TID 513
Tobin Ehlis67449422015-03-02 10:16:40 -070052static loader_platform_thread_id g_tidMapping[MAX_TID] = {0};
Tobin Ehlisea189f12015-02-23 09:06:28 -070053static uint32_t g_maxTID = 0;
54// Map actual TID to an index value and return that index
55// This keeps TIDs in range from 0-MAX_TID and simplifies compares between runs
56static uint32_t getTIDIndex() {
57 loader_platform_thread_id tid = loader_platform_get_thread_id();
58 for (uint32_t i = 0; i < g_maxTID; i++) {
Tobin Ehlis67449422015-03-02 10:16:40 -070059 if (tid == g_tidMapping[i])
Tobin Ehlisea189f12015-02-23 09:06:28 -070060 return i;
61 }
62 // Don't yet have mapping, set it and return newly set index
63 uint32_t retVal = (uint32_t) g_maxTID;
Tobin Ehlis67449422015-03-02 10:16:40 -070064 g_tidMapping[g_maxTID++] = tid;
Tobin Ehlisea189f12015-02-23 09:06:28 -070065 assert(g_maxTID < MAX_TID);
66 return retVal;
67}
Tobin Ehlis93837a02015-02-13 13:30:07 -070068// Return a string representation of CMD_TYPE enum
69static char* cmdTypeToString(CMD_TYPE cmd)
70{
71 switch (cmd)
72 {
73 case CMD_BINDPIPELINE:
74 return "CMD_BINDPIPELINE";
75 case CMD_BINDPIPELINEDELTA:
76 return "CMD_BINDPIPELINEDELTA";
77 case CMD_BINDDYNAMICSTATEOBJECT:
78 return "CMD_BINDDYNAMICSTATEOBJECT";
79 case CMD_BINDDESCRIPTORSET:
80 return "CMD_BINDDESCRIPTORSET";
81 case CMD_BINDINDEXBUFFER:
82 return "CMD_BINDINDEXBUFFER";
83 case CMD_BINDVERTEXBUFFER:
84 return "CMD_BINDVERTEXBUFFER";
85 case CMD_DRAW:
86 return "CMD_DRAW";
87 case CMD_DRAWINDEXED:
88 return "CMD_DRAWINDEXED";
89 case CMD_DRAWINDIRECT:
90 return "CMD_DRAWINDIRECT";
91 case CMD_DRAWINDEXEDINDIRECT:
92 return "CMD_DRAWINDEXEDINDIRECT";
93 case CMD_DISPATCH:
94 return "CMD_DISPATCH";
95 case CMD_DISPATCHINDIRECT:
96 return "CMD_DISPATCHINDIRECT";
97 case CMD_COPYBUFFER:
98 return "CMD_COPYBUFFER";
99 case CMD_COPYIMAGE:
100 return "CMD_COPYIMAGE";
101 case CMD_COPYBUFFERTOIMAGE:
102 return "CMD_COPYBUFFERTOIMAGE";
103 case CMD_COPYIMAGETOBUFFER:
104 return "CMD_COPYIMAGETOBUFFER";
105 case CMD_CLONEIMAGEDATA:
106 return "CMD_CLONEIMAGEDATA";
107 case CMD_UPDATEBUFFER:
108 return "CMD_UPDATEBUFFER";
109 case CMD_FILLBUFFER:
110 return "CMD_FILLBUFFER";
111 case CMD_CLEARCOLORIMAGE:
112 return "CMD_CLEARCOLORIMAGE";
113 case CMD_CLEARCOLORIMAGERAW:
114 return "CMD_CLEARCOLORIMAGERAW";
115 case CMD_CLEARDEPTHSTENCIL:
116 return "CMD_CLEARDEPTHSTENCIL";
117 case CMD_RESOLVEIMAGE:
118 return "CMD_RESOLVEIMAGE";
119 case CMD_SETEVENT:
120 return "CMD_SETEVENT";
121 case CMD_RESETEVENT:
122 return "CMD_RESETEVENT";
123 case CMD_WAITEVENTS:
124 return "CMD_WAITEVENTS";
125 case CMD_PIPELINEBARRIER:
126 return "CMD_PIPELINEBARRIER";
127 case CMD_BEGINQUERY:
128 return "CMD_BEGINQUERY";
129 case CMD_ENDQUERY:
130 return "CMD_ENDQUERY";
131 case CMD_RESETQUERYPOOL:
132 return "CMD_RESETQUERYPOOL";
133 case CMD_WRITETIMESTAMP:
134 return "CMD_WRITETIMESTAMP";
135 case CMD_INITATOMICCOUNTERS:
136 return "CMD_INITATOMICCOUNTERS";
137 case CMD_LOADATOMICCOUNTERS:
138 return "CMD_LOADATOMICCOUNTERS";
139 case CMD_SAVEATOMICCOUNTERS:
140 return "CMD_SAVEATOMICCOUNTERS";
141 case CMD_BEGINRENDERPASS:
142 return "CMD_BEGINRENDERPASS";
143 case CMD_ENDRENDERPASS:
144 return "CMD_ENDRENDERPASS";
Tobin Ehlis67449422015-03-02 10:16:40 -0700145 case CMD_DBGMARKERBEGIN:
146 return "CMD_DBGMARKERBEGIN";
147 case CMD_DBGMARKEREND:
148 return "CMD_DBGMARKEREND";
Tobin Ehlis93837a02015-02-13 13:30:07 -0700149 default:
150 return "UNKNOWN";
151 }
152}
Tobin Ehlis97657ce2014-10-24 12:01:45 -0600153// Block of code at start here for managing/tracking Pipeline state that this layer cares about
154// Just track 2 shaders for now
Tobin Ehlis5742e772014-11-20 09:49:17 -0700155#define XGL_NUM_GRAPHICS_SHADERS XGL_SHADER_STAGE_COMPUTE
Tobin Ehlis97657ce2014-10-24 12:01:45 -0600156#define MAX_SLOTS 2048
Tobin Ehlis67449422015-03-02 10:16:40 -0700157#define NUM_COMMAND_BUFFERS_TO_DISPLAY 10
Tobin Ehlis296d5d52014-10-27 14:53:17 -0600158
Tobin Ehlisd01f7d62015-02-13 10:26:14 -0700159static uint64_t g_drawCount[NUM_DRAW_TYPES] = {0, 0, 0, 0};
160
Tobin Ehlis9dc93af2014-11-21 08:58:46 -0700161// TODO : Should be tracking lastBound per cmdBuffer and when draws occur, report based on that cmd buffer lastBound
Tobin Ehlis83562882014-11-27 15:43:39 -0700162// Then need to synchronize the accesses based on cmd buffer so that if I'm reading state on one cmd buffer, updates
163// to that same cmd buffer by separate thread are not changing state from underneath us
Tobin Ehlisd01f7d62015-02-13 10:26:14 -0700164static PIPELINE_NODE* g_pPipelineHead = NULL;
165static SAMPLER_NODE* g_pSamplerHead = NULL;
166static IMAGE_NODE* g_pImageHead = NULL;
167static BUFFER_NODE* g_pBufferHead = NULL;
168static GLOBAL_CB_NODE* g_pCmdBufferHead = NULL;
Tobin Ehlisae708b82015-02-27 08:48:43 -0700169// Track the last cmd buffer touched by this thread
Tobin Ehlisea189f12015-02-23 09:06:28 -0700170static XGL_CMD_BUFFER g_lastCmdBuffer[MAX_TID] = {NULL};
Tobin Ehlis67449422015-03-02 10:16:40 -0700171// Track the last group of CBs touched for displaying to dot file
172static GLOBAL_CB_NODE* g_pLastTouchedCB[NUM_COMMAND_BUFFERS_TO_DISPLAY] = {NULL};
173static uint32_t g_lastTouchedCBIndex = 0;
Tobin Ehlisae708b82015-02-27 08:48:43 -0700174// Track the last global DrawState of interest touched by any thread
Tobin Ehlis67449422015-03-02 10:16:40 -0700175static GLOBAL_CB_NODE* g_lastGlobalCB = NULL;
Tobin Ehlisae708b82015-02-27 08:48:43 -0700176static PIPELINE_NODE* g_lastBoundPipeline = NULL;
177static DYNAMIC_STATE_NODE* g_lastBoundDynamicState[XGL_NUM_STATE_BIND_POINT] = {NULL};
178static XGL_DESCRIPTOR_SET g_lastBoundDescriptorSet = NULL;
Tobin Ehlisd01f7d62015-02-13 10:26:14 -0700179#define MAX_BINDING 0xFFFFFFFF // Default vtxBinding value in CB Node to identify if no vtxBinding set
Tobin Ehlis97657ce2014-10-24 12:01:45 -0600180
Tobin Ehlis04178d72015-01-22 10:45:21 -0700181static DYNAMIC_STATE_NODE* g_pDynamicStateHead[XGL_NUM_STATE_BIND_POINT] = {0};
Tobin Ehlis9dc93af2014-11-21 08:58:46 -0700182
Tobin Ehlis04178d72015-01-22 10:45:21 -0700183static void insertDynamicState(const XGL_DYNAMIC_STATE_OBJECT state, const GENERIC_HEADER* pCreateInfo, XGL_STATE_BIND_POINT bindPoint)
Tobin Ehlis9dc93af2014-11-21 08:58:46 -0700184{
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700185 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis9dc93af2014-11-21 08:58:46 -0700186 // Insert new node at head of appropriate LL
187 DYNAMIC_STATE_NODE* pStateNode = (DYNAMIC_STATE_NODE*)malloc(sizeof(DYNAMIC_STATE_NODE));
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700188#if ALLOC_DEBUG
189 printf("Alloc1 #%lu pStateNode addr(%p)\n", ++g_alloc_count, (void*)pStateNode);
190#endif
Tobin Ehlis04178d72015-01-22 10:45:21 -0700191 pStateNode->pNext = g_pDynamicStateHead[bindPoint];
192 g_pDynamicStateHead[bindPoint] = pStateNode;
Tobin Ehlis9dc93af2014-11-21 08:58:46 -0700193 pStateNode->stateObj = state;
Tobin Ehlis04112922015-03-16 10:44:40 -0600194 pStateNode->pCreateInfo = (GENERIC_HEADER*)malloc(get_dynamic_struct_size(pCreateInfo));
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700195#if ALLOC_DEBUG
196 printf("Alloc2 #%lu pStateNode->pCreateInfo addr(%p)\n", ++g_alloc_count, (void*)pStateNode->pCreateInfo);
197#endif
Tobin Ehlis04112922015-03-16 10:44:40 -0600198 memcpy(pStateNode->pCreateInfo, pCreateInfo, get_dynamic_struct_size(pCreateInfo));
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700199 // VP has embedded ptr so need to handle that as special case
200 if (XGL_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO == pCreateInfo->sType) {
201 XGL_DYNAMIC_VP_STATE_CREATE_INFO* pVPCI = (XGL_DYNAMIC_VP_STATE_CREATE_INFO*)pStateNode->pCreateInfo;
202 XGL_VIEWPORT** ppViewports = (XGL_VIEWPORT**)&pVPCI->pViewports;
Courtney Goeltzenleuchterbbe3cc52015-02-11 14:13:34 -0700203 size_t vpSize = sizeof(XGL_VIEWPORT) * pVPCI->viewportAndScissorCount;
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700204 if (vpSize) {
205 *ppViewports = (XGL_VIEWPORT*)malloc(vpSize);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700206#if ALLOC_DEBUG
207 printf("Alloc3 #%lu *ppViewports addr(%p)\n", ++g_alloc_count, (void*)*ppViewports);
208#endif
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700209 memcpy(*ppViewports, ((XGL_DYNAMIC_VP_STATE_CREATE_INFO*)pCreateInfo)->pViewports, vpSize);
210 }
211 XGL_RECT** ppScissors = (XGL_RECT**)&pVPCI->pScissors;
Courtney Goeltzenleuchterbbe3cc52015-02-11 14:13:34 -0700212 size_t scSize = sizeof(XGL_RECT) * pVPCI->viewportAndScissorCount;
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700213 if (scSize) {
214 *ppScissors = (XGL_RECT*)malloc(scSize);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700215#if ALLOC_DEBUG
216 printf("Alloc4 #%lu *ppScissors addr(%p)\n", ++g_alloc_count, (void*)*ppScissors);
217#endif
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700218 memcpy(*ppScissors, ((XGL_DYNAMIC_VP_STATE_CREATE_INFO*)pCreateInfo)->pScissors, scSize);
219 }
220 }
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700221 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis9dc93af2014-11-21 08:58:46 -0700222}
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700223// Free all allocated nodes for Dynamic State objs
224static void freeDynamicState()
225{
226 for (uint32_t i = 0; i < XGL_NUM_STATE_BIND_POINT; i++) {
227 DYNAMIC_STATE_NODE* pStateNode = g_pDynamicStateHead[i];
228 DYNAMIC_STATE_NODE* pFreeMe = pStateNode;
229 while (pStateNode) {
230 pFreeMe = pStateNode;
231 pStateNode = pStateNode->pNext;
232 assert(pFreeMe->pCreateInfo);
233 if (XGL_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO == pFreeMe->pCreateInfo->sType) {
234 XGL_DYNAMIC_VP_STATE_CREATE_INFO* pVPCI = (XGL_DYNAMIC_VP_STATE_CREATE_INFO*)pFreeMe->pCreateInfo;
235 if (pVPCI->pViewports) {
236 void** ppToFree = (void**)&pVPCI->pViewports;
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700237#if ALLOC_DEBUG
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700238 printf("Free3 #%lu pViewports addr(%p)\n", ++g_free_count, (void*)*ppToFree);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700239#endif
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700240 free(*ppToFree);
241 }
242 if (pVPCI->pScissors) {
243 void** ppToFree = (void**)&pVPCI->pScissors;
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700244#if ALLOC_DEBUG
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700245 printf("Free4 #%lu pScissors addr(%p)\n", ++g_free_count, (void*)*ppToFree);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700246#endif
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700247 free(*ppToFree);
248 }
249 }
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700250#if ALLOC_DEBUG
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700251 printf("Free2 #%lu pStateNode->CreateInfo addr(%p)\n", ++g_free_count, (void*)pFreeMe->pCreateInfo);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700252#endif
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700253 free(pFreeMe->pCreateInfo);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700254#if ALLOC_DEBUG
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700255 printf("Free1 #%lu pStateNode addr(%p)\n", ++g_free_count, (void*)pFreeMe);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700256#endif
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700257 free(pFreeMe);
258 }
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700259 g_pDynamicStateHead[i] = NULL;
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700260 }
261}
262// Free all sampler nodes
263static void freeSamplers()
264{
265 SAMPLER_NODE* pSampler = g_pSamplerHead;
266 SAMPLER_NODE* pFreeMe = pSampler;
267 while (pSampler) {
268 pFreeMe = pSampler;
269 pSampler = pSampler->pNext;
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700270#if ALLOC_DEBUG
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700271 printf("Free25 #%lu pSampler addr(%p)\n", ++g_free_count, (void*)pFreeMe);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700272#endif
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700273 free(pFreeMe);
274 }
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700275 g_pSamplerHead = NULL;
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700276}
Tobin Ehlis2a15a5f2015-02-24 09:16:47 -0700277static XGL_IMAGE_VIEW_CREATE_INFO* getImageViewCreateInfo(XGL_IMAGE_VIEW view)
278{
279 loader_platform_thread_lock_mutex(&globalLock);
280 IMAGE_NODE* pTrav = g_pImageHead;
281 while (pTrav) {
282 if (view == pTrav->image) {
283 loader_platform_thread_unlock_mutex(&globalLock);
284 return &pTrav->createInfo;
285 }
286 pTrav = pTrav->pNext;
287 }
288 loader_platform_thread_unlock_mutex(&globalLock);
289 return NULL;
290}
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700291// Free all image nodes
292static void freeImages()
293{
294 IMAGE_NODE* pImage = g_pImageHead;
295 IMAGE_NODE* pFreeMe = pImage;
296 while (pImage) {
297 pFreeMe = pImage;
298 pImage = pImage->pNext;
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700299#if ALLOC_DEBUG
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700300 printf("Free22 #%lu pImage addr(%p)\n", ++g_free_count, (void*)pFreeMe);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700301#endif
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700302 free(pFreeMe);
303 }
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700304 g_pImageHead = NULL;
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700305}
Tobin Ehlis2a15a5f2015-02-24 09:16:47 -0700306static XGL_BUFFER_VIEW_CREATE_INFO* getBufferViewCreateInfo(XGL_BUFFER_VIEW view)
307{
308 loader_platform_thread_lock_mutex(&globalLock);
309 BUFFER_NODE* pTrav = g_pBufferHead;
310 while (pTrav) {
311 if (view == pTrav->buffer) {
312 loader_platform_thread_unlock_mutex(&globalLock);
313 return &pTrav->createInfo;
314 }
315 pTrav = pTrav->pNext;
316 }
317 loader_platform_thread_unlock_mutex(&globalLock);
318 return NULL;
319}
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700320// Free all buffer nodes
321static void freeBuffers()
322{
323 BUFFER_NODE* pBuffer = g_pBufferHead;
324 BUFFER_NODE* pFreeMe = pBuffer;
325 while (pBuffer) {
326 pFreeMe = pBuffer;
327 pBuffer = pBuffer->pNext;
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700328#if ALLOC_DEBUG
329 printf("Free21 #%lu pBuffer addr(%p)\n", ++g_free_count, (void*)pFreeMe);
330#endif
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700331 free(pFreeMe);
332 }
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700333 g_pBufferHead = NULL;
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700334}
Tobin Ehlis93837a02015-02-13 13:30:07 -0700335static GLOBAL_CB_NODE* getCBNode(XGL_CMD_BUFFER cb);
Tobin Ehlis67449422015-03-02 10:16:40 -0700336
337static void updateCBTracking(XGL_CMD_BUFFER cb)
338{
339 g_lastCmdBuffer[getTIDIndex()] = cb;
340 GLOBAL_CB_NODE* pCB = getCBNode(cb);
341 loader_platform_thread_lock_mutex(&globalLock);
342 g_lastGlobalCB = pCB;
343 // TODO : This is a dumb algorithm. Need smart LRU that drops off oldest
344 for (uint32_t i = 0; i < NUM_COMMAND_BUFFERS_TO_DISPLAY; i++) {
345 if (g_pLastTouchedCB[i] == pCB) {
346 loader_platform_thread_unlock_mutex(&globalLock);
347 return;
348 }
349 }
350 g_pLastTouchedCB[g_lastTouchedCBIndex++] = pCB;
351 g_lastTouchedCBIndex = g_lastTouchedCBIndex % NUM_COMMAND_BUFFERS_TO_DISPLAY;
352 loader_platform_thread_unlock_mutex(&globalLock);
353}
354
Tobin Ehlis9dc93af2014-11-21 08:58:46 -0700355// Print the last bound dynamic state
Tobin Ehlisd01f7d62015-02-13 10:26:14 -0700356static void printDynamicState(const XGL_CMD_BUFFER cb)
Tobin Ehlis9dc93af2014-11-21 08:58:46 -0700357{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -0700358 GLOBAL_CB_NODE* pCB = getCBNode(cb);
359 if (pCB) {
360 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700361 char str[4*1024];
Tobin Ehlisd01f7d62015-02-13 10:26:14 -0700362 for (uint32_t i = 0; i < XGL_NUM_STATE_BIND_POINT; i++) {
363 if (pCB->lastBoundDynamicState[i]) {
364 sprintf(str, "Reporting CreateInfo for currently bound %s object %p", string_XGL_STATE_BIND_POINT(i), pCB->lastBoundDynamicState[i]->stateObj);
365 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pCB->lastBoundDynamicState[i]->stateObj, 0, DRAWSTATE_NONE, "DS", str);
366 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pCB->lastBoundDynamicState[i]->stateObj, 0, DRAWSTATE_NONE, "DS", dynamic_display(pCB->lastBoundDynamicState[i]->pCreateInfo, " "));
367 break;
368 }
369 else {
370 sprintf(str, "No dynamic state of type %s bound", string_XGL_STATE_BIND_POINT(i));
371 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", str);
372 }
Tobin Ehlis9dc93af2014-11-21 08:58:46 -0700373 }
Tobin Ehlisd01f7d62015-02-13 10:26:14 -0700374 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis9dc93af2014-11-21 08:58:46 -0700375 }
Tobin Ehlisd01f7d62015-02-13 10:26:14 -0700376 else {
377 char str[1024];
378 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cb);
379 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
380 }
Tobin Ehlis9dc93af2014-11-21 08:58:46 -0700381}
382// Retrieve pipeline node ptr for given pipeline object
Tobin Ehlis97657ce2014-10-24 12:01:45 -0600383static PIPELINE_NODE *getPipeline(XGL_PIPELINE pipeline)
384{
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700385 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis04178d72015-01-22 10:45:21 -0700386 PIPELINE_NODE *pTrav = g_pPipelineHead;
Tobin Ehlis97657ce2014-10-24 12:01:45 -0600387 while (pTrav) {
Tobin Ehlis4a744362014-11-21 12:04:39 -0700388 if (pTrav->pipeline == pipeline) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700389 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis97657ce2014-10-24 12:01:45 -0600390 return pTrav;
Tobin Ehlis4a744362014-11-21 12:04:39 -0700391 }
Tobin Ehlis97657ce2014-10-24 12:01:45 -0600392 pTrav = pTrav->pNext;
393 }
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700394 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis97657ce2014-10-24 12:01:45 -0600395 return NULL;
396}
397
Tobin Ehlis612ec6c2014-11-20 10:48:56 -0700398// For given sampler, return a ptr to its Create Info struct, or NULL if sampler not found
399static XGL_SAMPLER_CREATE_INFO* getSamplerCreateInfo(const XGL_SAMPLER sampler)
400{
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700401 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis04178d72015-01-22 10:45:21 -0700402 SAMPLER_NODE *pTrav = g_pSamplerHead;
Tobin Ehlis612ec6c2014-11-20 10:48:56 -0700403 while (pTrav) {
Tobin Ehlis4a744362014-11-21 12:04:39 -0700404 if (sampler == pTrav->sampler) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700405 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis612ec6c2014-11-20 10:48:56 -0700406 return &pTrav->createInfo;
Tobin Ehlis4a744362014-11-21 12:04:39 -0700407 }
Tobin Ehlis612ec6c2014-11-20 10:48:56 -0700408 pTrav = pTrav->pNext;
409 }
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700410 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis612ec6c2014-11-20 10:48:56 -0700411 return NULL;
412}
413
Tobin Ehlis97657ce2014-10-24 12:01:45 -0600414// Init the pipeline mapping info based on pipeline create info LL tree
Tobin Ehlis4a744362014-11-21 12:04:39 -0700415// Threading note : Calls to this function should wrapped in mutex
Tobin Ehlis97657ce2014-10-24 12:01:45 -0600416static void initPipeline(PIPELINE_NODE *pPipeline, const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo)
417{
Tobin Ehlis5742e772014-11-20 09:49:17 -0700418 // First init create info, we'll shadow the structs as we go down the tree
Tobin Ehlis9dc93af2014-11-21 08:58:46 -0700419 pPipeline->pCreateTree = (XGL_GRAPHICS_PIPELINE_CREATE_INFO*)malloc(sizeof(XGL_GRAPHICS_PIPELINE_CREATE_INFO));
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700420#if ALLOC_DEBUG
421 printf("Alloc5 #%lu pPipeline->pCreateTree addr(%p)\n", ++g_alloc_count, (void*)pPipeline->pCreateTree);
422#endif
Tobin Ehlis5742e772014-11-20 09:49:17 -0700423 memcpy(pPipeline->pCreateTree, pCreateInfo, sizeof(XGL_GRAPHICS_PIPELINE_CREATE_INFO));
Tobin Ehlis04178d72015-01-22 10:45:21 -0700424 GENERIC_HEADER *pShadowTrav = (GENERIC_HEADER*)pPipeline->pCreateTree;
425 GENERIC_HEADER *pTrav = (GENERIC_HEADER*)pCreateInfo->pNext;
Tobin Ehlis97657ce2014-10-24 12:01:45 -0600426 while (pTrav) {
Tobin Ehlis5742e772014-11-20 09:49:17 -0700427 // Shadow the struct
Tobin Ehlis04112922015-03-16 10:44:40 -0600428 pShadowTrav->pNext = (GENERIC_HEADER*)malloc(get_dynamic_struct_size(pTrav));
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700429#if ALLOC_DEBUG
430 printf("Alloc6 #%lu pShadowTrav->pNext addr(%p)\n", ++g_alloc_count, (void*)pShadowTrav->pNext);
431#endif
Tobin Ehlis5742e772014-11-20 09:49:17 -0700432 // Typically pNext is const so have to cast to avoid warning when we modify it here
Tobin Ehlis04112922015-03-16 10:44:40 -0600433 memcpy((void*)pShadowTrav->pNext, pTrav, get_dynamic_struct_size(pTrav));
Tobin Ehlis04178d72015-01-22 10:45:21 -0700434 pShadowTrav = (GENERIC_HEADER*)pShadowTrav->pNext;
435 // Special copy of Vtx info as it has embedded array
436 if (XGL_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO == pTrav->sType) {
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700437 XGL_PIPELINE_VERTEX_INPUT_CREATE_INFO *pVICI = (XGL_PIPELINE_VERTEX_INPUT_CREATE_INFO*)pShadowTrav;
Tobin Ehlisdb20d602014-11-25 10:24:15 -0700438 pPipeline->vtxBindingCount = pVICI->bindingCount;
439 uint32_t allocSize = pPipeline->vtxBindingCount * sizeof(XGL_VERTEX_INPUT_BINDING_DESCRIPTION);
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700440 if (allocSize) {
441 pPipeline->pVertexBindingDescriptions = (XGL_VERTEX_INPUT_BINDING_DESCRIPTION*)malloc(allocSize);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700442#if ALLOC_DEBUG
443 printf("Alloc7 #%lu pPipeline->pVertexBindingDescriptions addr(%p)\n", ++g_alloc_count, (void*)pPipeline->pVertexBindingDescriptions);
444#endif
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700445 memcpy(pPipeline->pVertexBindingDescriptions, ((XGL_PIPELINE_VERTEX_INPUT_CREATE_INFO*)pTrav)->pVertexAttributeDescriptions, allocSize);
446 }
Tobin Ehlisdb20d602014-11-25 10:24:15 -0700447 pPipeline->vtxAttributeCount = pVICI->attributeCount;
448 allocSize = pPipeline->vtxAttributeCount * sizeof(XGL_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION);
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700449 if (allocSize) {
450 pPipeline->pVertexAttributeDescriptions = (XGL_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION*)malloc(allocSize);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700451#if ALLOC_DEBUG
452 printf("Alloc8 #%lu pPipeline->pVertexAttributeDescriptions addr(%p)\n", ++g_alloc_count, (void*)pPipeline->pVertexAttributeDescriptions);
453#endif
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700454 memcpy(pPipeline->pVertexAttributeDescriptions, ((XGL_PIPELINE_VERTEX_INPUT_CREATE_INFO*)pTrav)->pVertexAttributeDescriptions, allocSize);
455 }
456 }
457 else if (XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO == pTrav->sType) {
458 // Special copy of CB state as it has embedded array
459 XGL_PIPELINE_CB_STATE_CREATE_INFO *pCBCI = (XGL_PIPELINE_CB_STATE_CREATE_INFO*)pShadowTrav;
460 pPipeline->attachmentCount = pCBCI->attachmentCount;
461 uint32_t allocSize = pPipeline->attachmentCount * sizeof(XGL_PIPELINE_CB_ATTACHMENT_STATE);
462 if (allocSize) {
463 pPipeline->pAttachments = (XGL_PIPELINE_CB_ATTACHMENT_STATE*)malloc(allocSize);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700464#if ALLOC_DEBUG
465 printf("Alloc9 #%lu pPipeline->pAttachments addr(%p)\n", ++g_alloc_count, (void*)pPipeline->pAttachments);
466#endif
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700467 XGL_PIPELINE_CB_ATTACHMENT_STATE** ppAttachments = (XGL_PIPELINE_CB_ATTACHMENT_STATE**)&pCBCI->pAttachments;
468 *ppAttachments = pPipeline->pAttachments;
469 memcpy(pPipeline->pAttachments, ((XGL_PIPELINE_CB_STATE_CREATE_INFO*)pTrav)->pAttachments, allocSize);
470 }
Tobin Ehlisdb20d602014-11-25 10:24:15 -0700471 }
Tobin Ehlis04178d72015-01-22 10:45:21 -0700472 pTrav = (GENERIC_HEADER*)pTrav->pNext;
Tobin Ehlis97657ce2014-10-24 12:01:45 -0600473 }
474}
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700475// Free the Pipeline nodes
476static void freePipelines()
477{
478 PIPELINE_NODE* pPipeline = g_pPipelineHead;
479 PIPELINE_NODE* pFreeMe = pPipeline;
480 while (pPipeline) {
481 pFreeMe = pPipeline;
482 GENERIC_HEADER* pShadowTrav = (GENERIC_HEADER*)pPipeline->pCreateTree;
483 GENERIC_HEADER* pShadowFree = pShadowTrav;
484 while (pShadowTrav) {
485 pShadowFree = pShadowTrav;
486 pShadowTrav = (GENERIC_HEADER*)pShadowTrav->pNext;
487 if (XGL_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO == pShadowFree->sType) {
488 // Free the vtx data shadowed directly into pPipeline node
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700489 if (pFreeMe->pVertexBindingDescriptions) {
490#if ALLOC_DEBUG
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700491 printf("Free7 #%lu pVertexBindingDescriptions addr(%p)\n", ++g_free_count, (void*)pFreeMe->pVertexBindingDescriptions);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700492#endif
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700493 free(pFreeMe->pVertexBindingDescriptions);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700494 }
495 if (pFreeMe->pVertexAttributeDescriptions) {
496#if ALLOC_DEBUG
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700497 printf("Free8 #%lu pVertexAttributeDescriptions addr(%p)\n", ++g_free_count, (void*)pFreeMe->pVertexAttributeDescriptions);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700498#endif
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700499 free(pFreeMe->pVertexAttributeDescriptions);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700500 }
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700501 }
502 else if (XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO == pShadowFree->sType) {
503 // Free attachment data shadowed into pPipeline node
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700504 if (pFreeMe->pAttachments) {
505#if ALLOC_DEBUG
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700506 printf("Free9 #%lu pAttachments addr(%p)\n", ++g_free_count, (void*)pFreeMe->pAttachments);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700507#endif
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700508 free(pFreeMe->pAttachments);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700509 }
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700510 }
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700511#if ALLOC_DEBUG
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700512 printf("Free5 & Free6 #%lu pShadowNode addr(%p)\n", ++g_free_count, (void*)pShadowFree);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700513#endif
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700514 free(pShadowFree);
515 }
516 pPipeline = pPipeline->pNext;
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700517#if ALLOC_DEBUG
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700518 printf("Free23 & Free24 #%lu pPipeline addr(%p)\n", ++g_free_count, (void*)pFreeMe);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700519#endif
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700520 free(pFreeMe);
521 }
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700522 g_pPipelineHead = NULL;
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700523}
Tobin Ehlis97657ce2014-10-24 12:01:45 -0600524// Block of code at start here specifically for managing/tracking DSs
Tobin Ehlis70f47262014-10-27 17:12:54 -0600525
Tobin Ehlis7265e832015-01-19 08:42:29 -0700526// ptr to HEAD of LL of DS Regions
527static REGION_NODE* g_pRegionHead = NULL;
Tobin Ehlis04178d72015-01-22 10:45:21 -0700528// ptr to HEAD of LL of top-level Layouts
529static LAYOUT_NODE* g_pLayoutHead = NULL;
Tobin Ehlis7e65d752015-01-15 17:51:52 -0700530
Tobin Ehlis7265e832015-01-19 08:42:29 -0700531// Return Region node ptr for specified region or else NULL
532static REGION_NODE* getRegionNode(XGL_DESCRIPTOR_REGION region)
533{
Tobin Ehlisb0497852015-02-11 14:24:02 -0700534 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -0700535 REGION_NODE* pTrav = g_pRegionHead;
536 while (pTrav) {
537 if (pTrav->region == region) {
Tobin Ehlisb0497852015-02-11 14:24:02 -0700538 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -0700539 return pTrav;
540 }
541 pTrav = pTrav->pNext;
542 }
Tobin Ehlisb0497852015-02-11 14:24:02 -0700543 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -0700544 return NULL;
545}
Tobin Ehlis7265e832015-01-19 08:42:29 -0700546// Return Set node ptr for specified set or else NULL
Tobin Ehlis04178d72015-01-22 10:45:21 -0700547static SET_NODE* getSetNode(XGL_DESCRIPTOR_SET set)
Tobin Ehlis7265e832015-01-19 08:42:29 -0700548{
Tobin Ehlisb0497852015-02-11 14:24:02 -0700549 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -0700550 REGION_NODE* pTrav = g_pRegionHead;
551 while (pTrav) {
Tobin Ehlis04178d72015-01-22 10:45:21 -0700552 SET_NODE* pSet = pTrav->pSets;
553 while (pSet) {
554 if (pSet->set == set) {
Tobin Ehlisb0497852015-02-11 14:24:02 -0700555 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis04178d72015-01-22 10:45:21 -0700556 return pSet;
557 }
558 pSet = pSet->pNext;
559 }
560 pTrav = pTrav->pNext;
561 }
Tobin Ehlisb0497852015-02-11 14:24:02 -0700562 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis04178d72015-01-22 10:45:21 -0700563 return NULL;
564}
565
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700566// Return XGL_TRUE if DS Exists and is within an xglBeginDescriptorRegionUpdate() call sequence, otherwise XGL_FALSE
567static bool32_t dsUpdateActive(XGL_DESCRIPTOR_SET ds)
568{
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700569 // Note, both "get" functions use global mutex so this guy does not
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700570 SET_NODE* pTrav = getSetNode(ds);
571 if (pTrav) {
572 REGION_NODE* pRegion = NULL;
573 pRegion = getRegionNode(pTrav->region);
574 if (pRegion) {
575 return pRegion->updateActive;
576 }
577 }
578 return XGL_FALSE;
579}
580
Tobin Ehlis04178d72015-01-22 10:45:21 -0700581static LAYOUT_NODE* getLayoutNode(XGL_DESCRIPTOR_SET_LAYOUT layout) {
Tobin Ehlisb0497852015-02-11 14:24:02 -0700582 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis04178d72015-01-22 10:45:21 -0700583 LAYOUT_NODE* pTrav = g_pLayoutHead;
584 while (pTrav) {
585 if (pTrav->layout == layout) {
Tobin Ehlisb0497852015-02-11 14:24:02 -0700586 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -0700587 return pTrav;
588 }
589 pTrav = pTrav->pNext;
590 }
Tobin Ehlisb0497852015-02-11 14:24:02 -0700591 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -0700592 return NULL;
593}
Tobin Ehlis97657ce2014-10-24 12:01:45 -0600594
Tobin Ehlis04178d72015-01-22 10:45:21 -0700595static uint32_t getUpdateIndex(GENERIC_HEADER* pUpdateStruct)
596{
597 switch (pUpdateStruct->sType)
598 {
599 case XGL_STRUCTURE_TYPE_UPDATE_SAMPLERS:
600 return ((XGL_UPDATE_SAMPLERS*)pUpdateStruct)->index;
601 case XGL_STRUCTURE_TYPE_UPDATE_SAMPLER_TEXTURES:
602 return ((XGL_UPDATE_SAMPLER_TEXTURES*)pUpdateStruct)->index;
603 case XGL_STRUCTURE_TYPE_UPDATE_IMAGES:
604 return ((XGL_UPDATE_IMAGES*)pUpdateStruct)->index;
605 case XGL_STRUCTURE_TYPE_UPDATE_BUFFERS:
606 return ((XGL_UPDATE_BUFFERS*)pUpdateStruct)->index;
607 case XGL_STRUCTURE_TYPE_UPDATE_AS_COPY:
608 return ((XGL_UPDATE_AS_COPY*)pUpdateStruct)->descriptorIndex;
609 default:
610 // TODO : Flag specific error for this case
611 return 0;
612 }
613}
614
615static uint32_t getUpdateUpperBound(GENERIC_HEADER* pUpdateStruct)
616{
617 switch (pUpdateStruct->sType)
618 {
619 case XGL_STRUCTURE_TYPE_UPDATE_SAMPLERS:
Tobin Ehlis481ec712015-02-19 09:55:18 -0700620 return (((XGL_UPDATE_SAMPLERS*)pUpdateStruct)->count + ((XGL_UPDATE_SAMPLERS*)pUpdateStruct)->index);
Tobin Ehlis04178d72015-01-22 10:45:21 -0700621 case XGL_STRUCTURE_TYPE_UPDATE_SAMPLER_TEXTURES:
Tobin Ehlis481ec712015-02-19 09:55:18 -0700622 return (((XGL_UPDATE_SAMPLER_TEXTURES*)pUpdateStruct)->count + ((XGL_UPDATE_SAMPLER_TEXTURES*)pUpdateStruct)->index);
Tobin Ehlis04178d72015-01-22 10:45:21 -0700623 case XGL_STRUCTURE_TYPE_UPDATE_IMAGES:
Tobin Ehlis481ec712015-02-19 09:55:18 -0700624 return (((XGL_UPDATE_IMAGES*)pUpdateStruct)->count + ((XGL_UPDATE_IMAGES*)pUpdateStruct)->index);
Tobin Ehlis04178d72015-01-22 10:45:21 -0700625 case XGL_STRUCTURE_TYPE_UPDATE_BUFFERS:
Tobin Ehlis481ec712015-02-19 09:55:18 -0700626 return (((XGL_UPDATE_BUFFERS*)pUpdateStruct)->count + ((XGL_UPDATE_BUFFERS*)pUpdateStruct)->index);
Tobin Ehlis04178d72015-01-22 10:45:21 -0700627 case XGL_STRUCTURE_TYPE_UPDATE_AS_COPY:
628 // TODO : Need to understand this case better and make sure code is correct
Tobin Ehlis481ec712015-02-19 09:55:18 -0700629 return (((XGL_UPDATE_AS_COPY*)pUpdateStruct)->count + ((XGL_UPDATE_AS_COPY*)pUpdateStruct)->descriptorIndex);
Tobin Ehlis04178d72015-01-22 10:45:21 -0700630 default:
631 // TODO : Flag specific error for this case
632 return 0;
633 }
634}
635
636// Verify that the descriptor type in the update struct matches what's expected by the layout
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700637static bool32_t validateUpdateType(GENERIC_HEADER* pUpdateStruct, const LAYOUT_NODE* pLayout)//XGL_DESCRIPTOR_TYPE type)
Tobin Ehlis04178d72015-01-22 10:45:21 -0700638{
639 // First get actual type of update
640 XGL_DESCRIPTOR_TYPE actualType;
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700641 uint32_t i = 0;
642 uint32_t bound = getUpdateUpperBound(pUpdateStruct);
Tobin Ehlis04178d72015-01-22 10:45:21 -0700643 switch (pUpdateStruct->sType)
644 {
645 case XGL_STRUCTURE_TYPE_UPDATE_SAMPLERS:
646 actualType = XGL_DESCRIPTOR_TYPE_SAMPLER;
647 break;
648 case XGL_STRUCTURE_TYPE_UPDATE_SAMPLER_TEXTURES:
649 actualType = XGL_DESCRIPTOR_TYPE_SAMPLER_TEXTURE;
650 break;
651 case XGL_STRUCTURE_TYPE_UPDATE_IMAGES:
652 actualType = ((XGL_UPDATE_IMAGES*)pUpdateStruct)->descriptorType;
653 break;
654 case XGL_STRUCTURE_TYPE_UPDATE_BUFFERS:
655 actualType = ((XGL_UPDATE_BUFFERS*)pUpdateStruct)->descriptorType;
656 break;
657 case XGL_STRUCTURE_TYPE_UPDATE_AS_COPY:
658 actualType = ((XGL_UPDATE_AS_COPY*)pUpdateStruct)->descriptorType;
659 break;
660 default:
661 // TODO : Flag specific error for this case
662 return 0;
663 }
Tobin Ehlis481ec712015-02-19 09:55:18 -0700664 for (i = getUpdateIndex(pUpdateStruct); i < bound; i++) {
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700665 if (pLayout->pTypes[i] != actualType)
666 return 0;
667 }
668 return 1;
Tobin Ehlis04178d72015-01-22 10:45:21 -0700669}
670
671// Verify that update region for this update does not exceed max layout index for this type
672static bool32_t validateUpdateSize(GENERIC_HEADER* pUpdateStruct, uint32_t layoutIdx)
673{
Tobin Ehlis481ec712015-02-19 09:55:18 -0700674 if ((getUpdateUpperBound(pUpdateStruct)-1) > layoutIdx)
Tobin Ehlis04178d72015-01-22 10:45:21 -0700675 return 0;
676 return 1;
677}
Tobin Ehlis04178d72015-01-22 10:45:21 -0700678// Determine the update type, allocate a new struct of that type, shadow the given pUpdate
679// struct into the new struct and return ptr to shadow struct cast as GENERIC_HEADER
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700680// NOTE : Calls to this function should be wrapped in mutex
Tobin Ehlis04178d72015-01-22 10:45:21 -0700681static GENERIC_HEADER* shadowUpdateNode(GENERIC_HEADER* pUpdate)
682{
683 GENERIC_HEADER* pNewNode = NULL;
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700684 size_t array_size = 0;
Tobin Ehlis6926cd92015-02-11 13:13:18 -0700685 size_t base_array_size = 0;
686 size_t total_array_size = 0;
Tobin Ehlis3bca6b52015-02-18 14:38:11 -0700687 size_t baseBuffAddr = 0;
Tobin Ehlis6926cd92015-02-11 13:13:18 -0700688 XGL_UPDATE_BUFFERS* pUBCI;
Tobin Ehlis3bca6b52015-02-18 14:38:11 -0700689 XGL_UPDATE_IMAGES* pUICI;
Tobin Ehlis297b9852015-02-23 16:09:58 -0700690 char str[1024];
Tobin Ehlis04178d72015-01-22 10:45:21 -0700691 switch (pUpdate->sType)
692 {
693 case XGL_STRUCTURE_TYPE_UPDATE_SAMPLERS:
694 pNewNode = (GENERIC_HEADER*)malloc(sizeof(XGL_UPDATE_SAMPLERS));
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700695#if ALLOC_DEBUG
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700696 printf("Alloc10 #%lu pNewNode addr(%p)\n", ++g_alloc_count, (void*)pNewNode);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700697#endif
Tobin Ehlis04178d72015-01-22 10:45:21 -0700698 memcpy(pNewNode, pUpdate, sizeof(XGL_UPDATE_SAMPLERS));
699 array_size = sizeof(XGL_SAMPLER) * ((XGL_UPDATE_SAMPLERS*)pNewNode)->count;
700 ((XGL_UPDATE_SAMPLERS*)pNewNode)->pSamplers = (XGL_SAMPLER*)malloc(array_size);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700701#if ALLOC_DEBUG
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700702 printf("Alloc11 #%lu pNewNode->pSamplers addr(%p)\n", ++g_alloc_count, (void*)((XGL_UPDATE_SAMPLERS*)pNewNode)->pSamplers);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700703#endif
Tobin Ehlis04178d72015-01-22 10:45:21 -0700704 memcpy((XGL_SAMPLER*)((XGL_UPDATE_SAMPLERS*)pNewNode)->pSamplers, ((XGL_UPDATE_SAMPLERS*)pUpdate)->pSamplers, array_size);
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700705 break;
Tobin Ehlis04178d72015-01-22 10:45:21 -0700706 case XGL_STRUCTURE_TYPE_UPDATE_SAMPLER_TEXTURES:
707 pNewNode = (GENERIC_HEADER*)malloc(sizeof(XGL_UPDATE_SAMPLER_TEXTURES));
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700708#if ALLOC_DEBUG
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700709 printf("Alloc12 #%lu pNewNode addr(%p)\n", ++g_alloc_count, (void*)pNewNode);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700710#endif
Tobin Ehlis04178d72015-01-22 10:45:21 -0700711 memcpy(pNewNode, pUpdate, sizeof(XGL_UPDATE_SAMPLER_TEXTURES));
712 array_size = sizeof(XGL_SAMPLER_IMAGE_VIEW_INFO) * ((XGL_UPDATE_SAMPLER_TEXTURES*)pNewNode)->count;
713 ((XGL_UPDATE_SAMPLER_TEXTURES*)pNewNode)->pSamplerImageViews = (XGL_SAMPLER_IMAGE_VIEW_INFO*)malloc(array_size);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700714#if ALLOC_DEBUG
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700715 printf("Alloc13 #%lu pNewNode->pSamplerImageViews addr(%p)\n", ++g_alloc_count, (void*)((XGL_UPDATE_SAMPLER_TEXTURES*)pNewNode)->pSamplerImageViews);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700716#endif
Tobin Ehlis04178d72015-01-22 10:45:21 -0700717 for (uint32_t i = 0; i < ((XGL_UPDATE_SAMPLER_TEXTURES*)pNewNode)->count; i++) {
718 memcpy((XGL_SAMPLER_IMAGE_VIEW_INFO*)&((XGL_UPDATE_SAMPLER_TEXTURES*)pNewNode)->pSamplerImageViews[i], &((XGL_UPDATE_SAMPLER_TEXTURES*)pUpdate)->pSamplerImageViews[i], sizeof(XGL_SAMPLER_IMAGE_VIEW_INFO));
719 ((XGL_SAMPLER_IMAGE_VIEW_INFO*)((XGL_UPDATE_SAMPLER_TEXTURES*)pNewNode)->pSamplerImageViews)[i].pImageView = malloc(sizeof(XGL_IMAGE_VIEW_ATTACH_INFO));
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700720#if ALLOC_DEBUG
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700721 printf("Alloc14 #%lu pSamplerImageViews)[%u].pImageView addr(%p)\n", ++g_alloc_count, i, (void*)((XGL_SAMPLER_IMAGE_VIEW_INFO*)((XGL_UPDATE_SAMPLER_TEXTURES*)pNewNode)->pSamplerImageViews)[i].pImageView);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700722#endif
Tobin Ehlis04178d72015-01-22 10:45:21 -0700723 memcpy((XGL_IMAGE_VIEW_ATTACH_INFO*)((XGL_UPDATE_SAMPLER_TEXTURES*)pNewNode)->pSamplerImageViews[i].pImageView, ((XGL_UPDATE_SAMPLER_TEXTURES*)pUpdate)->pSamplerImageViews[i].pImageView, sizeof(XGL_IMAGE_VIEW_ATTACH_INFO));
724 }
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700725 break;
Tobin Ehlis04178d72015-01-22 10:45:21 -0700726 case XGL_STRUCTURE_TYPE_UPDATE_IMAGES:
Tobin Ehlis3bca6b52015-02-18 14:38:11 -0700727 pUICI = (XGL_UPDATE_IMAGES*)pUpdate;
Tobin Ehlis04178d72015-01-22 10:45:21 -0700728 pNewNode = (GENERIC_HEADER*)malloc(sizeof(XGL_UPDATE_IMAGES));
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700729#if ALLOC_DEBUG
730 printf("Alloc15 #%lu pNewNode addr(%p)\n", ++g_alloc_count, (void*)pNewNode);
731#endif
Tobin Ehlis04178d72015-01-22 10:45:21 -0700732 memcpy(pNewNode, pUpdate, sizeof(XGL_UPDATE_IMAGES));
Tobin Ehlis6926cd92015-02-11 13:13:18 -0700733 base_array_size = sizeof(XGL_IMAGE_VIEW_ATTACH_INFO*) * ((XGL_UPDATE_IMAGES*)pNewNode)->count;
734 total_array_size = (sizeof(XGL_IMAGE_VIEW_ATTACH_INFO) * ((XGL_UPDATE_IMAGES*)pNewNode)->count) + base_array_size;
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700735 XGL_IMAGE_VIEW_ATTACH_INFO*** pppLocalImageViews = (XGL_IMAGE_VIEW_ATTACH_INFO***)&((XGL_UPDATE_IMAGES*)pNewNode)->pImageViews;
736 *pppLocalImageViews = (XGL_IMAGE_VIEW_ATTACH_INFO**)malloc(total_array_size);
Tobin Ehlis3bca6b52015-02-18 14:38:11 -0700737#if ALLOC_DEBUG
738 printf("Alloc16 #%lu *pppLocalImageViews addr(%p)\n", ++g_alloc_count, (void*)*pppLocalImageViews);
739#endif
740 baseBuffAddr = (size_t)(*pppLocalImageViews) + base_array_size;
741 for (uint32_t i = 0; i < pUICI->count; i++) {
Tobin Ehlis58c025c2015-02-19 13:14:59 -0700742 (*pppLocalImageViews)[i] = (XGL_IMAGE_VIEW_ATTACH_INFO*)(baseBuffAddr + (i * sizeof(XGL_IMAGE_VIEW_ATTACH_INFO)));
743 memcpy((*pppLocalImageViews)[i], pUICI->pImageViews[i], sizeof(XGL_IMAGE_VIEW_ATTACH_INFO));
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700744 }
745 break;
Tobin Ehlis04178d72015-01-22 10:45:21 -0700746 case XGL_STRUCTURE_TYPE_UPDATE_BUFFERS:
Tobin Ehlis6926cd92015-02-11 13:13:18 -0700747 pUBCI = (XGL_UPDATE_BUFFERS*)pUpdate;
Tobin Ehlis04178d72015-01-22 10:45:21 -0700748 pNewNode = (GENERIC_HEADER*)malloc(sizeof(XGL_UPDATE_BUFFERS));
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700749#if ALLOC_DEBUG
750 printf("Alloc17 #%lu pNewNode addr(%p)\n", ++g_alloc_count, (void*)pNewNode);
751#endif
Tobin Ehlis04178d72015-01-22 10:45:21 -0700752 memcpy(pNewNode, pUpdate, sizeof(XGL_UPDATE_BUFFERS));
Tobin Ehlis6926cd92015-02-11 13:13:18 -0700753 base_array_size = sizeof(XGL_BUFFER_VIEW_ATTACH_INFO*) * pUBCI->count;
754 total_array_size = (sizeof(XGL_BUFFER_VIEW_ATTACH_INFO) * pUBCI->count) + base_array_size;
755 XGL_BUFFER_VIEW_ATTACH_INFO*** pppLocalBufferViews = (XGL_BUFFER_VIEW_ATTACH_INFO***)&((XGL_UPDATE_BUFFERS*)pNewNode)->pBufferViews;
756 *pppLocalBufferViews = (XGL_BUFFER_VIEW_ATTACH_INFO**)malloc(total_array_size);
Tobin Ehlis3bca6b52015-02-18 14:38:11 -0700757#if ALLOC_DEBUG
758 printf("Alloc18 #%lu *pppLocalBufferViews addr(%p)\n", ++g_alloc_count, (void*)*pppLocalBufferViews);
759#endif
760 baseBuffAddr = (size_t)(*pppLocalBufferViews) + base_array_size;
Tobin Ehlis6926cd92015-02-11 13:13:18 -0700761 for (uint32_t i = 0; i < pUBCI->count; i++) {
762 // Set ptr and then copy data into that ptr
Tobin Ehlis58c025c2015-02-19 13:14:59 -0700763 (*pppLocalBufferViews)[i] = (XGL_BUFFER_VIEW_ATTACH_INFO*)(baseBuffAddr + (i * sizeof(XGL_BUFFER_VIEW_ATTACH_INFO)));
764 memcpy((*pppLocalBufferViews)[i], pUBCI->pBufferViews[i], sizeof(XGL_BUFFER_VIEW_ATTACH_INFO));
Tobin Ehlis6926cd92015-02-11 13:13:18 -0700765 }
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700766 break;
Tobin Ehlis04178d72015-01-22 10:45:21 -0700767 case XGL_STRUCTURE_TYPE_UPDATE_AS_COPY:
768 pNewNode = (GENERIC_HEADER*)malloc(sizeof(XGL_UPDATE_AS_COPY));
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700769#if ALLOC_DEBUG
770 printf("Alloc19 #%lu pNewNode addr(%p)\n", ++g_alloc_count, (void*)pNewNode);
771#endif
Tobin Ehlis04178d72015-01-22 10:45:21 -0700772 memcpy(pNewNode, pUpdate, sizeof(XGL_UPDATE_AS_COPY));
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700773 break;
Tobin Ehlis04178d72015-01-22 10:45:21 -0700774 default:
Tobin Ehlis297b9852015-02-23 16:09:58 -0700775 sprintf(str, "Unexpected UPDATE struct of type %s (value %u) in xglUpdateDescriptors() struct tree", string_XGL_STRUCTURE_TYPE(pUpdate->sType), pUpdate->sType);
776 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS", str);
Tobin Ehlis04178d72015-01-22 10:45:21 -0700777 return NULL;
778 }
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700779 // Make sure that pNext for the end of shadow copy is NULL
Tobin Ehlis04178d72015-01-22 10:45:21 -0700780 pNewNode->pNext = NULL;
781 return pNewNode;
782}
Tobin Ehlis297b9852015-02-23 16:09:58 -0700783// For given ds, update its mapping based on pUpdateChain linked-list
Tobin Ehlis04178d72015-01-22 10:45:21 -0700784static void dsUpdate(XGL_DESCRIPTOR_SET ds, GENERIC_HEADER* pUpdateChain)
785{
786 SET_NODE* pSet = getSetNode(ds);
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700787 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis4821eef2015-03-02 16:09:15 -0700788 g_lastBoundDescriptorSet = pSet->set;
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700789 LAYOUT_NODE* pLayout = NULL;
Tobin Ehlisef0c47c2015-02-25 11:46:39 -0700790 XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO* pLayoutCI = NULL;
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700791 // TODO : If pCIList is NULL, flag error
Tobin Ehlis04178d72015-01-22 10:45:21 -0700792 GENERIC_HEADER* pUpdates = pUpdateChain;
793 // Perform all updates
794 while (pUpdates) {
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700795 pLayout = pSet->pLayouts;
Tobin Ehlis04178d72015-01-22 10:45:21 -0700796 // For each update first find the layout section that it overlaps
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700797 while (pLayout && (pLayout->startIndex > getUpdateIndex(pUpdates))) {
798 pLayout = pLayout->pPriorSetLayout;
Tobin Ehlis04178d72015-01-22 10:45:21 -0700799 }
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700800 if (!pLayout) {
Tobin Ehlis04178d72015-01-22 10:45:21 -0700801 char str[1024];
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700802 sprintf(str, "Descriptor Set %p does not have index to match update index %u for update type %s!", ds, getUpdateIndex(pUpdates), string_XGL_STRUCTURE_TYPE(pUpdates->sType));
803 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, ds, 0, DRAWSTATE_INVALID_UPDATE_INDEX, "DS", str);
Tobin Ehlis04178d72015-01-22 10:45:21 -0700804 }
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700805 else {
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700806 // Next verify that update is correct size
807 if (!validateUpdateSize(pUpdates, pLayout->endIndex)) {
808 char str[48*1024]; // TODO : Keep count of layout CI structs and size this string dynamically based on that count
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700809 pLayoutCI = (XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO*)pLayout->pCreateInfoList;
Tobin Ehlisef0c47c2015-02-25 11:46:39 -0700810 char* pDSstr = xgl_print_xgl_descriptor_set_layout_create_info(pLayoutCI, "{DS} ");
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700811 sprintf(str, "Descriptor update type of %s is out of bounds for matching layout w/ CI:\n%s!", string_XGL_STRUCTURE_TYPE(pUpdates->sType), pDSstr);
812 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, ds, 0, DRAWSTATE_DESCRIPTOR_UPDATE_OUT_OF_BOUNDS, "DS", str);
813 free(pDSstr);
Tobin Ehlis04178d72015-01-22 10:45:21 -0700814 }
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700815 else { // TODO : should we skip update on a type mismatch or force it?
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700816 // We have the right layout section, now verify that update is of the right type
817 if (!validateUpdateType(pUpdates, pLayout)) {
Tobin Ehlis04178d72015-01-22 10:45:21 -0700818 char str[1024];
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700819 sprintf(str, "Descriptor update type of %s does not match overlapping layout type!", string_XGL_STRUCTURE_TYPE(pUpdates->sType));
820 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, ds, 0, DRAWSTATE_DESCRIPTOR_TYPE_MISMATCH, "DS", str);
Tobin Ehlis04178d72015-01-22 10:45:21 -0700821 }
822 else {
Tobin Ehlis481ec712015-02-19 09:55:18 -0700823 // Save the update info
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700824 // TODO : Info message that update successful
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700825 // Create new update struct for this set's shadow copy
826 GENERIC_HEADER* pNewNode = shadowUpdateNode(pUpdates);
827 if (NULL == pNewNode) {
828 char str[1024];
829 sprintf(str, "Out of memory while attempting to allocate UPDATE struct in xglUpdateDescriptors()");
830 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, ds, 0, DRAWSTATE_OUT_OF_MEMORY, "DS", str);
Tobin Ehlis04178d72015-01-22 10:45:21 -0700831 }
832 else {
Tobin Ehlis481ec712015-02-19 09:55:18 -0700833 // Insert shadow node into LL of updates for this set
834 pNewNode->pNext = pSet->pUpdateStructs;
835 pSet->pUpdateStructs = pNewNode;
836 // Now update appropriate descriptor(s) to point to new Update node
837 for (uint32_t i = getUpdateIndex(pUpdates); i < getUpdateUpperBound(pUpdates); i++) {
Tobin Ehlisb62a6fa2015-02-25 16:34:54 -0700838 assert(i<pSet->descriptorCount);
Tobin Ehlis481ec712015-02-19 09:55:18 -0700839 pSet->ppDescriptors[i] = pNewNode;
Tobin Ehlisa3a693e2015-02-10 15:35:23 -0700840 }
Tobin Ehlis04178d72015-01-22 10:45:21 -0700841 }
842 }
843 }
844 }
845 pUpdates = (GENERIC_HEADER*)pUpdates->pNext;
846 }
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700847 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis04178d72015-01-22 10:45:21 -0700848}
Tobin Ehlis297b9852015-02-23 16:09:58 -0700849// Free the shadowed update node for this Set
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700850// NOTE : Calls to this function should be wrapped in mutex
Tobin Ehlis297b9852015-02-23 16:09:58 -0700851static void freeShadowUpdateTree(SET_NODE* pSet)
Tobin Ehlis04178d72015-01-22 10:45:21 -0700852{
Tobin Ehlis297b9852015-02-23 16:09:58 -0700853 GENERIC_HEADER* pShadowUpdate = pSet->pUpdateStructs;
854 pSet->pUpdateStructs = NULL;
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700855 GENERIC_HEADER* pFreeUpdate = pShadowUpdate;
Tobin Ehlis8cb421e2015-02-25 15:01:21 -0700856 // Clear the descriptor mappings as they will now be invalid
Tobin Ehlisb62a6fa2015-02-25 16:34:54 -0700857 memset(pSet->ppDescriptors, 0, pSet->descriptorCount*sizeof(GENERIC_HEADER*));
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700858 while(pShadowUpdate) {
859 pFreeUpdate = pShadowUpdate;
860 pShadowUpdate = (GENERIC_HEADER*)pShadowUpdate->pNext;
861 uint32_t index = 0;
862 XGL_UPDATE_SAMPLERS* pUS = NULL;
863 XGL_UPDATE_SAMPLER_TEXTURES* pUST = NULL;
864 XGL_UPDATE_IMAGES* pUI = NULL;
865 XGL_UPDATE_BUFFERS* pUB = NULL;
866 void** ppToFree = NULL;
867 switch (pFreeUpdate->sType)
868 {
869 case XGL_STRUCTURE_TYPE_UPDATE_SAMPLERS:
870 pUS = (XGL_UPDATE_SAMPLERS*)pFreeUpdate;
871 if (pUS->pSamplers) {
872 ppToFree = (void**)&pUS->pSamplers;
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700873#if ALLOC_DEBUG
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700874 printf("Free11 #%lu pSamplers addr(%p)\n", ++g_free_count, (void*)*ppToFree);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700875#endif
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700876 free(*ppToFree);
877 }
878 break;
879 case XGL_STRUCTURE_TYPE_UPDATE_SAMPLER_TEXTURES:
880 pUST = (XGL_UPDATE_SAMPLER_TEXTURES*)pFreeUpdate;
881 for (index = 0; index < pUST->count; index++) {
882 if (pUST->pSamplerImageViews[index].pImageView) {
883 ppToFree = (void**)&pUST->pSamplerImageViews[index].pImageView;
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700884#if ALLOC_DEBUG
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700885 printf("Free14 #%lu pImageView addr(%p)\n", ++g_free_count, (void*)*ppToFree);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700886#endif
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700887 free(*ppToFree);
888 }
889 }
890 ppToFree = (void**)&pUST->pSamplerImageViews;
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700891#if ALLOC_DEBUG
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700892 printf("Free13 #%lu pSamplerImageViews addr(%p)\n", ++g_free_count, (void*)*ppToFree);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700893#endif
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700894 free(*ppToFree);
895 break;
896 case XGL_STRUCTURE_TYPE_UPDATE_IMAGES:
897 pUI = (XGL_UPDATE_IMAGES*)pFreeUpdate;
898 if (pUI->pImageViews) {
899 ppToFree = (void**)&pUI->pImageViews;
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700900#if ALLOC_DEBUG
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700901 printf("Free16 #%lu pImageViews addr(%p)\n", ++g_free_count, (void*)*ppToFree);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700902#endif
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700903 free(*ppToFree);
904 }
905 break;
906 case XGL_STRUCTURE_TYPE_UPDATE_BUFFERS:
907 pUB = (XGL_UPDATE_BUFFERS*)pFreeUpdate;
908 if (pUB->pBufferViews) {
909 ppToFree = (void**)&pUB->pBufferViews;
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700910#if ALLOC_DEBUG
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700911 printf("Free18 #%lu pBufferViews addr(%p)\n", ++g_free_count, (void*)*ppToFree);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700912#endif
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700913 free(*ppToFree);
914 }
915 break;
916 case XGL_STRUCTURE_TYPE_UPDATE_AS_COPY:
917 break;
918 default:
919 assert(0);
920 break;
921 }
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700922#if ALLOC_DEBUG
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700923 printf("Free10, Free12, Free15, Free17, Free19 #%lu pUpdateNode addr(%p)\n", ++g_free_count, (void*)pFreeUpdate);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700924#endif
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700925 free(pFreeUpdate);
926 }
927}
928// Free all DS Regions including their Sets & related sub-structs
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700929// NOTE : Calls to this function should be wrapped in mutex
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700930static void freeRegions()
931{
932 REGION_NODE* pRegion = g_pRegionHead;
933 REGION_NODE* pFreeMe = pRegion;
934 while (pRegion) {
935 pFreeMe = pRegion;
936 SET_NODE* pSet = pRegion->pSets;
937 SET_NODE* pFreeSet = pSet;
938 while (pSet) {
939 pFreeSet = pSet;
940 pSet = pSet->pNext;
941 // Freeing layouts handled in freeLayouts() function
942 // Free Update shadow struct tree
Tobin Ehlis297b9852015-02-23 16:09:58 -0700943 freeShadowUpdateTree(pFreeSet);
Tobin Ehlis481ec712015-02-19 09:55:18 -0700944 if (pFreeSet->ppDescriptors) {
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700945#if ALLOC_DEBUG
Tobin Ehlis481ec712015-02-19 09:55:18 -0700946 printf("Free35 #%lu pSet->ppDescriptors addr(%p)\n", ++g_free_count, (void*)pFreeSet->ppDescriptors);
947#endif
948 free(pFreeSet->ppDescriptors);
949 }
950#if ALLOC_DEBUG
951 printf("Free32 #%lu pSet addr(%p)\n", ++g_free_count, (void*)pFreeSet);
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700952#endif
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700953 free(pFreeSet);
954 }
955 pRegion = pRegion->pNext;
956 if (pFreeMe->createInfo.pTypeCount) {
957 void** ppToFree = (void**)&pFreeMe->createInfo.pTypeCount;
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700958#if ALLOC_DEBUG
959 printf("Free31 #%lu pTypeCount addr(%p)\n", ++g_free_count, (void*)*ppToFree);
960#endif
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700961 free(*ppToFree);
962 }
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700963#if ALLOC_DEBUG
964 printf("Free30 #%lu pRegion addr(%p)\n", ++g_free_count, (void*)pFreeMe);
965#endif
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700966 free(pFreeMe);
967 }
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700968 g_pRegionHead = NULL;
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700969}
970// WARN : Once freeLayouts() called, any layout ptrs in Region/Set data structure will be invalid
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700971// NOTE : Calls to this function should be wrapped in mutex
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700972static void freeLayouts()
973{
974 LAYOUT_NODE* pLayout = g_pLayoutHead;
975 LAYOUT_NODE* pFreeLayout = pLayout;
976 while (pLayout) {
977 pFreeLayout = pLayout;
978 GENERIC_HEADER* pTrav = (GENERIC_HEADER*)pLayout->pCreateInfoList;
979 while (pTrav) {
980 void* pToFree = (void*)pTrav;
981 pTrav = (GENERIC_HEADER*)pTrav->pNext;
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700982#if ALLOC_DEBUG
983 printf("Free27 & Free28 #%lu pLayoutCITree addr(%p)\n", ++g_free_count, (void*)pToFree);
984#endif
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700985 free(pToFree);
986 }
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700987 if (pLayout->pTypes) {
988#if ALLOC_DEBUG
989 printf("Free29 #%lu pLayout->pTypes addr(%p)\n", ++g_free_count, (void*)pLayout->pTypes);
990#endif
991 free(pLayout->pTypes);
992 }
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700993 pLayout = pLayout->pNext;
Tobin Ehlis03d7a092015-02-17 16:27:03 -0700994#if ALLOC_DEBUG
995 printf("Free26 #%lu pLayout addr(%p)\n", ++g_free_count, (void*)pFreeLayout);
996#endif
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -0700997 free(pFreeLayout);
Tobin Ehlis04178d72015-01-22 10:45:21 -0700998 }
Tobin Ehlis8c2ed212015-02-20 09:30:06 -0700999 g_pLayoutHead = NULL;
Tobin Ehlis04178d72015-01-22 10:45:21 -07001000}
Tobin Ehlisa3a693e2015-02-10 15:35:23 -07001001// Currently clearing a set is removing all previous updates to that set
Tobin Ehlis04178d72015-01-22 10:45:21 -07001002// TODO : Validate if this is correct clearing behavior
1003static void clearDescriptorSet(XGL_DESCRIPTOR_SET set)
1004{
1005 SET_NODE* pSet = getSetNode(set);
1006 if (!pSet) {
1007 // TODO : Return error
1008 }
1009 else {
Tobin Ehlis8c2ed212015-02-20 09:30:06 -07001010 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis297b9852015-02-23 16:09:58 -07001011 freeShadowUpdateTree(pSet);
Tobin Ehlis8c2ed212015-02-20 09:30:06 -07001012 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis04178d72015-01-22 10:45:21 -07001013 }
1014}
1015
1016static void clearDescriptorRegion(XGL_DESCRIPTOR_REGION region)
1017{
1018 REGION_NODE* pRegion = getRegionNode(region);
1019 if (!pRegion) {
1020 char str[1024];
1021 sprintf(str, "Unable to find region node for region %p specified in xglClearDescriptorRegion() call", (void*)region);
1022 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, region, 0, DRAWSTATE_INVALID_REGION, "DS", str);
1023 }
1024 else
1025 {
1026 // For every set off of this region, clear it
1027 SET_NODE* pSet = pRegion->pSets;
1028 while (pSet) {
1029 clearDescriptorSet(pSet->set);
1030 }
1031 }
1032}
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001033
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07001034// Code here to manage the Cmd buffer LL
1035static GLOBAL_CB_NODE* getCBNode(XGL_CMD_BUFFER cb)
Tobin Ehlis9dc93af2014-11-21 08:58:46 -07001036{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07001037 loader_platform_thread_lock_mutex(&globalLock);
1038 GLOBAL_CB_NODE* pCB = g_pCmdBufferHead;
1039 while (pCB) {
1040 if (cb == pCB->cmdBuffer) {
1041 loader_platform_thread_unlock_mutex(&globalLock);
1042 return pCB;
1043 }
1044 pCB = pCB->pNextGlobalCBNode;
Tobin Ehlis9dc93af2014-11-21 08:58:46 -07001045 }
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07001046 loader_platform_thread_unlock_mutex(&globalLock);
1047 return NULL;
1048}
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -07001049// Free all CB Nodes
Tobin Ehlis8c2ed212015-02-20 09:30:06 -07001050// NOTE : Calls to this function should be wrapped in mutex
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -07001051static void freeCmdBuffers()
1052{
1053 GLOBAL_CB_NODE* pCB = g_pCmdBufferHead;
1054 GLOBAL_CB_NODE* pFreeMe = pCB;
1055 while (pCB) {
1056 pFreeMe = pCB;
1057 CMD_NODE* pCmd = pCB->pCmds;
1058 CMD_NODE* pFreeCmd = pCmd;
1059 while (pCmd) {
1060 pFreeCmd = pCmd;
1061 pCmd = pCmd->pNext;
Tobin Ehlis03d7a092015-02-17 16:27:03 -07001062#if ALLOC_DEBUG
1063 printf("Free20 #%lu pCmd addr(%p)\n", ++g_free_count, (void*)pFreeCmd);
1064#endif
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -07001065 free(pFreeCmd);
1066 }
1067 pCB = pCB->pNextGlobalCBNode;
Tobin Ehlis03d7a092015-02-17 16:27:03 -07001068#if ALLOC_DEBUG
1069 printf("Free33 #%lu pCB addr(%p)\n", ++g_free_count, (void*)pFreeMe);
1070#endif
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -07001071 free(pFreeMe);
1072 }
Tobin Ehlis8c2ed212015-02-20 09:30:06 -07001073 g_pCmdBufferHead = NULL;
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -07001074}
Tobin Ehlis93837a02015-02-13 13:30:07 -07001075static void addCmd(GLOBAL_CB_NODE* pCB, const CMD_TYPE cmd)
1076{
1077 CMD_NODE* pCmd = (CMD_NODE*)malloc(sizeof(CMD_NODE));
Tobin Ehlis03d7a092015-02-17 16:27:03 -07001078#if ALLOC_DEBUG
1079 printf("Alloc20 #%lu pCmd addr(%p)\n", ++g_alloc_count, (void*)pCmd);
1080#endif
Tobin Ehlis93837a02015-02-13 13:30:07 -07001081 if (pCmd) {
1082 // init cmd node and append to end of cmd LL
1083 memset(pCmd, 0, sizeof(CMD_NODE));
1084 pCB->numCmds++;
1085 pCmd->cmdNumber = pCB->numCmds;
1086 pCmd->type = cmd;
1087 if (!pCB->pCmds) {
1088 pCB->pCmds = pCmd;
1089 }
1090 else {
Tobin Ehlis10ae8c12015-03-17 16:24:32 -06001091 assert(pCB->pLastCmd);
1092 pCB->pLastCmd->pNext = pCmd;
Tobin Ehlis93837a02015-02-13 13:30:07 -07001093 }
Tobin Ehlis10ae8c12015-03-17 16:24:32 -06001094 pCB->pLastCmd = pCmd;
Tobin Ehlis93837a02015-02-13 13:30:07 -07001095 }
1096 else {
1097 char str[1024];
1098 sprintf(str, "Out of memory while attempting to allocate new CMD_NODE for cmdBuffer %p", (void*)pCB->cmdBuffer);
1099 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, pCB->cmdBuffer, 0, DRAWSTATE_OUT_OF_MEMORY, "DS", str);
1100 }
1101}
1102static void resetCB(const XGL_CMD_BUFFER cb)
1103{
1104 GLOBAL_CB_NODE* pCB = getCBNode(cb);
1105 if (pCB) {
1106 CMD_NODE* pCur = pCB->pCmds;
1107 CMD_NODE* pFreeMe = pCur;
1108 while (pCur) {
1109 pFreeMe = pCur;
1110 pCur = pCur->pNext;
Tobin Ehlis03d7a092015-02-17 16:27:03 -07001111#if ALLOC_DEBUG
Tobin Ehlis8c2ed212015-02-20 09:30:06 -07001112 printf("Free20 #%lu pCmd addr(%p)\n", ++g_free_count, (void*)pFreeMe);
Tobin Ehlis03d7a092015-02-17 16:27:03 -07001113#endif
Tobin Ehlis93837a02015-02-13 13:30:07 -07001114 free(pFreeMe);
1115 }
1116 // Reset CB state
1117 GLOBAL_CB_NODE* pSaveNext = pCB->pNextGlobalCBNode;
1118 XGL_FLAGS saveFlags = pCB->flags;
Courtney Goeltzenleuchter18248e62015-03-05 18:09:39 -07001119 uint32_t saveQueueNodeIndex = pCB->queueNodeIndex;
Tobin Ehlis93837a02015-02-13 13:30:07 -07001120 memset(pCB, 0, sizeof(GLOBAL_CB_NODE));
1121 pCB->cmdBuffer = cb;
1122 pCB->flags = saveFlags;
Courtney Goeltzenleuchter18248e62015-03-05 18:09:39 -07001123 pCB->queueNodeIndex = saveQueueNodeIndex;
Tobin Ehlis93837a02015-02-13 13:30:07 -07001124 pCB->pNextGlobalCBNode = pSaveNext;
1125 pCB->lastVtxBinding = MAX_BINDING;
1126 }
1127}
1128// Set the last bound dynamic state of given type
1129// TODO : Need to track this per cmdBuffer and correlate cmdBuffer for Draw w/ last bound for that cmdBuffer?
1130static void setLastBoundDynamicState(const XGL_CMD_BUFFER cmdBuffer, const XGL_DYNAMIC_STATE_OBJECT state, const XGL_STATE_BIND_POINT sType)
1131{
1132 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
1133 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07001134 updateCBTracking(cmdBuffer);
Tobin Ehlis8c2ed212015-02-20 09:30:06 -07001135 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis93837a02015-02-13 13:30:07 -07001136 addCmd(pCB, CMD_BINDDYNAMICSTATEOBJECT);
Tobin Ehlis93837a02015-02-13 13:30:07 -07001137 DYNAMIC_STATE_NODE* pTrav = g_pDynamicStateHead[sType];
1138 while (pTrav && (state != pTrav->stateObj)) {
1139 pTrav = pTrav->pNext;
1140 }
1141 if (!pTrav) {
1142 char str[1024];
1143 sprintf(str, "Unable to find dynamic state object %p, was it ever created?", (void*)state);
1144 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, state, 0, DRAWSTATE_INVALID_DYNAMIC_STATE_OBJECT, "DS", str);
1145 }
1146 pCB->lastBoundDynamicState[sType] = pTrav;
Tobin Ehlisae708b82015-02-27 08:48:43 -07001147 g_lastBoundDynamicState[sType] = pTrav;
Tobin Ehlis93837a02015-02-13 13:30:07 -07001148 loader_platform_thread_unlock_mutex(&globalLock);
1149 }
1150 else {
1151 char str[1024];
1152 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
1153 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
1154 }
1155}
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07001156// Print the last bound Gfx Pipeline
1157static void printPipeline(const XGL_CMD_BUFFER cb)
1158{
1159 GLOBAL_CB_NODE* pCB = getCBNode(cb);
1160 if (pCB) {
1161 PIPELINE_NODE *pPipeTrav = getPipeline(pCB->lastBoundPipeline);
1162 if (!pPipeTrav) {
1163 // nothing to print
1164 }
1165 else {
1166 char* pipeStr = xgl_print_xgl_graphics_pipeline_create_info(pPipeTrav->pCreateTree, "{DS}");
1167 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", pipeStr);
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -07001168 free(pipeStr);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07001169 }
Tobin Ehlis9dc93af2014-11-21 08:58:46 -07001170 }
1171}
Tobin Ehlisae708b82015-02-27 08:48:43 -07001172// Common Dot dumping code
1173static void dsCoreDumpDot(const XGL_DESCRIPTOR_SET ds, FILE* pOutFile)
Tobin Ehlis83562882014-11-27 15:43:39 -07001174{
Tobin Ehlisae708b82015-02-27 08:48:43 -07001175 SET_NODE* pSet = getSetNode(ds);
1176 if (pSet) {
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07001177 REGION_NODE* pRegion = getRegionNode(pSet->region);
Tobin Ehlis03d7a092015-02-17 16:27:03 -07001178 char tmp_str[4*1024];
Tobin Ehlis6926cd92015-02-11 13:13:18 -07001179 fprintf(pOutFile, "subgraph cluster_DescriptorRegion\n{\nlabel=\"Descriptor Region\"\n");
1180 sprintf(tmp_str, "Region (%p)", pRegion->region);
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -07001181 char* pGVstr = xgl_gv_print_xgl_descriptor_region_create_info(&pRegion->createInfo, tmp_str);
1182 fprintf(pOutFile, "%s", pGVstr);
1183 free(pGVstr);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07001184 fprintf(pOutFile, "subgraph cluster_DescriptorSet\n{\nlabel=\"Descriptor Set (%p)\"\n", pSet->set);
1185 sprintf(tmp_str, "Descriptor Set (%p)", pSet->set);
1186 LAYOUT_NODE* pLayout = pSet->pLayouts;
1187 uint32_t layout_index = 0;
1188 while (pLayout) {
1189 ++layout_index;
1190 sprintf(tmp_str, "LAYOUT%u", layout_index);
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -07001191 pGVstr = xgl_gv_print_xgl_descriptor_set_layout_create_info(pLayout->pCreateInfoList, tmp_str);
1192 fprintf(pOutFile, "%s", pGVstr);
1193 free(pGVstr);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07001194 pLayout = pLayout->pNext;
1195 if (pLayout) {
1196 fprintf(pOutFile, "\"%s\" -> \"LAYOUT%u\" [];\n", tmp_str, layout_index+1);
Tobin Ehlis83562882014-11-27 15:43:39 -07001197 }
Tobin Ehlis83562882014-11-27 15:43:39 -07001198 }
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07001199 if (pSet->pUpdateStructs) {
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -07001200 pGVstr = dynamic_gv_display(pSet->pUpdateStructs, "Descriptor Updates");
1201 fprintf(pOutFile, "%s", pGVstr);
1202 free(pGVstr);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07001203 }
Tobin Ehlis2a15a5f2015-02-24 09:16:47 -07001204 if (pSet->ppDescriptors) {
1205 //void* pDesc = NULL;
Tobin Ehlis4821eef2015-03-02 16:09:15 -07001206 fprintf(pOutFile, "\"DESCRIPTORS\" [\nlabel=<<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\"> <TR><TD COLSPAN=\"2\" PORT=\"desc\">DESCRIPTORS</TD></TR>");
Tobin Ehlis2a15a5f2015-02-24 09:16:47 -07001207 uint32_t i = 0;
1208 for (i=0; i < pSet->descriptorCount; i++) {
1209 if (pSet->ppDescriptors[i]) {
Tobin Ehlis4821eef2015-03-02 16:09:15 -07001210 fprintf(pOutFile, "<TR><TD PORT=\"slot%u\">slot%u</TD><TD>%s</TD></TR>", i, i, string_XGL_STRUCTURE_TYPE(pSet->ppDescriptors[i]->sType));
Tobin Ehlis2a15a5f2015-02-24 09:16:47 -07001211 }
1212 }
Ian Elliott5bd12da2015-02-25 17:34:46 -07001213#define NUM_COLORS 7
Tobin Ehlis8cb421e2015-02-25 15:01:21 -07001214 char* edgeColors[NUM_COLORS];
1215 edgeColors[0] = "0000ff";
1216 edgeColors[1] = "ff00ff";
1217 edgeColors[2] = "ffff00";
1218 edgeColors[3] = "00ff00";
1219 edgeColors[4] = "000000";
1220 edgeColors[5] = "00ffff";
1221 edgeColors[6] = "ff0000";
1222 uint32_t colorIdx = 0;
Tobin Ehlis2a15a5f2015-02-24 09:16:47 -07001223 fprintf(pOutFile, "</TABLE>>\n];\n");
1224 // Now add the views that are mapped to active descriptors
1225 XGL_UPDATE_SAMPLERS* pUS = NULL;
1226 XGL_UPDATE_SAMPLER_TEXTURES* pUST = NULL;
1227 XGL_UPDATE_IMAGES* pUI = NULL;
1228 XGL_UPDATE_BUFFERS* pUB = NULL;
1229 XGL_UPDATE_AS_COPY* pUAC = NULL;
1230 XGL_SAMPLER_CREATE_INFO* pSCI = NULL;
1231 XGL_IMAGE_VIEW_CREATE_INFO* pIVCI = NULL;
1232 XGL_BUFFER_VIEW_CREATE_INFO* pBVCI = NULL;
1233 for (i=0; i < pSet->descriptorCount; i++) {
1234 if (pSet->ppDescriptors[i]) {
1235 switch (pSet->ppDescriptors[i]->sType)
1236 {
1237 case XGL_STRUCTURE_TYPE_UPDATE_SAMPLERS:
1238 pUS = (XGL_UPDATE_SAMPLERS*)pSet->ppDescriptors[i];
1239 pSCI = getSamplerCreateInfo(pUS->pSamplers[i-pUS->index]);
1240 if (pSCI) {
1241 sprintf(tmp_str, "SAMPLER%u", i);
1242 fprintf(pOutFile, "%s", xgl_gv_print_xgl_sampler_create_info(pSCI, tmp_str));
Tobin Ehlis8cb421e2015-02-25 15:01:21 -07001243 fprintf(pOutFile, "\"DESCRIPTORS\":slot%u -> \"%s\" [color=\"#%s\"];\n", i, tmp_str, edgeColors[colorIdx]);
Tobin Ehlis2a15a5f2015-02-24 09:16:47 -07001244 }
1245 break;
1246 case XGL_STRUCTURE_TYPE_UPDATE_SAMPLER_TEXTURES:
1247 pUST = (XGL_UPDATE_SAMPLER_TEXTURES*)pSet->ppDescriptors[i];
1248 pSCI = getSamplerCreateInfo(pUST->pSamplerImageViews[i-pUST->index].pSampler);
1249 if (pSCI) {
1250 sprintf(tmp_str, "SAMPLER%u", i);
1251 fprintf(pOutFile, "%s", xgl_gv_print_xgl_sampler_create_info(pSCI, tmp_str));
Tobin Ehlis8cb421e2015-02-25 15:01:21 -07001252 fprintf(pOutFile, "\"DESCRIPTORS\":slot%u -> \"%s\" [color=\"#%s\"];\n", i, tmp_str, edgeColors[colorIdx]);
Tobin Ehlis2a15a5f2015-02-24 09:16:47 -07001253 }
1254 pIVCI = getImageViewCreateInfo(pUST->pSamplerImageViews[i-pUST->index].pImageView->view);
1255 if (pIVCI) {
1256 sprintf(tmp_str, "IMAGE_VIEW%u", i);
1257 fprintf(pOutFile, "%s", xgl_gv_print_xgl_image_view_create_info(pIVCI, tmp_str));
Tobin Ehlis8cb421e2015-02-25 15:01:21 -07001258 fprintf(pOutFile, "\"DESCRIPTORS\":slot%u -> \"%s\" [color=\"#%s\"];\n", i, tmp_str, edgeColors[colorIdx]);
Tobin Ehlis2a15a5f2015-02-24 09:16:47 -07001259 }
1260 break;
1261 case XGL_STRUCTURE_TYPE_UPDATE_IMAGES:
1262 pUI = (XGL_UPDATE_IMAGES*)pSet->ppDescriptors[i];
1263 pIVCI = getImageViewCreateInfo(pUI->pImageViews[i-pUI->index]->view);
1264 if (pIVCI) {
1265 sprintf(tmp_str, "IMAGE_VIEW%u", i);
1266 fprintf(pOutFile, "%s", xgl_gv_print_xgl_image_view_create_info(pIVCI, tmp_str));
Tobin Ehlis8cb421e2015-02-25 15:01:21 -07001267 fprintf(pOutFile, "\"DESCRIPTORS\":slot%u -> \"%s\" [color=\"#%s\"];\n", i, tmp_str, edgeColors[colorIdx]);
Tobin Ehlis2a15a5f2015-02-24 09:16:47 -07001268 }
1269 break;
1270 case XGL_STRUCTURE_TYPE_UPDATE_BUFFERS:
1271 pUB = (XGL_UPDATE_BUFFERS*)pSet->ppDescriptors[i];
1272 pBVCI = getBufferViewCreateInfo(pUB->pBufferViews[i-pUB->index]->view);
1273 if (pBVCI) {
1274 sprintf(tmp_str, "BUFFER_VIEW%u", i);
1275 fprintf(pOutFile, "%s", xgl_gv_print_xgl_buffer_view_create_info(pBVCI, tmp_str));
Tobin Ehlis8cb421e2015-02-25 15:01:21 -07001276 fprintf(pOutFile, "\"DESCRIPTORS\":slot%u -> \"%s\" [color=\"#%s\"];\n", i, tmp_str, edgeColors[colorIdx]);
Tobin Ehlis2a15a5f2015-02-24 09:16:47 -07001277 }
1278 break;
1279 case XGL_STRUCTURE_TYPE_UPDATE_AS_COPY:
1280 pUAC = (XGL_UPDATE_AS_COPY*)pSet->ppDescriptors[i];
1281 // TODO : Need to validate this code
1282 // Save off pNext and set to NULL while printing this struct, then restore it
1283 void** ppNextPtr = (void*)&pUAC->pNext;
1284 void* pSaveNext = *ppNextPtr;
1285 *ppNextPtr = NULL;
1286 sprintf(tmp_str, "UPDATE_AS_COPY%u", i);
1287 fprintf(pOutFile, "%s", xgl_gv_print_xgl_update_as_copy(pUAC, tmp_str));
Tobin Ehlis8cb421e2015-02-25 15:01:21 -07001288 fprintf(pOutFile, "\"DESCRIPTORS\":slot%u -> \"%s\" [color=\"#%s\"];\n", i, tmp_str, edgeColors[colorIdx]);
Tobin Ehlis2a15a5f2015-02-24 09:16:47 -07001289 // Restore next ptr
1290 *ppNextPtr = pSaveNext;
1291 break;
1292 default:
1293 break;
1294 }
Tobin Ehlis8cb421e2015-02-25 15:01:21 -07001295 colorIdx = (colorIdx+1) % NUM_COLORS;
Tobin Ehlis2a15a5f2015-02-24 09:16:47 -07001296 }
1297 }
1298 }
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07001299 fprintf(pOutFile, "}\n");
Tobin Ehlis83562882014-11-27 15:43:39 -07001300 fprintf(pOutFile, "}\n");
Tobin Ehlis6926cd92015-02-11 13:13:18 -07001301 pRegion = pRegion->pNext;
Tobin Ehlis83562882014-11-27 15:43:39 -07001302 }
1303}
Tobin Ehlisae708b82015-02-27 08:48:43 -07001304// Dump subgraph w/ DS info
1305static void dsDumpDot(const XGL_CMD_BUFFER cb, FILE* pOutFile)
1306{
1307 GLOBAL_CB_NODE* pCB = getCBNode(cb);
1308 if (pCB && pCB->lastBoundDescriptorSet) {
1309 dsCoreDumpDot(pCB->lastBoundDescriptorSet, pOutFile);
1310 }
1311}
Tobin Ehlis249c77e2015-02-24 15:40:22 -07001312// Dump a GraphViz dot file showing the Cmd Buffers
1313static void cbDumpDotFile(char *outFileName)
1314{
1315 // Print CB Chain for each CB
1316 FILE* pOutFile;
1317 pOutFile = fopen(outFileName, "w");
1318 fprintf(pOutFile, "digraph g {\ngraph [\nrankdir = \"TB\"\n];\nnode [\nfontsize = \"16\"\nshape = \"plaintext\"\n];\nedge [\n];\n");
1319 fprintf(pOutFile, "subgraph cluster_cmdBuffers\n{\nlabel=\"Command Buffers\"\n");
Tobin Ehlis67449422015-03-02 10:16:40 -07001320 GLOBAL_CB_NODE* pCB = g_pCmdBufferHead;
1321 for (uint32_t i = 0; i < NUM_COMMAND_BUFFERS_TO_DISPLAY; i++) {
1322 pCB = g_pLastTouchedCB[i];
1323 if (pCB) {
1324 fprintf(pOutFile, "subgraph cluster_cmdBuffer%u\n{\nlabel=\"Command Buffer #%u\"\n", i, i);
1325 CMD_NODE* pCmd = pCB->pCmds;
1326 uint32_t instNum = 0;
1327 while (pCmd) {
1328 if (instNum) {
1329 fprintf(pOutFile, "\"CB%pCMD%u\" -> \"CB%pCMD%u\" [];\n", (void*)pCB->cmdBuffer, instNum-1, (void*)pCB->cmdBuffer, instNum);
Tobin Ehlis249c77e2015-02-24 15:40:22 -07001330 }
Tobin Ehlis67449422015-03-02 10:16:40 -07001331 if (pCB == g_lastGlobalCB) {
1332 fprintf(pOutFile, "\"CB%pCMD%u\" [\nlabel=<<TABLE BGCOLOR=\"#00FF00\" BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\"> <TR><TD>CMD#</TD><TD>%u</TD></TR><TR><TD>CMD Type</TD><TD>%s</TD></TR></TABLE>>\n];\n", (void*)pCB->cmdBuffer, instNum, instNum, cmdTypeToString(pCmd->type));
1333 }
1334 else {
1335 fprintf(pOutFile, "\"CB%pCMD%u\" [\nlabel=<<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\"> <TR><TD>CMD#</TD><TD>%u</TD></TR><TR><TD>CMD Type</TD><TD>%s</TD></TR></TABLE>>\n];\n", (void*)pCB->cmdBuffer, instNum, instNum, cmdTypeToString(pCmd->type));
1336 }
1337 ++instNum;
1338 pCmd = pCmd->pNext;
Tobin Ehlis249c77e2015-02-24 15:40:22 -07001339 }
Tobin Ehlis67449422015-03-02 10:16:40 -07001340 fprintf(pOutFile, "}\n");
Tobin Ehlis249c77e2015-02-24 15:40:22 -07001341 }
1342 }
1343 fprintf(pOutFile, "}\n");
1344 fprintf(pOutFile, "}\n"); // close main graph "g"
1345 fclose(pOutFile);
1346}
Tobin Ehlisae708b82015-02-27 08:48:43 -07001347// Dump a GraphViz dot file showing the pipeline for last bound global state
1348static void dumpGlobalDotFile(char *outFileName)
1349{
1350 PIPELINE_NODE *pPipeTrav = g_lastBoundPipeline;
1351 if (pPipeTrav) {
1352 FILE* pOutFile;
1353 pOutFile = fopen(outFileName, "w");
1354 fprintf(pOutFile, "digraph g {\ngraph [\nrankdir = \"TB\"\n];\nnode [\nfontsize = \"16\"\nshape = \"plaintext\"\n];\nedge [\n];\n");
1355 fprintf(pOutFile, "subgraph cluster_dynamicState\n{\nlabel=\"Dynamic State\"\n");
1356 char* pGVstr = NULL;
1357 for (uint32_t i = 0; i < XGL_NUM_STATE_BIND_POINT; i++) {
1358 if (g_lastBoundDynamicState[i] && g_lastBoundDynamicState[i]->pCreateInfo) {
1359 pGVstr = dynamic_gv_display(g_lastBoundDynamicState[i]->pCreateInfo, string_XGL_STATE_BIND_POINT(i));
1360 fprintf(pOutFile, "%s", pGVstr);
1361 free(pGVstr);
1362 }
1363 }
1364 fprintf(pOutFile, "}\n"); // close dynamicState subgraph
1365 fprintf(pOutFile, "subgraph cluster_PipelineStateObject\n{\nlabel=\"Pipeline State Object\"\n");
1366 pGVstr = xgl_gv_print_xgl_graphics_pipeline_create_info(pPipeTrav->pCreateTree, "PSO HEAD");
1367 fprintf(pOutFile, "%s", pGVstr);
1368 free(pGVstr);
1369 fprintf(pOutFile, "}\n");
1370 dsCoreDumpDot(g_lastBoundDescriptorSet, pOutFile);
1371 fprintf(pOutFile, "}\n"); // close main graph "g"
1372 fclose(pOutFile);
1373 }
1374}
1375// Dump a GraphViz dot file showing the pipeline for a given CB
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07001376static void dumpDotFile(const XGL_CMD_BUFFER cb, char *outFileName)
Tobin Ehlis83562882014-11-27 15:43:39 -07001377{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07001378 GLOBAL_CB_NODE* pCB = getCBNode(cb);
1379 if (pCB) {
1380 PIPELINE_NODE *pPipeTrav = getPipeline(pCB->lastBoundPipeline);
1381 if (pPipeTrav) {
1382 FILE* pOutFile;
1383 pOutFile = fopen(outFileName, "w");
1384 fprintf(pOutFile, "digraph g {\ngraph [\nrankdir = \"TB\"\n];\nnode [\nfontsize = \"16\"\nshape = \"plaintext\"\n];\nedge [\n];\n");
1385 fprintf(pOutFile, "subgraph cluster_dynamicState\n{\nlabel=\"Dynamic State\"\n");
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -07001386 char* pGVstr = NULL;
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07001387 for (uint32_t i = 0; i < XGL_NUM_STATE_BIND_POINT; i++) {
Tobin Ehlis481ec712015-02-19 09:55:18 -07001388 if (pCB->lastBoundDynamicState[i] && pCB->lastBoundDynamicState[i]->pCreateInfo) {
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -07001389 pGVstr = dynamic_gv_display(pCB->lastBoundDynamicState[i]->pCreateInfo, string_XGL_STATE_BIND_POINT(i));
1390 fprintf(pOutFile, "%s", pGVstr);
1391 free(pGVstr);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07001392 }
Tobin Ehlis83562882014-11-27 15:43:39 -07001393 }
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07001394 fprintf(pOutFile, "}\n"); // close dynamicState subgraph
1395 fprintf(pOutFile, "subgraph cluster_PipelineStateObject\n{\nlabel=\"Pipeline State Object\"\n");
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -07001396 pGVstr = xgl_gv_print_xgl_graphics_pipeline_create_info(pPipeTrav->pCreateTree, "PSO HEAD");
1397 fprintf(pOutFile, "%s", pGVstr);
1398 free(pGVstr);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07001399 fprintf(pOutFile, "}\n");
1400 dsDumpDot(cb, pOutFile);
1401 fprintf(pOutFile, "}\n"); // close main graph "g"
1402 fclose(pOutFile);
Tobin Ehlis83562882014-11-27 15:43:39 -07001403 }
Tobin Ehlis83562882014-11-27 15:43:39 -07001404 }
1405}
Tobin Ehlisdb186c02015-03-16 11:49:58 -06001406// Verify VB Buffer binding
1407static void validateVBBinding(const XGL_CMD_BUFFER cb)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001408{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07001409 GLOBAL_CB_NODE* pCB = getCBNode(cb);
1410 if (pCB && pCB->lastBoundPipeline) {
1411 // First verify that we have a Node for bound pipeline
1412 PIPELINE_NODE *pPipeTrav = getPipeline(pCB->lastBoundPipeline);
1413 char str[1024];
1414 if (!pPipeTrav) {
1415 sprintf(str, "Can't find last bound Pipeline %p!", (void*)pCB->lastBoundPipeline);
1416 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NO_PIPELINE_BOUND, "DS", str);
1417 }
1418 else {
1419 // Verify Vtx binding
1420 if (MAX_BINDING != pCB->lastVtxBinding) {
1421 if (pCB->lastVtxBinding >= pPipeTrav->vtxBindingCount) {
Tobin Ehlis03d7a092015-02-17 16:27:03 -07001422 if (0 == pPipeTrav->vtxBindingCount) {
1423 sprintf(str, "Vtx Buffer Index %u was bound, but no vtx buffers are attached to PSO.", pCB->lastVtxBinding);
1424 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, "DS", str);
1425 }
1426 else {
1427 sprintf(str, "Vtx binding Index of %u exceeds PSO pVertexBindingDescriptions max array index of %u.", pCB->lastVtxBinding, (pPipeTrav->vtxBindingCount - 1));
1428 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, "DS", str);
1429 }
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07001430 }
1431 else {
1432 char *tmpStr = xgl_print_xgl_vertex_input_binding_description(&pPipeTrav->pVertexBindingDescriptions[pCB->lastVtxBinding], "{DS}INFO : ");
1433 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", tmpStr);
1434 free(tmpStr);
1435 }
Tobin Ehlisdb20d602014-11-25 10:24:15 -07001436 }
1437 }
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001438 }
1439}
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001440// Print details of DS config to stdout
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07001441static void printDSConfig(const XGL_CMD_BUFFER cb)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001442{
Tobin Ehlis246ba4d2014-11-18 16:38:08 -07001443 char tmp_str[1024];
1444 char ds_config_str[1024*256] = {0}; // TODO : Currently making this buffer HUGE w/o overrun protection. Need to be smarter, start smaller, and grow as needed.
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07001445 GLOBAL_CB_NODE* pCB = getCBNode(cb);
1446 if (pCB) {
1447 SET_NODE* pSet = getSetNode(pCB->lastBoundDescriptorSet);
1448 REGION_NODE* pRegion = getRegionNode(pSet->region);
Tobin Ehlisa3a693e2015-02-10 15:35:23 -07001449 // Print out region details
1450 sprintf(tmp_str, "Details for region %p.", (void*)pRegion->region);
1451 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -07001452 char* pRegionStr = xgl_print_xgl_descriptor_region_create_info(&pRegion->createInfo, " ");
1453 sprintf(ds_config_str, "%s", pRegionStr);
Tobin Ehlisa3a693e2015-02-10 15:35:23 -07001454 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", ds_config_str);
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -07001455 free(pRegionStr);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07001456 // Print out set details
1457 char prefix[10];
1458 uint32_t index = 0;
1459 sprintf(tmp_str, "Details for descriptor set %p.", (void*)pSet->set);
1460 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
1461 LAYOUT_NODE* pLayout = pSet->pLayouts;
1462 while (pLayout) {
1463 // Print layout details
1464 sprintf(tmp_str, "Layout #%u, (object %p) for DS %p.", index+1, (void*)pLayout->layout, (void*)pSet->set);
Tobin Ehlisa3a693e2015-02-10 15:35:23 -07001465 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07001466 sprintf(prefix, " [L%u] ", index);
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -07001467 char* pDSLstr = xgl_print_xgl_descriptor_set_layout_create_info(&pLayout->pCreateInfoList[0], prefix);
1468 sprintf(ds_config_str, "%s", pDSLstr);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07001469 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", ds_config_str);
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -07001470 free(pDSLstr);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07001471 pLayout = pLayout->pPriorSetLayout;
1472 index++;
1473 }
1474 GENERIC_HEADER* pUpdate = pSet->pUpdateStructs;
1475 if (pUpdate) {
Tobin Ehlisa3a693e2015-02-10 15:35:23 -07001476 sprintf(tmp_str, "Update Chain [UC] for descriptor set %p:", (void*)pSet->set);
1477 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
1478 sprintf(prefix, " [UC] ");
1479 sprintf(ds_config_str, "%s", dynamic_display(pUpdate, prefix));
1480 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", ds_config_str);
1481 // TODO : If there is a "view" associated with this update, print CI for that view
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001482 }
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07001483 else {
1484 sprintf(tmp_str, "No Update Chain for descriptor set %p (xglUpdateDescriptors has not been called)", (void*)pSet->set);
1485 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
1486 }
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001487 }
1488}
1489
Tobin Ehlis93837a02015-02-13 13:30:07 -07001490static void printCB(const XGL_CMD_BUFFER cb)
1491{
1492 GLOBAL_CB_NODE* pCB = getCBNode(cb);
1493 if (pCB) {
1494 char str[1024];
1495 CMD_NODE* pCmd = pCB->pCmds;
1496 sprintf(str, "Cmds in CB %p", (void*)cb);
1497 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", str);
1498 while (pCmd) {
1499 sprintf(str, " CMD#%lu: %s", pCmd->cmdNumber, cmdTypeToString(pCmd->type));
1500 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, cb, 0, DRAWSTATE_NONE, "DS", str);
1501 pCmd = pCmd->pNext;
1502 }
1503 }
1504 else {
1505 // Nothing to print
1506 }
1507}
1508
Jeremy Hayes250e2742015-01-29 13:03:36 -07001509
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07001510static void synchAndPrintDSConfig(const XGL_CMD_BUFFER cb)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001511{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07001512 printDSConfig(cb);
1513 printPipeline(cb);
1514 printDynamicState(cb);
Tobin Ehlis65c46602015-02-19 15:26:49 -07001515 static int autoDumpOnce = 0;
Tobin Ehlis83562882014-11-27 15:43:39 -07001516 if (autoDumpOnce) {
1517 autoDumpOnce = 0;
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07001518 dumpDotFile(cb, "pipeline_dump.dot");
Tobin Ehlis249c77e2015-02-24 15:40:22 -07001519 cbDumpDotFile("cb_dump.dot");
Ian Elliott2d4ab1e2015-01-13 17:52:38 -07001520#if defined(_WIN32)
1521// FIXME: NEED WINDOWS EQUIVALENT
1522#else // WIN32
Jeremy Hayes943dc2f2015-02-12 16:15:58 -07001523 // Convert dot to svg if dot available
Tobin Ehlisf27eba72014-12-16 17:34:50 -07001524 if(access( "/usr/bin/dot", X_OK) != -1) {
Jeremy Hayes943dc2f2015-02-12 16:15:58 -07001525 system("/usr/bin/dot pipeline_dump.dot -Tsvg -o pipeline_dump.svg");
Tobin Ehlisf27eba72014-12-16 17:34:50 -07001526 }
Ian Elliott2d4ab1e2015-01-13 17:52:38 -07001527#endif // WIN32
Tobin Ehlis83562882014-11-27 15:43:39 -07001528 }
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001529}
1530
Tobin Ehlisb0497852015-02-11 14:24:02 -07001531static void initDrawState(void)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001532{
Jon Ashburn892d9182014-12-22 13:38:27 -07001533 const char *strOpt;
Tobin Ehlisee702232015-01-08 14:26:53 -07001534 // initialize DrawState options
Ian Elliotte7826712015-03-06 13:50:05 -07001535 getLayerOptionEnum("DrawStateReportLevel", (uint32_t *) &g_reportingLevel);
1536 g_actionIsDefault = getLayerOptionEnum("DrawStateDebugAction", (uint32_t *) &g_debugAction);
Tobin Ehlisee702232015-01-08 14:26:53 -07001537
Jon Ashburn892d9182014-12-22 13:38:27 -07001538 if (g_debugAction & XGL_DBG_LAYER_ACTION_LOG_MSG)
1539 {
1540 strOpt = getLayerOption("DrawStateLogFilename");
1541 if (strOpt)
1542 {
1543 g_logFile = fopen(strOpt, "w");
Jon Ashburn892d9182014-12-22 13:38:27 -07001544 }
1545 if (g_logFile == NULL)
1546 g_logFile = stdout;
1547 }
Jon Ashburn892d9182014-12-22 13:38:27 -07001548 // initialize Layer dispatch table
1549 // TODO handle multiple GPUs
Mark Lobodzinski391bb6d2015-01-09 15:12:03 -06001550 xglGetProcAddrType fpNextGPA;
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001551 fpNextGPA = pCurObj->pGPA;
1552 assert(fpNextGPA);
1553
Chia-I Wuaa4121f2015-01-04 23:11:43 +08001554 layer_initialize_dispatch_table(&nextTable, fpNextGPA, (XGL_PHYSICAL_GPU) pCurObj->nextObject);
1555
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001556 xglGetProcAddrType fpGetProcAddr = fpNextGPA((XGL_PHYSICAL_GPU) pCurObj->nextObject, (char *) "xglGetProcAddr");
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001557 nextTable.GetProcAddr = fpGetProcAddr;
Ian Elliott2d4ab1e2015-01-13 17:52:38 -07001558
1559 if (!globalLockInitialized)
1560 {
1561 // TODO/TBD: Need to delete this mutex sometime. How??? One
1562 // suggestion is to call this during xglCreateInstance(), and then we
1563 // can clean it up during xglDestroyInstance(). However, that requires
1564 // that the layer have per-instance locks. We need to come back and
1565 // address this soon.
1566 loader_platform_thread_create_mutex(&globalLock);
1567 globalLockInitialized = 1;
1568 }
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001569}
1570
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001571XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDevice(XGL_PHYSICAL_GPU gpu, const XGL_DEVICE_CREATE_INFO* pCreateInfo, XGL_DEVICE* pDevice)
1572{
1573 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001574 pCurObj = gpuw;
Ian Elliott2d4ab1e2015-01-13 17:52:38 -07001575 loader_platform_thread_once(&g_initOnce, initDrawState);
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001576 XGL_RESULT result = nextTable.CreateDevice((XGL_PHYSICAL_GPU)gpuw->nextObject, pCreateInfo, pDevice);
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001577 return result;
1578}
1579
1580XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDestroyDevice(XGL_DEVICE device)
1581{
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -07001582 // Free all the memory
1583 loader_platform_thread_lock_mutex(&globalLock);
1584 freePipelines();
1585 freeSamplers();
1586 freeImages();
1587 freeBuffers();
1588 freeCmdBuffers();
1589 freeDynamicState();
1590 freeRegions();
1591 freeLayouts();
1592 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001593 XGL_RESULT result = nextTable.DestroyDevice(device);
1594 return result;
1595}
1596
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001597XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglEnumerateLayers(XGL_PHYSICAL_GPU gpu, size_t maxLayerCount, size_t maxStringSize, size_t* pOutLayerCount, char* const* pOutLayers, void* pReserved)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001598{
Jon Ashburnf7a08742014-11-25 11:08:42 -07001599 if (gpu != NULL)
1600 {
1601 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
1602 pCurObj = gpuw;
Ian Elliott2d4ab1e2015-01-13 17:52:38 -07001603 loader_platform_thread_once(&g_initOnce, initDrawState);
Mark Lobodzinski391bb6d2015-01-09 15:12:03 -06001604 XGL_RESULT result = nextTable.EnumerateLayers((XGL_PHYSICAL_GPU)gpuw->nextObject, maxLayerCount, maxStringSize, pOutLayerCount, pOutLayers, pReserved);
Jon Ashburnf7a08742014-11-25 11:08:42 -07001605 return result;
1606 } else
1607 {
1608 if (pOutLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL)
1609 return XGL_ERROR_INVALID_POINTER;
1610 // This layer compatible with all GPUs
1611 *pOutLayerCount = 1;
Chia-I Wu1da4b9f2014-12-16 10:47:33 +08001612 strncpy((char *) pOutLayers[0], "DrawState", maxStringSize);
Jon Ashburnf7a08742014-11-25 11:08:42 -07001613 return XGL_SUCCESS;
1614 }
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001615}
1616
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001617XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglQueueSubmit(XGL_QUEUE queue, uint32_t cmdBufferCount, const XGL_CMD_BUFFER* pCmdBuffers, uint32_t memRefCount, const XGL_MEMORY_REF* pMemRefs, XGL_FENCE fence)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001618{
Tobin Ehlis93837a02015-02-13 13:30:07 -07001619 for (uint32_t i=0; i < cmdBufferCount; i++) {
1620 // Validate that cmd buffers have been updated
1621 }
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001622 XGL_RESULT result = nextTable.QueueSubmit(queue, cmdBufferCount, pCmdBuffers, memRefCount, pMemRefs, fence);
1623 return result;
1624}
1625
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001626XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDestroyObject(XGL_OBJECT object)
1627{
Tobin Ehlisa3a693e2015-02-10 15:35:23 -07001628 // TODO : When wrapped objects (such as dynamic state) are destroyed, need to clean up memory
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001629 XGL_RESULT result = nextTable.DestroyObject(object);
1630 return result;
1631}
1632
Tobin Ehlis7265e832015-01-19 08:42:29 -07001633XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateBufferView(XGL_DEVICE device, const XGL_BUFFER_VIEW_CREATE_INFO* pCreateInfo, XGL_BUFFER_VIEW* pView)
1634{
1635 XGL_RESULT result = nextTable.CreateBufferView(device, pCreateInfo, pView);
Tobin Ehlis2a15a5f2015-02-24 09:16:47 -07001636 if (XGL_SUCCESS == result) {
1637 loader_platform_thread_lock_mutex(&globalLock);
1638 BUFFER_NODE *pNewNode = (BUFFER_NODE*)malloc(sizeof(BUFFER_NODE));
1639#if ALLOC_DEBUG
1640 printf("Alloc21 #%lu pNewNode addr(%p)\n", ++g_alloc_count, (void*)pNewNode);
1641#endif
1642 pNewNode->buffer = *pView;
1643 memcpy(&pNewNode->createInfo, pCreateInfo, sizeof(XGL_BUFFER_VIEW_CREATE_INFO));
1644 pNewNode->pNext = g_pBufferHead;
1645 g_pBufferHead = pNewNode;
1646 loader_platform_thread_unlock_mutex(&globalLock);
1647 }
Tobin Ehlis7265e832015-01-19 08:42:29 -07001648 return result;
1649}
1650
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001651XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateImageView(XGL_DEVICE device, const XGL_IMAGE_VIEW_CREATE_INFO* pCreateInfo, XGL_IMAGE_VIEW* pView)
1652{
1653 XGL_RESULT result = nextTable.CreateImageView(device, pCreateInfo, pView);
Tobin Ehlis04178d72015-01-22 10:45:21 -07001654 if (XGL_SUCCESS == result) {
Tobin Ehlisb0497852015-02-11 14:24:02 -07001655 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis04178d72015-01-22 10:45:21 -07001656 IMAGE_NODE *pNewNode = (IMAGE_NODE*)malloc(sizeof(IMAGE_NODE));
Tobin Ehlis03d7a092015-02-17 16:27:03 -07001657#if ALLOC_DEBUG
1658 printf("Alloc22 #%lu pNewNode addr(%p)\n", ++g_alloc_count, (void*)pNewNode);
1659#endif
Tobin Ehlis04178d72015-01-22 10:45:21 -07001660 pNewNode->image = *pView;
1661 memcpy(&pNewNode->createInfo, pCreateInfo, sizeof(XGL_IMAGE_VIEW_CREATE_INFO));
1662 pNewNode->pNext = g_pImageHead;
1663 g_pImageHead = pNewNode;
Tobin Ehlisb0497852015-02-11 14:24:02 -07001664 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis04178d72015-01-22 10:45:21 -07001665 }
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001666 return result;
1667}
1668
Courtney Goeltzenleuchter0d40f152015-03-25 15:37:49 -06001669static void track_pipeline(const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo, XGL_PIPELINE* pPipeline)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001670{
Ian Elliott2d4ab1e2015-01-13 17:52:38 -07001671 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis04178d72015-01-22 10:45:21 -07001672 PIPELINE_NODE *pTrav = g_pPipelineHead;
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001673 if (pTrav) {
1674 while (pTrav->pNext)
1675 pTrav = pTrav->pNext;
1676 pTrav->pNext = (PIPELINE_NODE*)malloc(sizeof(PIPELINE_NODE));
Tobin Ehlis03d7a092015-02-17 16:27:03 -07001677#if ALLOC_DEBUG
1678 printf("Alloc23 #%lu pTrav->pNext addr(%p)\n", ++g_alloc_count, (void*)pTrav->pNext);
1679#endif
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001680 pTrav = pTrav->pNext;
1681 }
1682 else {
1683 pTrav = (PIPELINE_NODE*)malloc(sizeof(PIPELINE_NODE));
Tobin Ehlis03d7a092015-02-17 16:27:03 -07001684#if ALLOC_DEBUG
1685 printf("Alloc24 #%lu pTrav addr(%p)\n", ++g_alloc_count, (void*)pTrav);
1686#endif
Tobin Ehlis04178d72015-01-22 10:45:21 -07001687 g_pPipelineHead = pTrav;
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001688 }
1689 memset((void*)pTrav, 0, sizeof(PIPELINE_NODE));
1690 pTrav->pipeline = *pPipeline;
1691 initPipeline(pTrav, pCreateInfo);
Ian Elliott2d4ab1e2015-01-13 17:52:38 -07001692 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchter0d40f152015-03-25 15:37:49 -06001693}
1694
1695XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateGraphicsPipeline(XGL_DEVICE device, const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo, XGL_PIPELINE* pPipeline)
1696{
1697 XGL_RESULT result = nextTable.CreateGraphicsPipeline(device, pCreateInfo, pPipeline);
1698 // Create LL HEAD for this Pipeline
1699 char str[1024];
1700 sprintf(str, "Created Gfx Pipeline %p", (void*)*pPipeline);
1701 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pPipeline, 0, DRAWSTATE_NONE, "DS", str);
1702
1703 track_pipeline(pCreateInfo, pPipeline);
1704
1705 return result;
1706}
1707
1708XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateGraphicsPipelineDerivative(
1709 XGL_DEVICE device,
1710 const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo,
1711 XGL_PIPELINE basePipeline,
1712 XGL_PIPELINE* pPipeline)
1713{
1714 XGL_RESULT result = nextTable.CreateGraphicsPipelineDerivative(device, pCreateInfo, basePipeline, pPipeline);
1715 // Create LL HEAD for this Pipeline
1716 char str[1024];
1717 sprintf(str, "Created Gfx Pipeline %p (derived from pipeline %p)", (void*)*pPipeline, basePipeline);
1718 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pPipeline, 0, DRAWSTATE_NONE, "DS", str);
1719
1720 track_pipeline(pCreateInfo, pPipeline);
1721
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001722 return result;
1723}
1724
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001725XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateSampler(XGL_DEVICE device, const XGL_SAMPLER_CREATE_INFO* pCreateInfo, XGL_SAMPLER* pSampler)
1726{
1727 XGL_RESULT result = nextTable.CreateSampler(device, pCreateInfo, pSampler);
Tobin Ehlis04178d72015-01-22 10:45:21 -07001728 if (XGL_SUCCESS == result) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -07001729 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis04178d72015-01-22 10:45:21 -07001730 SAMPLER_NODE *pNewNode = (SAMPLER_NODE*)malloc(sizeof(SAMPLER_NODE));
Tobin Ehlis03d7a092015-02-17 16:27:03 -07001731#if ALLOC_DEBUG
Tobin Ehlis8c2ed212015-02-20 09:30:06 -07001732 printf("Alloc25 #%lu pNewNode addr(%p)\n", ++g_alloc_count, (void*)pNewNode);
Tobin Ehlis03d7a092015-02-17 16:27:03 -07001733#endif
Tobin Ehlis04178d72015-01-22 10:45:21 -07001734 pNewNode->sampler = *pSampler;
1735 memcpy(&pNewNode->createInfo, pCreateInfo, sizeof(XGL_SAMPLER_CREATE_INFO));
1736 pNewNode->pNext = g_pSamplerHead;
1737 g_pSamplerHead = pNewNode;
Ian Elliott2d4ab1e2015-01-13 17:52:38 -07001738 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis04178d72015-01-22 10:45:21 -07001739 }
Tobin Ehlis97657ce2014-10-24 12:01:45 -06001740 return result;
1741}
1742
Tobin Ehlis7265e832015-01-19 08:42:29 -07001743XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDescriptorSetLayout(XGL_DEVICE device, XGL_FLAGS stageFlags, const uint32_t* pSetBindPoints, XGL_DESCRIPTOR_SET_LAYOUT priorSetLayout, const XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO* pSetLayoutInfoList, XGL_DESCRIPTOR_SET_LAYOUT* pSetLayout)
1744{
1745 XGL_RESULT result = nextTable.CreateDescriptorSetLayout(device, stageFlags, pSetBindPoints, priorSetLayout, pSetLayoutInfoList, pSetLayout);
1746 if (XGL_SUCCESS == result) {
Tobin Ehlis7265e832015-01-19 08:42:29 -07001747 LAYOUT_NODE* pNewNode = (LAYOUT_NODE*)malloc(sizeof(LAYOUT_NODE));
Tobin Ehlis03d7a092015-02-17 16:27:03 -07001748#if ALLOC_DEBUG
Tobin Ehlis8c2ed212015-02-20 09:30:06 -07001749 printf("Alloc26 #%lu pNewNode addr(%p)\n", ++g_alloc_count, (void*)pNewNode);
Tobin Ehlis03d7a092015-02-17 16:27:03 -07001750#endif
Tobin Ehlis7265e832015-01-19 08:42:29 -07001751 if (NULL == pNewNode) {
1752 char str[1024];
1753 sprintf(str, "Out of memory while attempting to allocate LAYOUT_NODE in xglCreateDescriptorSetLayout()");
1754 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, *pSetLayout, 0, DRAWSTATE_OUT_OF_MEMORY, "DS", str);
1755 }
1756 memset(pNewNode, 0, sizeof(LAYOUT_NODE));
Tobin Ehlis04178d72015-01-22 10:45:21 -07001757 // TODO : API Currently missing a count here that we should multiply by struct size
1758 pNewNode->pCreateInfoList = (XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO*)malloc(sizeof(XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO));
Tobin Ehlis03d7a092015-02-17 16:27:03 -07001759#if ALLOC_DEBUG
Tobin Ehlis8c2ed212015-02-20 09:30:06 -07001760 printf("Alloc27 #%lu pNewNode->pCreateInfoList addr(%p)\n", ++g_alloc_count, (void*)pNewNode->pCreateInfoList);
Tobin Ehlis03d7a092015-02-17 16:27:03 -07001761#endif
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07001762 memset((void*)pNewNode->pCreateInfoList, 0, sizeof(XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO));
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -07001763 void* pCITrav = NULL;
1764 uint32_t totalCount = 0;
1765 if (pSetLayoutInfoList) {
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07001766 memcpy((void*)pNewNode->pCreateInfoList, pSetLayoutInfoList, sizeof(XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO));
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -07001767 pCITrav = (void*)pSetLayoutInfoList->pNext;
1768 totalCount = pSetLayoutInfoList->count;
1769 }
1770 void** ppNext = (void**)&pNewNode->pCreateInfoList->pNext;
1771 while (pCITrav) {
1772 totalCount += ((XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO*)pCITrav)->count;
1773 *ppNext = (void*)malloc(sizeof(XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO));
Tobin Ehlis03d7a092015-02-17 16:27:03 -07001774#if ALLOC_DEBUG
Tobin Ehlis8c2ed212015-02-20 09:30:06 -07001775 printf("Alloc28 #%lu *ppNext addr(%p)\n", ++g_alloc_count, (void*)*ppNext);
Tobin Ehlis03d7a092015-02-17 16:27:03 -07001776#endif
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -07001777 memcpy((void*)*ppNext, pCITrav, sizeof(XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO));
1778 pCITrav = (void*)((XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO*)pCITrav)->pNext;
Tobin Ehlis481ec712015-02-19 09:55:18 -07001779 ppNext = (void**)&((XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO*)*ppNext)->pNext;
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -07001780 }
1781 if (totalCount > 0) {
1782 pNewNode->pTypes = (XGL_DESCRIPTOR_TYPE*)malloc(totalCount*sizeof(XGL_DESCRIPTOR_TYPE));
Tobin Ehlis03d7a092015-02-17 16:27:03 -07001783#if ALLOC_DEBUG
Tobin Ehlis8c2ed212015-02-20 09:30:06 -07001784 printf("Alloc29 #%lu pNewNode->pTypes addr(%p)\n", ++g_alloc_count, (void*)pNewNode->pTypes);
Tobin Ehlis03d7a092015-02-17 16:27:03 -07001785#endif
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -07001786 XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO* pLCI = (XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO*)pSetLayoutInfoList;
Tobin Ehlis481ec712015-02-19 09:55:18 -07001787 uint32_t offset = 0;
1788 uint32_t i = 0;
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -07001789 while (pLCI) {
Tobin Ehlis481ec712015-02-19 09:55:18 -07001790 for (i = 0; i < pLCI->count; i++) {
1791 pNewNode->pTypes[offset + i] = pLCI->descriptorType;
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -07001792 }
Tobin Ehlis481ec712015-02-19 09:55:18 -07001793 offset += i;
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -07001794 pLCI = (XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO*)pLCI->pNext;
1795 }
1796 }
Tobin Ehlis04178d72015-01-22 10:45:21 -07001797 pNewNode->layout = *pSetLayout;
Tobin Ehlisa3a693e2015-02-10 15:35:23 -07001798 pNewNode->stageFlags = stageFlags;
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -07001799 uint32_t i = (XGL_SHADER_STAGE_FLAGS_ALL == stageFlags) ? 0 : XGL_SHADER_STAGE_COMPUTE;
Tobin Ehlisc5ad8012015-02-16 14:29:30 -07001800 for (uint32_t stage = XGL_SHADER_STAGE_FLAGS_COMPUTE_BIT; stage > 0; stage >>= 1) {
1801 assert(i < XGL_NUM_SHADER_STAGE);
1802 if (stage & stageFlags)
1803 pNewNode->shaderStageBindPoints[i] = pSetBindPoints[i];
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -07001804 i = (i == 0) ? 0 : (i-1);
Tobin Ehlisc5ad8012015-02-16 14:29:30 -07001805 }
Tobin Ehlisa3a693e2015-02-10 15:35:23 -07001806 pNewNode->startIndex = 0;
Tobin Ehlis04178d72015-01-22 10:45:21 -07001807 LAYOUT_NODE* pPriorNode = getLayoutNode(priorSetLayout);
1808 // Point to prior node or NULL if no prior node
Tobin Ehlisa3a693e2015-02-10 15:35:23 -07001809 if (NULL != priorSetLayout && pPriorNode == NULL) {
1810 char str[1024];
1811 sprintf(str, "Invalid priorSetLayout of %p passed to xglCreateDescriptorSetLayout()", (void*)priorSetLayout);
1812 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, priorSetLayout, 0, DRAWSTATE_INVALID_LAYOUT, "DS", str);
1813 }
1814 else if (pPriorNode != NULL) { // We have a node for a valid prior layout
1815 // Get count for prior layout
1816 pNewNode->startIndex = pPriorNode->endIndex + 1;
1817 }
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -07001818 pNewNode->endIndex = pNewNode->startIndex + totalCount - 1;
Tobin Ehlisa3a693e2015-02-10 15:35:23 -07001819 assert(pNewNode->endIndex >= pNewNode->startIndex);
Tobin Ehlis04178d72015-01-22 10:45:21 -07001820 pNewNode->pPriorSetLayout = pPriorNode;
1821 // Put new node at Head of global Layer list
Tobin Ehlis8c2ed212015-02-20 09:30:06 -07001822 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlisa3a693e2015-02-10 15:35:23 -07001823 pNewNode->pNext = g_pLayoutHead;
Tobin Ehlis04178d72015-01-22 10:45:21 -07001824 g_pLayoutHead = pNewNode;
Tobin Ehlis8c2ed212015-02-20 09:30:06 -07001825 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001826 }
1827 return result;
1828}
1829
1830XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglBeginDescriptorRegionUpdate(XGL_DEVICE device, XGL_DESCRIPTOR_UPDATE_MODE updateMode)
1831{
1832 XGL_RESULT result = nextTable.BeginDescriptorRegionUpdate(device, updateMode);
1833 if (XGL_SUCCESS == result) {
Tobin Ehlis8c2ed212015-02-20 09:30:06 -07001834 loader_platform_thread_lock_mutex(&globalLock);
1835 REGION_NODE* pRegionNode = g_pRegionHead;
1836 if (!pRegionNode) {
Tobin Ehlis7265e832015-01-19 08:42:29 -07001837 char str[1024];
Tobin Ehlis8c2ed212015-02-20 09:30:06 -07001838 sprintf(str, "Unable to find region node for global region head %p", (void*)g_pRegionHead);
1839 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, g_pRegionHead, 0, DRAWSTATE_INTERNAL_ERROR, "DS", str);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001840 }
1841 else {
Tobin Ehlis8c2ed212015-02-20 09:30:06 -07001842 pRegionNode->updateActive = 1;
Tobin Ehlis7265e832015-01-19 08:42:29 -07001843 }
Tobin Ehlis8c2ed212015-02-20 09:30:06 -07001844 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001845 }
1846 return result;
1847}
1848
1849XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglEndDescriptorRegionUpdate(XGL_DEVICE device, XGL_CMD_BUFFER cmd)
1850{
1851 XGL_RESULT result = nextTable.EndDescriptorRegionUpdate(device, cmd);
1852 if (XGL_SUCCESS == result) {
Tobin Ehlis8c2ed212015-02-20 09:30:06 -07001853 loader_platform_thread_lock_mutex(&globalLock);
1854 REGION_NODE* pRegionNode = g_pRegionHead;
1855 if (!pRegionNode) {
Tobin Ehlis7265e832015-01-19 08:42:29 -07001856 char str[1024];
Tobin Ehlis8c2ed212015-02-20 09:30:06 -07001857 sprintf(str, "Unable to find region node for global region head %p", (void*)g_pRegionHead);
1858 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, g_pRegionHead, 0, DRAWSTATE_INTERNAL_ERROR, "DS", str);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001859 }
1860 else {
Tobin Ehlis8c2ed212015-02-20 09:30:06 -07001861 if (!pRegionNode->updateActive) {
Tobin Ehlis7265e832015-01-19 08:42:29 -07001862 char str[1024];
Tobin Ehlis8c2ed212015-02-20 09:30:06 -07001863 sprintf(str, "You must call xglBeginDescriptorRegionUpdate() before this call to xglEndDescriptorRegionUpdate()!");
1864 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, g_pRegionHead, 0, DRAWSTATE_DS_END_WITHOUT_BEGIN, "DS", str);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001865 }
1866 else {
Tobin Ehlis8c2ed212015-02-20 09:30:06 -07001867 pRegionNode->updateActive = 0;
Tobin Ehlis7265e832015-01-19 08:42:29 -07001868 }
1869 }
Tobin Ehlis8c2ed212015-02-20 09:30:06 -07001870 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001871 }
1872 return result;
1873}
1874
1875XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDescriptorRegion(XGL_DEVICE device, XGL_DESCRIPTOR_REGION_USAGE regionUsage, uint32_t maxSets, const XGL_DESCRIPTOR_REGION_CREATE_INFO* pCreateInfo, XGL_DESCRIPTOR_REGION* pDescriptorRegion)
1876{
1877 XGL_RESULT result = nextTable.CreateDescriptorRegion(device, regionUsage, maxSets, pCreateInfo, pDescriptorRegion);
1878 if (XGL_SUCCESS == result) {
1879 // Insert this region into Global Region LL at head
1880 char str[1024];
1881 sprintf(str, "Created Descriptor Region %p", (void*)*pDescriptorRegion);
1882 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pDescriptorRegion, 0, DRAWSTATE_NONE, "DS", str);
Tobin Ehlisb0497852015-02-11 14:24:02 -07001883 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlisa3a693e2015-02-10 15:35:23 -07001884 REGION_NODE* pNewNode = (REGION_NODE*)malloc(sizeof(REGION_NODE));
Tobin Ehlis03d7a092015-02-17 16:27:03 -07001885#if ALLOC_DEBUG
Tobin Ehlis8c2ed212015-02-20 09:30:06 -07001886 printf("Alloc30 #%lu pNewNode addr(%p)\n", ++g_alloc_count, (void*)pNewNode);
Tobin Ehlis03d7a092015-02-17 16:27:03 -07001887#endif
Tobin Ehlis7265e832015-01-19 08:42:29 -07001888 if (NULL == pNewNode) {
1889 char str[1024];
Tobin Ehlisa3a693e2015-02-10 15:35:23 -07001890 sprintf(str, "Out of memory while attempting to allocate REGION_NODE in xglCreateDescriptorRegion()");
Tobin Ehlis7265e832015-01-19 08:42:29 -07001891 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, *pDescriptorRegion, 0, DRAWSTATE_OUT_OF_MEMORY, "DS", str);
1892 }
1893 else {
1894 memset(pNewNode, 0, sizeof(REGION_NODE));
1895 pNewNode->pNext = g_pRegionHead;
1896 g_pRegionHead = pNewNode;
Tobin Ehlisa3a693e2015-02-10 15:35:23 -07001897 XGL_DESCRIPTOR_REGION_CREATE_INFO* pCI = (XGL_DESCRIPTOR_REGION_CREATE_INFO*)&pNewNode->createInfo;
1898 memcpy((void*)pCI, pCreateInfo, sizeof(XGL_DESCRIPTOR_REGION_CREATE_INFO));
1899 size_t typeCountSize = pNewNode->createInfo.count * sizeof(XGL_DESCRIPTOR_TYPE_COUNT);
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -07001900 if (typeCountSize) {
1901 XGL_DESCRIPTOR_TYPE_COUNT** ppTypeCount = (XGL_DESCRIPTOR_TYPE_COUNT**)&pNewNode->createInfo.pTypeCount;
1902 *ppTypeCount = (XGL_DESCRIPTOR_TYPE_COUNT*)malloc(typeCountSize);
Tobin Ehlis03d7a092015-02-17 16:27:03 -07001903#if ALLOC_DEBUG
Tobin Ehlis8c2ed212015-02-20 09:30:06 -07001904 printf("Alloc31 #%lu *ppTypeCount addr(%p)\n", ++g_alloc_count, (void*)*ppTypeCount);
Tobin Ehlis03d7a092015-02-17 16:27:03 -07001905#endif
Tobin Ehlis3d0d99b2015-02-17 09:54:13 -07001906 memcpy((void*)*ppTypeCount, pCreateInfo->pTypeCount, typeCountSize);
1907 }
Tobin Ehlis7265e832015-01-19 08:42:29 -07001908 pNewNode->regionUsage = regionUsage;
1909 pNewNode->updateActive = 0;
1910 pNewNode->maxSets = maxSets;
1911 pNewNode->region = *pDescriptorRegion;
1912 }
Tobin Ehlisb0497852015-02-11 14:24:02 -07001913 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001914 }
1915 else {
1916 // Need to do anything if region create fails?
1917 }
1918 return result;
1919}
1920
1921XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglClearDescriptorRegion(XGL_DESCRIPTOR_REGION descriptorRegion)
1922{
Tobin Ehlis7265e832015-01-19 08:42:29 -07001923 XGL_RESULT result = nextTable.ClearDescriptorRegion(descriptorRegion);
Tobin Ehlis04178d72015-01-22 10:45:21 -07001924 if (XGL_SUCCESS == result) {
1925 clearDescriptorRegion(descriptorRegion);
1926 }
Tobin Ehlis7265e832015-01-19 08:42:29 -07001927 return result;
1928}
1929
1930XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglAllocDescriptorSets(XGL_DESCRIPTOR_REGION descriptorRegion, XGL_DESCRIPTOR_SET_USAGE setUsage, uint32_t count, const XGL_DESCRIPTOR_SET_LAYOUT* pSetLayouts, XGL_DESCRIPTOR_SET* pDescriptorSets, uint32_t* pCount)
1931{
1932 XGL_RESULT result = nextTable.AllocDescriptorSets(descriptorRegion, setUsage, count, pSetLayouts, pDescriptorSets, pCount);
Tobin Ehlis04178d72015-01-22 10:45:21 -07001933 if ((XGL_SUCCESS == result) || (*pCount > 0)) {
1934 REGION_NODE *pRegionNode = getRegionNode(descriptorRegion);
1935 if (!pRegionNode) {
Tobin Ehlis7265e832015-01-19 08:42:29 -07001936 char str[1024];
Tobin Ehlis04178d72015-01-22 10:45:21 -07001937 sprintf(str, "Unable to find region node for region %p specified in xglAllocDescriptorSets() call", (void*)descriptorRegion);
Tobin Ehlisa3a693e2015-02-10 15:35:23 -07001938 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, descriptorRegion, 0, DRAWSTATE_INVALID_REGION, "DS", str);
Tobin Ehlis04178d72015-01-22 10:45:21 -07001939 }
1940 else {
Tobin Ehlisa3a693e2015-02-10 15:35:23 -07001941 for (uint32_t i = 0; i < *pCount; i++) {
Tobin Ehlis7265e832015-01-19 08:42:29 -07001942 char str[1024];
Tobin Ehlis04178d72015-01-22 10:45:21 -07001943 sprintf(str, "Created Descriptor Set %p", (void*)pDescriptorSets[i]);
Tobin Ehlisa3a693e2015-02-10 15:35:23 -07001944 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pDescriptorSets[i], 0, DRAWSTATE_NONE, "DS", str);
Tobin Ehlis04178d72015-01-22 10:45:21 -07001945 // Create new set node and add to head of region nodes
Tobin Ehlisa3a693e2015-02-10 15:35:23 -07001946 SET_NODE* pNewNode = (SET_NODE*)malloc(sizeof(SET_NODE));
Tobin Ehlis03d7a092015-02-17 16:27:03 -07001947#if ALLOC_DEBUG
Tobin Ehlis481ec712015-02-19 09:55:18 -07001948 printf("Alloc32 #%lu pNewNode addr(%p)\n", ++g_alloc_count, (void*)pNewNode);
Tobin Ehlis03d7a092015-02-17 16:27:03 -07001949#endif
Tobin Ehlis04178d72015-01-22 10:45:21 -07001950 if (NULL == pNewNode) {
1951 char str[1024];
1952 sprintf(str, "Out of memory while attempting to allocate SET_NODE in xglAllocDescriptorSets()");
Tobin Ehlisa3a693e2015-02-10 15:35:23 -07001953 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, pDescriptorSets[i], 0, DRAWSTATE_OUT_OF_MEMORY, "DS", str);
Tobin Ehlis04178d72015-01-22 10:45:21 -07001954 }
1955 else {
1956 memset(pNewNode, 0, sizeof(SET_NODE));
1957 // Insert set at head of Set LL for this region
1958 pNewNode->pNext = pRegionNode->pSets;
1959 pRegionNode->pSets = pNewNode;
1960 LAYOUT_NODE* pLayout = getLayoutNode(pSetLayouts[i]);
1961 if (NULL == pLayout) {
1962 char str[1024];
1963 sprintf(str, "Unable to find set layout node for layout %p specified in xglAllocDescriptorSets() call", (void*)pSetLayouts[i]);
1964 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, pSetLayouts[i], 0, DRAWSTATE_INVALID_LAYOUT, "DS", str);
1965 }
1966 pNewNode->pLayouts = pLayout;
1967 pNewNode->region = descriptorRegion;
1968 pNewNode->set = pDescriptorSets[i];
1969 pNewNode->setUsage = setUsage;
Tobin Ehlis6926cd92015-02-11 13:13:18 -07001970 pNewNode->descriptorCount = pLayout->endIndex + 1;
Tobin Ehlis481ec712015-02-19 09:55:18 -07001971 size_t descriptorArraySize = sizeof(GENERIC_HEADER*)*pNewNode->descriptorCount;
1972 pNewNode->ppDescriptors = (GENERIC_HEADER**)malloc(descriptorArraySize);
1973#if ALLOC_DEBUG
1974 printf("Alloc35 #%lu pSet->ppDescriptors addr(%p)\n", ++g_alloc_count, (void*)pNewNode->ppDescriptors);
1975#endif
1976 memset(pNewNode->ppDescriptors, 0, descriptorArraySize);
Tobin Ehlis04178d72015-01-22 10:45:21 -07001977 }
Tobin Ehlis7265e832015-01-19 08:42:29 -07001978 }
Tobin Ehlis7265e832015-01-19 08:42:29 -07001979 }
1980 }
1981 return result;
1982}
1983
1984XGL_LAYER_EXPORT void XGLAPI xglClearDescriptorSets(XGL_DESCRIPTOR_REGION descriptorRegion, uint32_t count, const XGL_DESCRIPTOR_SET* pDescriptorSets)
1985{
Tobin Ehlis04178d72015-01-22 10:45:21 -07001986 for (uint32_t i = 0; i < count; i++) {
Tobin Ehlisa3a693e2015-02-10 15:35:23 -07001987 clearDescriptorSet(pDescriptorSets[i]);
Tobin Ehlis04178d72015-01-22 10:45:21 -07001988 }
Tobin Ehlis7265e832015-01-19 08:42:29 -07001989 nextTable.ClearDescriptorSets(descriptorRegion, count, pDescriptorSets);
1990}
1991
1992XGL_LAYER_EXPORT void XGLAPI xglUpdateDescriptors(XGL_DESCRIPTOR_SET descriptorSet, const void* pUpdateChain)
1993{
Tobin Ehlisa3a693e2015-02-10 15:35:23 -07001994 if (!dsUpdateActive(descriptorSet)) {
Tobin Ehlis7265e832015-01-19 08:42:29 -07001995 char str[1024];
1996 sprintf(str, "You must call xglBeginDescriptorRegionUpdate() before this call to xglUpdateDescriptors()!");
Tobin Ehlis8c2ed212015-02-20 09:30:06 -07001997 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, g_pRegionHead->region, 0, DRAWSTATE_UPDATE_WITHOUT_BEGIN, "DS", str);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001998 }
Tobin Ehlis04178d72015-01-22 10:45:21 -07001999 else {
2000 // pUpdateChain is a Linked-list of XGL_UPDATE_* structures defining the mappings for the descriptors
2001 dsUpdate(descriptorSet, (GENERIC_HEADER*)pUpdateChain);
2002 }
2003
Tobin Ehlis7265e832015-01-19 08:42:29 -07002004 nextTable.UpdateDescriptors(descriptorSet, pUpdateChain);
2005}
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002006
Tobin Ehlis7265e832015-01-19 08:42:29 -07002007XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDynamicViewportState(XGL_DEVICE device, const XGL_DYNAMIC_VP_STATE_CREATE_INFO* pCreateInfo, XGL_DYNAMIC_VP_STATE_OBJECT* pState)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002008{
Tobin Ehlis7265e832015-01-19 08:42:29 -07002009 XGL_RESULT result = nextTable.CreateDynamicViewportState(device, pCreateInfo, pState);
Tobin Ehlis04178d72015-01-22 10:45:21 -07002010 insertDynamicState(*pState, (GENERIC_HEADER*)pCreateInfo, XGL_STATE_BIND_VIEWPORT);
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002011 return result;
2012}
2013
Tobin Ehlis7265e832015-01-19 08:42:29 -07002014XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDynamicRasterState(XGL_DEVICE device, const XGL_DYNAMIC_RS_STATE_CREATE_INFO* pCreateInfo, XGL_DYNAMIC_RS_STATE_OBJECT* pState)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002015{
Tobin Ehlis7265e832015-01-19 08:42:29 -07002016 XGL_RESULT result = nextTable.CreateDynamicRasterState(device, pCreateInfo, pState);
Tobin Ehlis04178d72015-01-22 10:45:21 -07002017 insertDynamicState(*pState, (GENERIC_HEADER*)pCreateInfo, XGL_STATE_BIND_RASTER);
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002018 return result;
2019}
2020
Tobin Ehlis7265e832015-01-19 08:42:29 -07002021XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDynamicColorBlendState(XGL_DEVICE device, const XGL_DYNAMIC_CB_STATE_CREATE_INFO* pCreateInfo, XGL_DYNAMIC_CB_STATE_OBJECT* pState)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002022{
Tobin Ehlis7265e832015-01-19 08:42:29 -07002023 XGL_RESULT result = nextTable.CreateDynamicColorBlendState(device, pCreateInfo, pState);
Tobin Ehlis04178d72015-01-22 10:45:21 -07002024 insertDynamicState(*pState, (GENERIC_HEADER*)pCreateInfo, XGL_STATE_BIND_COLOR_BLEND);
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002025 return result;
2026}
2027
Tobin Ehlis7265e832015-01-19 08:42:29 -07002028XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDynamicDepthStencilState(XGL_DEVICE device, const XGL_DYNAMIC_DS_STATE_CREATE_INFO* pCreateInfo, XGL_DYNAMIC_DS_STATE_OBJECT* pState)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002029{
Tobin Ehlis7265e832015-01-19 08:42:29 -07002030 XGL_RESULT result = nextTable.CreateDynamicDepthStencilState(device, pCreateInfo, pState);
Tobin Ehlis04178d72015-01-22 10:45:21 -07002031 insertDynamicState(*pState, (GENERIC_HEADER*)pCreateInfo, XGL_STATE_BIND_DEPTH_STENCIL);
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002032 return result;
2033}
2034
2035XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateCommandBuffer(XGL_DEVICE device, const XGL_CMD_BUFFER_CREATE_INFO* pCreateInfo, XGL_CMD_BUFFER* pCmdBuffer)
2036{
2037 XGL_RESULT result = nextTable.CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002038 if (XGL_SUCCESS == result) {
Tobin Ehlis8c2ed212015-02-20 09:30:06 -07002039 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002040 GLOBAL_CB_NODE* pCB = (GLOBAL_CB_NODE*)malloc(sizeof(GLOBAL_CB_NODE));
Tobin Ehlis03d7a092015-02-17 16:27:03 -07002041#if ALLOC_DEBUG
Tobin Ehlis8c2ed212015-02-20 09:30:06 -07002042 printf("Alloc33 #%lu pCB addr(%p)\n", ++g_alloc_count, (void*)pCB);
Tobin Ehlis03d7a092015-02-17 16:27:03 -07002043#endif
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002044 memset(pCB, 0, sizeof(GLOBAL_CB_NODE));
2045 pCB->pNextGlobalCBNode = g_pCmdBufferHead;
2046 g_pCmdBufferHead = pCB;
2047 pCB->cmdBuffer = *pCmdBuffer;
2048 pCB->flags = pCreateInfo->flags;
Courtney Goeltzenleuchter18248e62015-03-05 18:09:39 -07002049 pCB->queueNodeIndex = pCreateInfo->queueNodeIndex;
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002050 pCB->lastVtxBinding = MAX_BINDING;
Tobin Ehlis8c2ed212015-02-20 09:30:06 -07002051 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis67449422015-03-02 10:16:40 -07002052 updateCBTracking(*pCmdBuffer);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002053 }
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002054 return result;
2055}
2056
Jon Ashburn86522372014-12-31 17:11:49 -07002057XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglBeginCommandBuffer(XGL_CMD_BUFFER cmdBuffer, const XGL_CMD_BUFFER_BEGIN_INFO* pBeginInfo)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002058{
Jon Ashburn86522372014-12-31 17:11:49 -07002059 XGL_RESULT result = nextTable.BeginCommandBuffer(cmdBuffer, pBeginInfo);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002060 if (XGL_SUCCESS == result) {
2061 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
Tobin Ehlis481ec712015-02-19 09:55:18 -07002062 if (pCB) {
2063 if (CB_NEW != pCB->state)
2064 resetCB(cmdBuffer);
2065 pCB->state = CB_UPDATE_ACTIVE;
2066 }
2067 else {
2068 char str[1024];
2069 sprintf(str, "In xglBeginCommandBuffer() and unable to find CmdBuffer Node for CB %p!", (void*)cmdBuffer);
2070 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2071 }
Tobin Ehlis67449422015-03-02 10:16:40 -07002072 updateCBTracking(cmdBuffer);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002073 }
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002074 return result;
2075}
2076
2077XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglEndCommandBuffer(XGL_CMD_BUFFER cmdBuffer)
2078{
2079 XGL_RESULT result = nextTable.EndCommandBuffer(cmdBuffer);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002080 if (XGL_SUCCESS == result) {
2081 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
Tobin Ehlis481ec712015-02-19 09:55:18 -07002082 if (pCB) {
2083 pCB->state = CB_UPDATE_COMPLETE;
2084 printCB(cmdBuffer);
2085 }
2086 else {
2087 char str[1024];
2088 sprintf(str, "In xglEndCommandBuffer() and unable to find CmdBuffer Node for CB %p!", (void*)cmdBuffer);
2089 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2090 }
Tobin Ehlis67449422015-03-02 10:16:40 -07002091 updateCBTracking(cmdBuffer);
2092 //cbDumpDotFile("cb_dump.dot");
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002093 }
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002094 return result;
2095}
2096
2097XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglResetCommandBuffer(XGL_CMD_BUFFER cmdBuffer)
2098{
2099 XGL_RESULT result = nextTable.ResetCommandBuffer(cmdBuffer);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002100 if (XGL_SUCCESS == result) {
Tobin Ehlis93837a02015-02-13 13:30:07 -07002101 resetCB(cmdBuffer);
Tobin Ehlis67449422015-03-02 10:16:40 -07002102 updateCBTracking(cmdBuffer);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002103 }
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002104 return result;
2105}
2106
Mark Lobodzinski17caf572015-01-29 08:55:56 -06002107XGL_LAYER_EXPORT void XGLAPI xglCmdBindPipeline(XGL_CMD_BUFFER cmdBuffer, XGL_PIPELINE_BIND_POINT pipelineBindPoint, XGL_PIPELINE pipeline)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002108{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002109 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2110 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002111 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002112 addCmd(pCB, CMD_BINDPIPELINE);
Tobin Ehlis5c7e7b82015-03-03 13:58:42 -07002113 PIPELINE_NODE* pPN = getPipeline(pipeline);
2114 if (pPN) {
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002115 pCB->lastBoundPipeline = pipeline;
Tobin Ehlis5c7e7b82015-03-03 13:58:42 -07002116 loader_platform_thread_lock_mutex(&globalLock);
2117 g_lastBoundPipeline = pPN;
2118 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002119 }
2120 else {
2121 char str[1024];
2122 sprintf(str, "Attempt to bind Pipeline %p that doesn't exist!", (void*)pipeline);
2123 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, pipeline, 0, DRAWSTATE_INVALID_PIPELINE, "DS", str);
2124 }
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002125 }
2126 else {
Tobin Ehlis246ba4d2014-11-18 16:38:08 -07002127 char str[1024];
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002128 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2129 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002130 }
2131 nextTable.CmdBindPipeline(cmdBuffer, pipelineBindPoint, pipeline);
2132}
2133
Tobin Ehlis7265e832015-01-19 08:42:29 -07002134XGL_LAYER_EXPORT void XGLAPI xglCmdBindDynamicStateObject(XGL_CMD_BUFFER cmdBuffer, XGL_STATE_BIND_POINT stateBindPoint, XGL_DYNAMIC_STATE_OBJECT state)
2135{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002136 setLastBoundDynamicState(cmdBuffer, state, stateBindPoint);
Tobin Ehlis7265e832015-01-19 08:42:29 -07002137 nextTable.CmdBindDynamicStateObject(cmdBuffer, stateBindPoint, state);
2138}
2139
2140XGL_LAYER_EXPORT void XGLAPI xglCmdBindDescriptorSet(XGL_CMD_BUFFER cmdBuffer, XGL_PIPELINE_BIND_POINT pipelineBindPoint, XGL_DESCRIPTOR_SET descriptorSet, const uint32_t* pUserData)
2141{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002142 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2143 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002144 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002145 addCmd(pCB, CMD_BINDDESCRIPTORSET);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002146 if (getSetNode(descriptorSet)) {
2147 if (dsUpdateActive(descriptorSet)) {
Tobin Ehlis65c46602015-02-19 15:26:49 -07002148 // TODO : This check here needs to be made at QueueSubmit time
2149/*
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002150 char str[1024];
2151 sprintf(str, "You must call xglEndDescriptorRegionUpdate(%p) before this call to xglCmdBindDescriptorSet()!", (void*)descriptorSet);
2152 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, descriptorSet, 0, DRAWSTATE_BINDING_DS_NO_END_UPDATE, "DS", str);
Tobin Ehlis65c46602015-02-19 15:26:49 -07002153*/
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002154 }
2155 loader_platform_thread_lock_mutex(&globalLock);
2156 pCB->lastBoundDescriptorSet = descriptorSet;
Tobin Ehlisae708b82015-02-27 08:48:43 -07002157 g_lastBoundDescriptorSet = descriptorSet;
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002158 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlisa3a693e2015-02-10 15:35:23 -07002159 char str[1024];
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002160 sprintf(str, "DS %p bound on pipeline %s", (void*)descriptorSet, string_XGL_PIPELINE_BIND_POINT(pipelineBindPoint));
2161 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, descriptorSet, 0, DRAWSTATE_NONE, "DS", str);
Tobin Ehlisb8013a22015-02-26 12:57:08 -07002162 synchAndPrintDSConfig(cmdBuffer);
Tobin Ehlisa3a693e2015-02-10 15:35:23 -07002163 }
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002164 else {
2165 char str[1024];
2166 sprintf(str, "Attempt to bind DS %p that doesn't exist!", (void*)descriptorSet);
2167 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, descriptorSet, 0, DRAWSTATE_INVALID_SET, "DS", str);
2168 }
Tobin Ehlisa3a693e2015-02-10 15:35:23 -07002169 }
2170 else {
2171 char str[1024];
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002172 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2173 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlisa3a693e2015-02-10 15:35:23 -07002174 }
Tobin Ehlis7265e832015-01-19 08:42:29 -07002175 nextTable.CmdBindDescriptorSet(cmdBuffer, pipelineBindPoint, descriptorSet, pUserData);
2176}
2177
2178XGL_LAYER_EXPORT void XGLAPI xglCmdBindIndexBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER buffer, XGL_GPU_SIZE offset, XGL_INDEX_TYPE indexType)
2179{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002180 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2181 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002182 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002183 addCmd(pCB, CMD_BINDINDEXBUFFER);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002184 // TODO : Track idxBuffer binding
2185 }
2186 else {
2187 char str[1024];
2188 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2189 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2190 }
Tobin Ehlis7265e832015-01-19 08:42:29 -07002191 nextTable.CmdBindIndexBuffer(cmdBuffer, buffer, offset, indexType);
2192}
2193
2194XGL_LAYER_EXPORT void XGLAPI xglCmdBindVertexBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER buffer, XGL_GPU_SIZE offset, uint32_t binding)
Chia-I Wu7a42e122014-11-08 10:48:20 +08002195{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002196 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2197 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002198 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002199 addCmd(pCB, CMD_BINDVERTEXBUFFER);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002200 pCB->lastVtxBinding = binding;
Tobin Ehlisdb186c02015-03-16 11:49:58 -06002201 validateVBBinding(cmdBuffer);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002202 }
2203 else {
2204 char str[1024];
2205 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2206 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2207 }
Tobin Ehlis7265e832015-01-19 08:42:29 -07002208 nextTable.CmdBindVertexBuffer(cmdBuffer, buffer, offset, binding);
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002209}
2210
Mark Lobodzinski17caf572015-01-29 08:55:56 -06002211XGL_LAYER_EXPORT void XGLAPI xglCmdDraw(XGL_CMD_BUFFER cmdBuffer, uint32_t firstVertex, uint32_t vertexCount, uint32_t firstInstance, uint32_t instanceCount)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002212{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002213 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2214 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002215 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002216 addCmd(pCB, CMD_DRAW);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002217 pCB->drawCount[DRAW]++;
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002218 char str[1024];
2219 sprintf(str, "xglCmdDraw() call #%lu, reporting DS state:", g_drawCount[DRAW]++);
2220 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_NONE, "DS", str);
2221 synchAndPrintDSConfig(cmdBuffer);
2222 }
2223 else {
2224 char str[1024];
2225 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2226 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2227 }
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002228 nextTable.CmdDraw(cmdBuffer, firstVertex, vertexCount, firstInstance, instanceCount);
2229}
2230
Mark Lobodzinski17caf572015-01-29 08:55:56 -06002231XGL_LAYER_EXPORT void XGLAPI xglCmdDrawIndexed(XGL_CMD_BUFFER cmdBuffer, uint32_t firstIndex, uint32_t indexCount, int32_t vertexOffset, uint32_t firstInstance, uint32_t instanceCount)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002232{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002233 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2234 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002235 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002236 addCmd(pCB, CMD_DRAWINDEXED);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002237 pCB->drawCount[DRAW_INDEXED]++;
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002238 char str[1024];
2239 sprintf(str, "xglCmdDrawIndexed() call #%lu, reporting DS state:", g_drawCount[DRAW_INDEXED]++);
2240 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_NONE, "DS", str);
2241 synchAndPrintDSConfig(cmdBuffer);
2242 }
2243 else {
2244 char str[1024];
2245 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2246 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2247 }
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002248 nextTable.CmdDrawIndexed(cmdBuffer, firstIndex, indexCount, vertexOffset, firstInstance, instanceCount);
2249}
2250
Tobin Ehlis7265e832015-01-19 08:42:29 -07002251XGL_LAYER_EXPORT void XGLAPI xglCmdDrawIndirect(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER buffer, XGL_GPU_SIZE offset, uint32_t count, uint32_t stride)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002252{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002253 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2254 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002255 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002256 addCmd(pCB, CMD_DRAWINDIRECT);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002257 pCB->drawCount[DRAW_INDIRECT]++;
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002258 char str[1024];
2259 sprintf(str, "xglCmdDrawIndirect() call #%lu, reporting DS state:", g_drawCount[DRAW_INDIRECT]++);
2260 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_NONE, "DS", str);
2261 synchAndPrintDSConfig(cmdBuffer);
2262 }
2263 else {
2264 char str[1024];
2265 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2266 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2267 }
Tobin Ehlis7265e832015-01-19 08:42:29 -07002268 nextTable.CmdDrawIndirect(cmdBuffer, buffer, offset, count, stride);
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002269}
2270
Tobin Ehlis7265e832015-01-19 08:42:29 -07002271XGL_LAYER_EXPORT void XGLAPI xglCmdDrawIndexedIndirect(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER buffer, XGL_GPU_SIZE offset, uint32_t count, uint32_t stride)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002272{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002273 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2274 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002275 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002276 addCmd(pCB, CMD_DRAWINDEXEDINDIRECT);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002277 pCB->drawCount[DRAW_INDEXED_INDIRECT]++;
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002278 char str[1024];
2279 sprintf(str, "xglCmdDrawIndexedIndirect() call #%lu, reporting DS state:", g_drawCount[DRAW_INDEXED_INDIRECT]++);
2280 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_NONE, "DS", str);
2281 synchAndPrintDSConfig(cmdBuffer);
2282 }
2283 else {
2284 char str[1024];
2285 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2286 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2287 }
Tobin Ehlis7265e832015-01-19 08:42:29 -07002288 nextTable.CmdDrawIndexedIndirect(cmdBuffer, buffer, offset, count, stride);
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002289}
2290
Mark Lobodzinski17caf572015-01-29 08:55:56 -06002291XGL_LAYER_EXPORT void XGLAPI xglCmdDispatch(XGL_CMD_BUFFER cmdBuffer, uint32_t x, uint32_t y, uint32_t z)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002292{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002293 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2294 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002295 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002296 addCmd(pCB, CMD_DISPATCH);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002297 }
2298 else {
2299 char str[1024];
2300 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2301 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2302 }
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002303 nextTable.CmdDispatch(cmdBuffer, x, y, z);
2304}
2305
Tobin Ehlis7265e832015-01-19 08:42:29 -07002306XGL_LAYER_EXPORT void XGLAPI xglCmdDispatchIndirect(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER buffer, XGL_GPU_SIZE offset)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002307{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002308 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2309 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002310 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002311 addCmd(pCB, CMD_DISPATCHINDIRECT);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002312 }
2313 else {
2314 char str[1024];
2315 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2316 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2317 }
Tobin Ehlis7265e832015-01-19 08:42:29 -07002318 nextTable.CmdDispatchIndirect(cmdBuffer, buffer, offset);
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002319}
2320
Tobin Ehlis7265e832015-01-19 08:42:29 -07002321XGL_LAYER_EXPORT void XGLAPI xglCmdCopyBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER srcBuffer, XGL_BUFFER destBuffer, uint32_t regionCount, const XGL_BUFFER_COPY* pRegions)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002322{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002323 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2324 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002325 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002326 addCmd(pCB, CMD_COPYBUFFER);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002327 }
2328 else {
2329 char str[1024];
2330 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2331 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2332 }
Tobin Ehlis7265e832015-01-19 08:42:29 -07002333 nextTable.CmdCopyBuffer(cmdBuffer, srcBuffer, destBuffer, regionCount, pRegions);
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002334}
2335
Courtney Goeltzenleuchterb3efe9b2015-03-25 11:25:10 -06002336XGL_LAYER_EXPORT void XGLAPI xglCmdCopyImage(XGL_CMD_BUFFER cmdBuffer,
2337 XGL_IMAGE srcImage,
2338 XGL_IMAGE_LAYOUT srcImageLayout,
2339 XGL_IMAGE destImage,
2340 XGL_IMAGE_LAYOUT destImageLayout,
2341 uint32_t regionCount, const XGL_IMAGE_COPY* pRegions)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002342{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002343 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2344 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002345 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002346 addCmd(pCB, CMD_COPYIMAGE);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002347 }
2348 else {
2349 char str[1024];
2350 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2351 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2352 }
Courtney Goeltzenleuchterb3efe9b2015-03-25 11:25:10 -06002353 nextTable.CmdCopyImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002354}
2355
Courtney Goeltzenleuchterb3efe9b2015-03-25 11:25:10 -06002356XGL_LAYER_EXPORT void XGLAPI xglCmdBlitImage(XGL_CMD_BUFFER cmdBuffer,
2357 XGL_IMAGE srcImage, XGL_IMAGE_LAYOUT srcImageLayout,
2358 XGL_IMAGE destImage, XGL_IMAGE_LAYOUT destImageLayout,
Courtney Goeltzenleuchter89299fa2015-03-08 17:02:18 -06002359 uint32_t regionCount, const XGL_IMAGE_BLIT* pRegions)
2360{
2361 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2362 if (pCB) {
2363 updateCBTracking(cmdBuffer);
2364 addCmd(pCB, CMD_COPYIMAGE);
2365 }
2366 else {
2367 char str[1024];
2368 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2369 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2370 }
Courtney Goeltzenleuchterb3efe9b2015-03-25 11:25:10 -06002371 nextTable.CmdBlitImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
Courtney Goeltzenleuchter89299fa2015-03-08 17:02:18 -06002372}
2373
Courtney Goeltzenleuchterb3efe9b2015-03-25 11:25:10 -06002374XGL_LAYER_EXPORT void XGLAPI xglCmdCopyBufferToImage(XGL_CMD_BUFFER cmdBuffer,
2375 XGL_BUFFER srcBuffer,
2376 XGL_IMAGE destImage, XGL_IMAGE_LAYOUT destImageLayout,
2377 uint32_t regionCount, const XGL_BUFFER_IMAGE_COPY* pRegions)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002378{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002379 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2380 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002381 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002382 addCmd(pCB, CMD_COPYBUFFERTOIMAGE);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002383 }
2384 else {
2385 char str[1024];
2386 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2387 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2388 }
Courtney Goeltzenleuchterb3efe9b2015-03-25 11:25:10 -06002389 nextTable.CmdCopyBufferToImage(cmdBuffer, srcBuffer, destImage, destImageLayout, regionCount, pRegions);
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002390}
2391
Courtney Goeltzenleuchterb3efe9b2015-03-25 11:25:10 -06002392XGL_LAYER_EXPORT void XGLAPI xglCmdCopyImageToBuffer(XGL_CMD_BUFFER cmdBuffer,
2393 XGL_IMAGE srcImage, XGL_IMAGE_LAYOUT srcImageLayout,
2394 XGL_BUFFER destBuffer,
2395 uint32_t regionCount, const XGL_BUFFER_IMAGE_COPY* pRegions)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002396{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002397 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2398 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002399 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002400 addCmd(pCB, CMD_COPYIMAGETOBUFFER);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002401 }
2402 else {
2403 char str[1024];
2404 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2405 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2406 }
Courtney Goeltzenleuchterb3efe9b2015-03-25 11:25:10 -06002407 nextTable.CmdCopyImageToBuffer(cmdBuffer, srcImage, srcImageLayout, destBuffer, regionCount, pRegions);
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002408}
2409
Mark Lobodzinski17caf572015-01-29 08:55:56 -06002410XGL_LAYER_EXPORT void XGLAPI xglCmdCloneImageData(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE srcImage, XGL_IMAGE_LAYOUT srcImageLayout, XGL_IMAGE destImage, XGL_IMAGE_LAYOUT destImageLayout)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002411{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002412 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2413 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002414 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002415 addCmd(pCB, CMD_CLONEIMAGEDATA);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002416 }
2417 else {
2418 char str[1024];
2419 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2420 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2421 }
Mike Stroyanfb80d5f2014-12-04 11:08:39 +00002422 nextTable.CmdCloneImageData(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout);
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002423}
2424
Tobin Ehlis7265e832015-01-19 08:42:29 -07002425XGL_LAYER_EXPORT void XGLAPI xglCmdUpdateBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER destBuffer, XGL_GPU_SIZE destOffset, XGL_GPU_SIZE dataSize, const uint32_t* pData)
2426{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002427 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2428 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002429 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002430 addCmd(pCB, CMD_UPDATEBUFFER);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002431 }
2432 else {
2433 char str[1024];
2434 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2435 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2436 }
Tobin Ehlis7265e832015-01-19 08:42:29 -07002437 nextTable.CmdUpdateBuffer(cmdBuffer, destBuffer, destOffset, dataSize, pData);
2438}
2439
2440XGL_LAYER_EXPORT void XGLAPI xglCmdFillBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER destBuffer, XGL_GPU_SIZE destOffset, XGL_GPU_SIZE fillSize, uint32_t data)
2441{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002442 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2443 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002444 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002445 addCmd(pCB, CMD_FILLBUFFER);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002446 }
2447 else {
2448 char str[1024];
2449 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2450 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2451 }
Tobin Ehlis7265e832015-01-19 08:42:29 -07002452 nextTable.CmdFillBuffer(cmdBuffer, destBuffer, destOffset, fillSize, data);
2453}
2454
Courtney Goeltzenleuchterb3efe9b2015-03-25 11:25:10 -06002455XGL_LAYER_EXPORT void XGLAPI xglCmdClearColorImage(XGL_CMD_BUFFER cmdBuffer,
2456 XGL_IMAGE image, XGL_IMAGE_LAYOUT imageLayout,
2457 XGL_CLEAR_COLOR color,
2458 uint32_t rangeCount, const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002459{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002460 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2461 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002462 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002463 addCmd(pCB, CMD_CLEARCOLORIMAGE);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002464 }
2465 else {
2466 char str[1024];
2467 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2468 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2469 }
Courtney Goeltzenleuchterb3efe9b2015-03-25 11:25:10 -06002470 nextTable.CmdClearColorImage(cmdBuffer, image, imageLayout, color, rangeCount, pRanges);
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002471}
2472
Courtney Goeltzenleuchterb3efe9b2015-03-25 11:25:10 -06002473XGL_LAYER_EXPORT void XGLAPI xglCmdClearDepthStencil(XGL_CMD_BUFFER cmdBuffer,
2474 XGL_IMAGE image, XGL_IMAGE_LAYOUT imageLayout,
2475 float depth, uint32_t stencil,
2476 uint32_t rangeCount, const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002477{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002478 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2479 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002480 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002481 addCmd(pCB, CMD_CLEARDEPTHSTENCIL);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002482 }
2483 else {
2484 char str[1024];
2485 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2486 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2487 }
Courtney Goeltzenleuchterb3efe9b2015-03-25 11:25:10 -06002488 nextTable.CmdClearDepthStencil(cmdBuffer, image, imageLayout, depth, stencil, rangeCount, pRanges);
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002489}
2490
Courtney Goeltzenleuchterb3efe9b2015-03-25 11:25:10 -06002491XGL_LAYER_EXPORT void XGLAPI xglCmdResolveImage(XGL_CMD_BUFFER cmdBuffer,
2492 XGL_IMAGE srcImage, XGL_IMAGE_LAYOUT srcImageLayout,
2493 XGL_IMAGE destImage, XGL_IMAGE_LAYOUT destImageLayout,
2494 uint32_t rectCount, const XGL_IMAGE_RESOLVE* pRects)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002495{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002496 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2497 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002498 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002499 addCmd(pCB, CMD_RESOLVEIMAGE);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002500 }
2501 else {
2502 char str[1024];
2503 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2504 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2505 }
Courtney Goeltzenleuchterb3efe9b2015-03-25 11:25:10 -06002506 nextTable.CmdResolveImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, rectCount, pRects);
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002507}
2508
Courtney Goeltzenleuchter1e8f3be2015-03-24 18:02:34 -06002509XGL_LAYER_EXPORT void XGLAPI xglCmdSetEvent(XGL_CMD_BUFFER cmdBuffer, XGL_EVENT event, XGL_PIPE_EVENT pipeEvent)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002510{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002511 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2512 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002513 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002514 addCmd(pCB, CMD_SETEVENT);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002515 }
2516 else {
2517 char str[1024];
2518 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2519 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2520 }
Mike Stroyanfb80d5f2014-12-04 11:08:39 +00002521 nextTable.CmdSetEvent(cmdBuffer, event, pipeEvent);
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002522}
2523
Courtney Goeltzenleuchter1e8f3be2015-03-24 18:02:34 -06002524XGL_LAYER_EXPORT void XGLAPI xglCmdResetEvent(XGL_CMD_BUFFER cmdBuffer, XGL_EVENT event, XGL_PIPE_EVENT pipeEvent)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002525{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002526 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2527 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002528 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002529 addCmd(pCB, CMD_RESETEVENT);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002530 }
2531 else {
2532 char str[1024];
2533 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2534 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2535 }
Courtney Goeltzenleuchter1e8f3be2015-03-24 18:02:34 -06002536 nextTable.CmdResetEvent(cmdBuffer, event, pipeEvent);
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002537}
2538
Mark Lobodzinski17caf572015-01-29 08:55:56 -06002539XGL_LAYER_EXPORT void XGLAPI xglCmdWaitEvents(XGL_CMD_BUFFER cmdBuffer, const XGL_EVENT_WAIT_INFO* pWaitInfo)
Mike Stroyanfb80d5f2014-12-04 11:08:39 +00002540{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002541 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2542 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002543 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002544 addCmd(pCB, CMD_WAITEVENTS);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002545 }
2546 else {
2547 char str[1024];
2548 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2549 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2550 }
Mike Stroyanfb80d5f2014-12-04 11:08:39 +00002551 nextTable.CmdWaitEvents(cmdBuffer, pWaitInfo);
2552}
2553
Tobin Ehlis7265e832015-01-19 08:42:29 -07002554XGL_LAYER_EXPORT void XGLAPI xglCmdPipelineBarrier(XGL_CMD_BUFFER cmdBuffer, const XGL_PIPELINE_BARRIER* pBarrier)
Mike Stroyanfb80d5f2014-12-04 11:08:39 +00002555{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002556 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2557 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002558 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002559 addCmd(pCB, CMD_PIPELINEBARRIER);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002560 }
2561 else {
2562 char str[1024];
2563 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2564 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2565 }
Mike Stroyanfb80d5f2014-12-04 11:08:39 +00002566 nextTable.CmdPipelineBarrier(cmdBuffer, pBarrier);
2567}
2568
Mark Lobodzinski17caf572015-01-29 08:55:56 -06002569XGL_LAYER_EXPORT void XGLAPI xglCmdBeginQuery(XGL_CMD_BUFFER cmdBuffer, XGL_QUERY_POOL queryPool, uint32_t slot, XGL_FLAGS flags)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002570{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002571 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2572 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002573 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002574 addCmd(pCB, CMD_BEGINQUERY);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002575 }
2576 else {
2577 char str[1024];
2578 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2579 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2580 }
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002581 nextTable.CmdBeginQuery(cmdBuffer, queryPool, slot, flags);
2582}
2583
Mark Lobodzinski17caf572015-01-29 08:55:56 -06002584XGL_LAYER_EXPORT void XGLAPI xglCmdEndQuery(XGL_CMD_BUFFER cmdBuffer, XGL_QUERY_POOL queryPool, uint32_t slot)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002585{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002586 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2587 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002588 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002589 addCmd(pCB, CMD_ENDQUERY);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002590 }
2591 else {
2592 char str[1024];
2593 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2594 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2595 }
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002596 nextTable.CmdEndQuery(cmdBuffer, queryPool, slot);
2597}
2598
Mark Lobodzinski17caf572015-01-29 08:55:56 -06002599XGL_LAYER_EXPORT void XGLAPI xglCmdResetQueryPool(XGL_CMD_BUFFER cmdBuffer, XGL_QUERY_POOL queryPool, uint32_t startQuery, uint32_t queryCount)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002600{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002601 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2602 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002603 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002604 addCmd(pCB, CMD_RESETQUERYPOOL);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002605 }
2606 else {
2607 char str[1024];
2608 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2609 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2610 }
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002611 nextTable.CmdResetQueryPool(cmdBuffer, queryPool, startQuery, queryCount);
2612}
2613
Tobin Ehlis7265e832015-01-19 08:42:29 -07002614XGL_LAYER_EXPORT void XGLAPI xglCmdWriteTimestamp(XGL_CMD_BUFFER cmdBuffer, XGL_TIMESTAMP_TYPE timestampType, XGL_BUFFER destBuffer, XGL_GPU_SIZE destOffset)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002615{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002616 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2617 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002618 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002619 addCmd(pCB, CMD_WRITETIMESTAMP);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002620 }
2621 else {
2622 char str[1024];
2623 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2624 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2625 }
Tobin Ehlis7265e832015-01-19 08:42:29 -07002626 nextTable.CmdWriteTimestamp(cmdBuffer, timestampType, destBuffer, destOffset);
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002627}
2628
Mark Lobodzinski17caf572015-01-29 08:55:56 -06002629XGL_LAYER_EXPORT void XGLAPI xglCmdInitAtomicCounters(XGL_CMD_BUFFER cmdBuffer, XGL_PIPELINE_BIND_POINT pipelineBindPoint, uint32_t startCounter, uint32_t counterCount, const uint32_t* pData)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002630{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002631 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2632 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002633 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002634 addCmd(pCB, CMD_INITATOMICCOUNTERS);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002635 }
2636 else {
2637 char str[1024];
2638 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2639 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2640 }
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002641 nextTable.CmdInitAtomicCounters(cmdBuffer, pipelineBindPoint, startCounter, counterCount, pData);
2642}
2643
Tobin Ehlis7265e832015-01-19 08:42:29 -07002644XGL_LAYER_EXPORT void XGLAPI xglCmdLoadAtomicCounters(XGL_CMD_BUFFER cmdBuffer, XGL_PIPELINE_BIND_POINT pipelineBindPoint, uint32_t startCounter, uint32_t counterCount, XGL_BUFFER srcBuffer, XGL_GPU_SIZE srcOffset)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002645{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002646 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2647 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002648 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002649 addCmd(pCB, CMD_LOADATOMICCOUNTERS);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002650 }
2651 else {
2652 char str[1024];
2653 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2654 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2655 }
Tobin Ehlis7265e832015-01-19 08:42:29 -07002656 nextTable.CmdLoadAtomicCounters(cmdBuffer, pipelineBindPoint, startCounter, counterCount, srcBuffer, srcOffset);
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002657}
2658
Tobin Ehlis7265e832015-01-19 08:42:29 -07002659XGL_LAYER_EXPORT void XGLAPI xglCmdSaveAtomicCounters(XGL_CMD_BUFFER cmdBuffer, XGL_PIPELINE_BIND_POINT pipelineBindPoint, uint32_t startCounter, uint32_t counterCount, XGL_BUFFER destBuffer, XGL_GPU_SIZE destOffset)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002660{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002661 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2662 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002663 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002664 addCmd(pCB, CMD_SAVEATOMICCOUNTERS);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002665 }
2666 else {
2667 char str[1024];
2668 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2669 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2670 }
Tobin Ehlis7265e832015-01-19 08:42:29 -07002671 nextTable.CmdSaveAtomicCounters(cmdBuffer, pipelineBindPoint, startCounter, counterCount, destBuffer, destOffset);
2672}
2673
Courtney Goeltzenleuchter69894b72015-04-03 15:25:24 -06002674XGL_LAYER_EXPORT void XGLAPI xglCmdBeginRenderPass(XGL_CMD_BUFFER cmdBuffer, const XGL_RENDER_PASS_BEGIN *pRenderPassBegin)
Tobin Ehlis7265e832015-01-19 08:42:29 -07002675{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002676 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2677 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002678 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002679 addCmd(pCB, CMD_BEGINRENDERPASS);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002680 }
2681 else {
2682 char str[1024];
2683 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2684 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2685 }
Courtney Goeltzenleuchter69894b72015-04-03 15:25:24 -06002686 nextTable.CmdBeginRenderPass(cmdBuffer, pRenderPassBegin);
Tobin Ehlis7265e832015-01-19 08:42:29 -07002687}
2688
2689XGL_LAYER_EXPORT void XGLAPI xglCmdEndRenderPass(XGL_CMD_BUFFER cmdBuffer, XGL_RENDER_PASS renderPass)
2690{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002691 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2692 if (pCB) {
Tobin Ehlis67449422015-03-02 10:16:40 -07002693 updateCBTracking(cmdBuffer);
Tobin Ehlis93837a02015-02-13 13:30:07 -07002694 addCmd(pCB, CMD_ENDRENDERPASS);
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002695 }
2696 else {
2697 char str[1024];
2698 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2699 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2700 }
Tobin Ehlis7265e832015-01-19 08:42:29 -07002701 nextTable.CmdEndRenderPass(cmdBuffer, renderPass);
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002702}
2703
Courtney Goeltzenleuchterc80a5572015-04-13 14:10:06 -06002704XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDbgRegisterMsgCallback(XGL_INSTANCE instance, XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback, void* pUserData)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002705{
Tobin Ehlis246ba4d2014-11-18 16:38:08 -07002706 // This layer intercepts callbacks
Tobin Ehlis03d7a092015-02-17 16:27:03 -07002707 XGL_LAYER_DBG_FUNCTION_NODE* pNewDbgFuncNode = (XGL_LAYER_DBG_FUNCTION_NODE*)malloc(sizeof(XGL_LAYER_DBG_FUNCTION_NODE));
2708#if ALLOC_DEBUG
2709 printf("Alloc34 #%lu pNewDbgFuncNode addr(%p)\n", ++g_alloc_count, (void*)pNewDbgFuncNode);
2710#endif
Tobin Ehlis246ba4d2014-11-18 16:38:08 -07002711 if (!pNewDbgFuncNode)
2712 return XGL_ERROR_OUT_OF_MEMORY;
2713 pNewDbgFuncNode->pfnMsgCallback = pfnMsgCallback;
2714 pNewDbgFuncNode->pUserData = pUserData;
Jon Ashburn892d9182014-12-22 13:38:27 -07002715 pNewDbgFuncNode->pNext = g_pDbgFunctionHead;
2716 g_pDbgFunctionHead = pNewDbgFuncNode;
Jon Ashburna8aa8372015-03-03 15:07:15 -07002717 // force callbacks if DebugAction hasn't been set already other than initial value
Courtney Goeltzenleuchter90d93202015-03-04 15:47:34 -07002718 if (g_actionIsDefault) {
2719 g_debugAction = XGL_DBG_LAYER_ACTION_CALLBACK;
2720 }
Courtney Goeltzenleuchterc80a5572015-04-13 14:10:06 -06002721 XGL_RESULT result = nextTable.DbgRegisterMsgCallback(instance, pfnMsgCallback, pUserData);
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002722 return result;
2723}
2724
Courtney Goeltzenleuchterc80a5572015-04-13 14:10:06 -06002725XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDbgUnregisterMsgCallback(XGL_INSTANCE instance, XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002726{
Jon Ashburn892d9182014-12-22 13:38:27 -07002727 XGL_LAYER_DBG_FUNCTION_NODE *pTrav = g_pDbgFunctionHead;
Tobin Ehlis246ba4d2014-11-18 16:38:08 -07002728 XGL_LAYER_DBG_FUNCTION_NODE *pPrev = pTrav;
2729 while (pTrav) {
2730 if (pTrav->pfnMsgCallback == pfnMsgCallback) {
2731 pPrev->pNext = pTrav->pNext;
Jon Ashburn892d9182014-12-22 13:38:27 -07002732 if (g_pDbgFunctionHead == pTrav)
2733 g_pDbgFunctionHead = pTrav->pNext;
Tobin Ehlis03d7a092015-02-17 16:27:03 -07002734#if ALLOC_DEBUG
2735 printf("Free34 #%lu pNewDbgFuncNode addr(%p)\n", ++g_alloc_count, (void*)pTrav);
2736#endif
Tobin Ehlis246ba4d2014-11-18 16:38:08 -07002737 free(pTrav);
2738 break;
2739 }
2740 pPrev = pTrav;
2741 pTrav = pTrav->pNext;
2742 }
Jon Ashburna8aa8372015-03-03 15:07:15 -07002743 if (g_pDbgFunctionHead == NULL)
2744 {
2745 if (g_actionIsDefault)
2746 g_debugAction = XGL_DBG_LAYER_ACTION_LOG_MSG;
2747 else
2748 g_debugAction &= ~XGL_DBG_LAYER_ACTION_CALLBACK;
2749 }
Courtney Goeltzenleuchterc80a5572015-04-13 14:10:06 -06002750 XGL_RESULT result = nextTable.DbgUnregisterMsgCallback(instance, pfnMsgCallback);
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002751 return result;
2752}
2753
Mark Lobodzinski17caf572015-01-29 08:55:56 -06002754XGL_LAYER_EXPORT void XGLAPI xglCmdDbgMarkerBegin(XGL_CMD_BUFFER cmdBuffer, const char* pMarker)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002755{
Tobin Ehlis67449422015-03-02 10:16:40 -07002756 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2757 if (pCB) {
2758 updateCBTracking(cmdBuffer);
2759 addCmd(pCB, CMD_DBGMARKERBEGIN);
2760 }
2761 else {
2762 char str[1024];
2763 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2764 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2765 }
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002766 nextTable.CmdDbgMarkerBegin(cmdBuffer, pMarker);
2767}
2768
Mark Lobodzinski17caf572015-01-29 08:55:56 -06002769XGL_LAYER_EXPORT void XGLAPI xglCmdDbgMarkerEnd(XGL_CMD_BUFFER cmdBuffer)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002770{
Tobin Ehlis67449422015-03-02 10:16:40 -07002771 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2772 if (pCB) {
2773 updateCBTracking(cmdBuffer);
2774 addCmd(pCB, CMD_DBGMARKEREND);
2775 }
2776 else {
2777 char str[1024];
2778 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
2779 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
2780 }
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002781 nextTable.CmdDbgMarkerEnd(cmdBuffer);
2782}
2783
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002784// TODO : Want to pass in a cmdBuffer here based on which state to display
Mark Lobodzinski17caf572015-01-29 08:55:56 -06002785void drawStateDumpDotFile(char* outFileName)
Tobin Ehlis83562882014-11-27 15:43:39 -07002786{
Tobin Ehlisd01f7d62015-02-13 10:26:14 -07002787 // TODO : Currently just setting cmdBuffer based on global var
Tobin Ehlisae708b82015-02-27 08:48:43 -07002788 //dumpDotFile(g_lastDrawStateCmdBuffer, outFileName);
2789 dumpGlobalDotFile(outFileName);
Tobin Ehlis83562882014-11-27 15:43:39 -07002790}
2791
Tobin Ehlis249c77e2015-02-24 15:40:22 -07002792void drawStateDumpCommandBufferDotFile(char* outFileName)
2793{
2794 cbDumpDotFile(outFileName);
2795}
2796
Mark Lobodzinski17caf572015-01-29 08:55:56 -06002797void drawStateDumpPngFile(char* outFileName)
Tobin Ehlisf27eba72014-12-16 17:34:50 -07002798{
Ian Elliott2d4ab1e2015-01-13 17:52:38 -07002799#if defined(_WIN32)
2800// FIXME: NEED WINDOWS EQUIVALENT
2801 char str[1024];
2802 sprintf(str, "Cannot execute dot program yet on Windows.");
2803 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_MISSING_DOT_PROGRAM, "DS", str);
2804#else // WIN32
Tobin Ehlisf27eba72014-12-16 17:34:50 -07002805 char dotExe[32] = "/usr/bin/dot";
2806 if( access(dotExe, X_OK) != -1) {
Tobin Ehlisea189f12015-02-23 09:06:28 -07002807 dumpDotFile(g_lastCmdBuffer[getTIDIndex()], "/tmp/tmp.dot");
Tobin Ehlisf27eba72014-12-16 17:34:50 -07002808 char dotCmd[1024];
2809 sprintf(dotCmd, "%s /tmp/tmp.dot -Tpng -o %s", dotExe, outFileName);
2810 system(dotCmd);
2811 remove("/tmp/tmp.dot");
2812 }
2813 else {
2814 char str[1024];
2815 sprintf(str, "Cannot execute dot program at (%s) to dump requested %s file.", dotExe, outFileName);
2816 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_MISSING_DOT_PROGRAM, "DS", str);
2817 }
Ian Elliott2d4ab1e2015-01-13 17:52:38 -07002818#endif // WIN32
Tobin Ehlisf27eba72014-12-16 17:34:50 -07002819}
2820
Mark Lobodzinski17caf572015-01-29 08:55:56 -06002821XGL_LAYER_EXPORT void* XGLAPI xglGetProcAddr(XGL_PHYSICAL_GPU gpu, const char* funcName)
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002822{
2823 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
Chia-I Wu4d11dcc2015-01-05 13:18:57 +08002824
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002825 if (gpu == NULL)
2826 return NULL;
2827 pCurObj = gpuw;
Ian Elliott2d4ab1e2015-01-13 17:52:38 -07002828 loader_platform_thread_once(&g_initOnce, initDrawState);
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002829
Jon Ashburn925fee92015-03-02 11:32:24 -07002830 if (!strcmp(funcName, "xglGetProcAddr"))
2831 return (void *) xglGetProcAddr;
2832 if (!strcmp(funcName, "xglCreateDevice"))
2833 return (void*) xglCreateDevice;
2834 if (!strcmp(funcName, "xglDestroyDevice"))
2835 return (void*) xglDestroyDevice;
2836 if (!strcmp(funcName, "xglEnumerateLayers"))
2837 return (void*) xglEnumerateLayers;
2838 if (!strcmp(funcName, "xglQueueSubmit"))
2839 return (void*) xglQueueSubmit;
2840 if (!strcmp(funcName, "xglDestroyObject"))
2841 return (void*) xglDestroyObject;
2842 if (!strcmp(funcName, "xglCreateBufferView"))
2843 return (void*) xglCreateBufferView;
2844 if (!strcmp(funcName, "xglCreateImageView"))
2845 return (void*) xglCreateImageView;
2846 if (!strcmp(funcName, "xglCreateGraphicsPipeline"))
2847 return (void*) xglCreateGraphicsPipeline;
Courtney Goeltzenleuchter0d40f152015-03-25 15:37:49 -06002848 if (!strcmp(funcName, "xglCreateGraphicsPipelineDerivative"))
2849 return (void*) xglCreateGraphicsPipelineDerivative;
Jon Ashburn925fee92015-03-02 11:32:24 -07002850 if (!strcmp(funcName, "xglCreateSampler"))
2851 return (void*) xglCreateSampler;
2852 if (!strcmp(funcName, "xglCreateDescriptorSetLayout"))
2853 return (void*) xglCreateDescriptorSetLayout;
2854 if (!strcmp(funcName, "xglBeginDescriptorRegionUpdate"))
2855 return (void*) xglBeginDescriptorRegionUpdate;
2856 if (!strcmp(funcName, "xglEndDescriptorRegionUpdate"))
2857 return (void*) xglEndDescriptorRegionUpdate;
2858 if (!strcmp(funcName, "xglCreateDescriptorRegion"))
2859 return (void*) xglCreateDescriptorRegion;
2860 if (!strcmp(funcName, "xglClearDescriptorRegion"))
2861 return (void*) xglClearDescriptorRegion;
2862 if (!strcmp(funcName, "xglAllocDescriptorSets"))
2863 return (void*) xglAllocDescriptorSets;
2864 if (!strcmp(funcName, "xglClearDescriptorSets"))
2865 return (void*) xglClearDescriptorSets;
2866 if (!strcmp(funcName, "xglUpdateDescriptors"))
2867 return (void*) xglUpdateDescriptors;
2868 if (!strcmp(funcName, "xglCreateDynamicViewportState"))
2869 return (void*) xglCreateDynamicViewportState;
2870 if (!strcmp(funcName, "xglCreateDynamicRasterState"))
2871 return (void*) xglCreateDynamicRasterState;
2872 if (!strcmp(funcName, "xglCreateDynamicColorBlendState"))
2873 return (void*) xglCreateDynamicColorBlendState;
2874 if (!strcmp(funcName, "xglCreateDynamicDepthStencilState"))
2875 return (void*) xglCreateDynamicDepthStencilState;
2876 if (!strcmp(funcName, "xglCreateCommandBuffer"))
2877 return (void*) xglCreateCommandBuffer;
2878 if (!strcmp(funcName, "xglBeginCommandBuffer"))
2879 return (void*) xglBeginCommandBuffer;
2880 if (!strcmp(funcName, "xglEndCommandBuffer"))
2881 return (void*) xglEndCommandBuffer;
2882 if (!strcmp(funcName, "xglResetCommandBuffer"))
2883 return (void*) xglResetCommandBuffer;
2884 if (!strcmp(funcName, "xglCmdBindPipeline"))
2885 return (void*) xglCmdBindPipeline;
Jon Ashburn925fee92015-03-02 11:32:24 -07002886 if (!strcmp(funcName, "xglCmdBindDynamicStateObject"))
2887 return (void*) xglCmdBindDynamicStateObject;
2888 if (!strcmp(funcName, "xglCmdBindDescriptorSet"))
2889 return (void*) xglCmdBindDescriptorSet;
2890 if (!strcmp(funcName, "xglCmdBindVertexBuffer"))
2891 return (void*) xglCmdBindVertexBuffer;
2892 if (!strcmp(funcName, "xglCmdBindIndexBuffer"))
2893 return (void*) xglCmdBindIndexBuffer;
2894 if (!strcmp(funcName, "xglCmdDraw"))
2895 return (void*) xglCmdDraw;
2896 if (!strcmp(funcName, "xglCmdDrawIndexed"))
2897 return (void*) xglCmdDrawIndexed;
2898 if (!strcmp(funcName, "xglCmdDrawIndirect"))
2899 return (void*) xglCmdDrawIndirect;
2900 if (!strcmp(funcName, "xglCmdDrawIndexedIndirect"))
2901 return (void*) xglCmdDrawIndexedIndirect;
2902 if (!strcmp(funcName, "xglCmdDispatch"))
2903 return (void*) xglCmdDispatch;
2904 if (!strcmp(funcName, "xglCmdDispatchIndirect"))
2905 return (void*) xglCmdDispatchIndirect;
2906 if (!strcmp(funcName, "xglCmdCopyBuffer"))
2907 return (void*) xglCmdCopyBuffer;
2908 if (!strcmp(funcName, "xglCmdCopyImage"))
2909 return (void*) xglCmdCopyImage;
2910 if (!strcmp(funcName, "xglCmdCopyBufferToImage"))
2911 return (void*) xglCmdCopyBufferToImage;
2912 if (!strcmp(funcName, "xglCmdCopyImageToBuffer"))
2913 return (void*) xglCmdCopyImageToBuffer;
2914 if (!strcmp(funcName, "xglCmdCloneImageData"))
2915 return (void*) xglCmdCloneImageData;
2916 if (!strcmp(funcName, "xglCmdUpdateBuffer"))
2917 return (void*) xglCmdUpdateBuffer;
2918 if (!strcmp(funcName, "xglCmdFillBuffer"))
2919 return (void*) xglCmdFillBuffer;
2920 if (!strcmp(funcName, "xglCmdClearColorImage"))
2921 return (void*) xglCmdClearColorImage;
Jon Ashburn925fee92015-03-02 11:32:24 -07002922 if (!strcmp(funcName, "xglCmdClearDepthStencil"))
2923 return (void*) xglCmdClearDepthStencil;
2924 if (!strcmp(funcName, "xglCmdResolveImage"))
2925 return (void*) xglCmdResolveImage;
2926 if (!strcmp(funcName, "xglCmdSetEvent"))
2927 return (void*) xglCmdSetEvent;
2928 if (!strcmp(funcName, "xglCmdResetEvent"))
2929 return (void*) xglCmdResetEvent;
2930 if (!strcmp(funcName, "xglCmdWaitEvents"))
2931 return (void*) xglCmdWaitEvents;
2932 if (!strcmp(funcName, "xglCmdPipelineBarrier"))
2933 return (void*) xglCmdPipelineBarrier;
2934 if (!strcmp(funcName, "xglCmdBeginQuery"))
2935 return (void*) xglCmdBeginQuery;
2936 if (!strcmp(funcName, "xglCmdEndQuery"))
2937 return (void*) xglCmdEndQuery;
2938 if (!strcmp(funcName, "xglCmdResetQueryPool"))
2939 return (void*) xglCmdResetQueryPool;
2940 if (!strcmp(funcName, "xglCmdWriteTimestamp"))
2941 return (void*) xglCmdWriteTimestamp;
2942 if (!strcmp(funcName, "xglCmdInitAtomicCounters"))
2943 return (void*) xglCmdInitAtomicCounters;
2944 if (!strcmp(funcName, "xglCmdLoadAtomicCounters"))
2945 return (void*) xglCmdLoadAtomicCounters;
2946 if (!strcmp(funcName, "xglCmdSaveAtomicCounters"))
2947 return (void*) xglCmdSaveAtomicCounters;
2948 if (!strcmp(funcName, "xglCmdBeginRenderPass"))
2949 return (void*) xglCmdBeginRenderPass;
2950 if (!strcmp(funcName, "xglCmdEndRenderPass"))
2951 return (void*) xglCmdEndRenderPass;
2952 if (!strcmp(funcName, "xglDbgRegisterMsgCallback"))
2953 return (void*) xglDbgRegisterMsgCallback;
2954 if (!strcmp(funcName, "xglDbgUnregisterMsgCallback"))
2955 return (void*) xglDbgUnregisterMsgCallback;
2956 if (!strcmp(funcName, "xglCmdDbgMarkerBegin"))
2957 return (void*) xglCmdDbgMarkerBegin;
2958 if (!strcmp(funcName, "xglCmdDbgMarkerEnd"))
2959 return (void*) xglCmdDbgMarkerEnd;
2960 if (!strcmp("drawStateDumpDotFile", funcName))
Tobin Ehlis83562882014-11-27 15:43:39 -07002961 return drawStateDumpDotFile;
Jon Ashburn925fee92015-03-02 11:32:24 -07002962 if (!strcmp("drawStateDumpCommandBufferDotFile", funcName))
Tobin Ehlis249c77e2015-02-24 15:40:22 -07002963 return drawStateDumpCommandBufferDotFile;
Jon Ashburn925fee92015-03-02 11:32:24 -07002964 if (!strcmp("drawStateDumpPngFile", funcName))
Tobin Ehlisf27eba72014-12-16 17:34:50 -07002965 return drawStateDumpPngFile;
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002966 else {
Tobin Ehlis97657ce2014-10-24 12:01:45 -06002967 if (gpuw->pGPA == NULL)
2968 return NULL;
2969 return gpuw->pGPA(gpuw->nextObject, funcName);
2970 }
2971}