blob: 7a02581ccafe9d4f2d1b11611cd6d5c18fea18be [file] [log] [blame]
Tobin Ehlis6663f492014-11-10 12:29:12 -07001/*
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -05002 * Vulkan
Tobin Ehlis6663f492014-11-10 12:29:12 -07003 *
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -05004 * Copyright (C) 2015 LunarG, Inc.
Tobin Ehlis6663f492014-11-10 12:29:12 -07005 *
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
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -050017* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Tobin Ehlis6663f492014-11-10 12:29:12 -070018 * 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
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -050025#include <inttypes.h>
Tobin Ehlis6663f492014-11-10 12:29:12 -070026#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <assert.h>
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -050030#include <list>
31#include <map>
32using namespace std;
33
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070034#include "loader_platform.h"
Chia-I Wuaa4121f2015-01-04 23:11:43 +080035#include "xgl_dispatch_table_helper.h"
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -050036#include "xgl_struct_string_helper_cpp.h"
Tobin Ehliscd9223b2014-11-19 16:19:28 -070037#include "mem_tracker.h"
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -070038#include "layers_config.h"
Ian Elliott655cad72015-02-12 17:08:34 -070039// The following is #included again to catch certain OS-specific functions
40// being used:
41#include "loader_platform.h"
Jon Ashburn2e672892015-02-16 08:46:53 -070042#include "layers_msg.h"
Tobin Ehlis6663f492014-11-10 12:29:12 -070043
44static XGL_LAYER_DISPATCH_TABLE nextTable;
45static XGL_BASE_LAYER_OBJECT *pCurObj;
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070046static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(g_initOnce);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -060047// TODO : This can be much smarter, using separate locks for separate global data
48static int globalLockInitialized = 0;
49static loader_platform_thread_mutex globalLock;
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -070050
Tobin Ehlisc145be82015-01-08 15:22:32 -070051#define MAX_BINDING 0xFFFFFFFF
Tobin Ehlisc145be82015-01-08 15:22:32 -070052
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -050053map<XGL_CMD_BUFFER, GLOBAL_CB_NODE*> cbMap;
54map<XGL_GPU_MEMORY, GLOBAL_MEM_OBJ_NODE*> memObjMap;
55map<XGL_OBJECT, GLOBAL_OBJECT_NODE*> objectMap;
56map<uint64_t, GLOBAL_FENCE_NODE*> fenceMap; // Map fenceId to fence node
57
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -050058// TODO : Add support for per-queue and per-device fence completion
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -050059static uint64_t g_currentFenceId = 1;
60static uint64_t g_lastRetiredId = 0;
61static XGL_DEVICE globalDevice = NULL;
Mark Lobodzinskic52b7752015-02-18 16:38:17 -060062
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -050063// Add new CB node for this cb to map container
Tobin Ehlis6663f492014-11-10 12:29:12 -070064static void insertGlobalCB(const XGL_CMD_BUFFER cb)
65{
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -050066 GLOBAL_CB_NODE* pTrav = new GLOBAL_CB_NODE;
67 memset(pTrav, 0, (sizeof(GLOBAL_CB_NODE) - sizeof(list<XGL_GPU_MEMORY>)));
68 pTrav->cmdBuffer = cb;
69 cbMap[cb] = pTrav;
Tobin Ehlis6663f492014-11-10 12:29:12 -070070}
71
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -050072// Return ptr to node in CB map, or NULL if not found
Tobin Ehlis6663f492014-11-10 12:29:12 -070073static GLOBAL_CB_NODE* getGlobalCBNode(const XGL_CMD_BUFFER cb)
74{
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -050075 GLOBAL_CB_NODE* pCBNode = NULL;
76 if (cbMap.find(cb) != cbMap.end()) {
77 pCBNode = cbMap[cb];
Mark Lobodzinski93f494b2015-03-02 20:23:52 -060078 }
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -050079 return pCBNode;
Tobin Ehlis6663f492014-11-10 12:29:12 -070080}
Mark Lobodzinski93f494b2015-03-02 20:23:52 -060081
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -050082// Add a fence, creating one if necessary to our list of fences/fenceIds
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -050083static uint64_t addFenceNode(XGL_FENCE fence)
84{
85 // Create fence node
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -050086 GLOBAL_FENCE_NODE* pFenceNode = new GLOBAL_FENCE_NODE;
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -050087 memset(pFenceNode, 0, sizeof(GLOBAL_FENCE_NODE));
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -050088 // If no fence, create an internal fence to track the submissions
89 if (fence == NULL) {
90 XGL_FENCE_CREATE_INFO fci;
91 fci.sType = XGL_STRUCTURE_TYPE_FENCE_CREATE_INFO;
92 fci.pNext = NULL;
93 fci.flags = 0;
94 nextTable.CreateFence(globalDevice, &fci, &pFenceNode->fence);
95 pFenceNode->localFence = XGL_TRUE;
96 } else {
97 pFenceNode->localFence = XGL_FALSE;
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -050098 pFenceNode->fence = fence;
Tobin Ehlis6663f492014-11-10 12:29:12 -070099 }
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500100 uint64_t fenceId = g_currentFenceId++;
101 fenceMap[fenceId] = pFenceNode;
102 return fenceId;
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500103}
104
105// Remove a node from our list of fences/fenceIds
106static void deleteFenceNode(uint64_t fenceId)
107{
108 if (fenceId != 0) {
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500109 if (fenceMap.find(fenceId) != fenceMap.end()) {
110 GLOBAL_FENCE_NODE* pDelNode = fenceMap[fenceId];
111 if (pDelNode->localFence == XGL_TRUE) {
112 nextTable.DestroyObject(pDelNode->fence);
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500113 }
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500114 delete pDelNode;
115 fenceMap.erase(fenceId);
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500116 }
117 }
118}
119
120// Search through list for this fence, deleting all nodes before it (with lower IDs) and updating lastRetiredId
121static void updateFenceTracking(XGL_FENCE fence)
122{
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500123 GLOBAL_FENCE_NODE *pCurFenceNode = NULL;
124 uint64_t fenceId = 0;
125
126 for (map<uint64_t, GLOBAL_FENCE_NODE*>::iterator ii=fenceMap.begin(); ii!=fenceMap.end(); ++ii) {
127 if (fence == ((*ii).second)->fence) {
128 g_lastRetiredId = (*ii).first;
129 } else {
130 deleteFenceNode((*ii).first);
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500131 }
132 }
133}
134
135// Utility function that determines if a fenceId has been retired yet
136static bool32_t fenceRetired(uint64_t fenceId)
137{
138 bool32_t result = XGL_FALSE;
139 if (fenceId <= g_lastRetiredId) {
140 result = XGL_TRUE;
141 }
142 return result;
143}
144
145// Return the fence associated with a fenceId
146static XGL_FENCE getFenceFromId(uint64_t fenceId)
147{
148 XGL_FENCE fence = NULL;
149 if (fenceId != 0) {
150 // Search for a node with this fenceId
151 if (fenceId > g_lastRetiredId) {
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500152 if (fenceMap.find(fenceId) != fenceMap.end()) {
153 fence = (fenceMap[fenceId])->fence;
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500154 }
155 }
156 }
157 return fence;
158}
159
160// Helper routine that updates the fence list to all-retired, as for Queue/DeviceWaitIdle
161static void retireAllFences(void)
162{
163 // In this case, we go throught the whole list, retiring each node and update the global retired ID until the list is empty
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500164 GLOBAL_FENCE_NODE* pDelNode = NULL;
165 for (map<uint64_t, GLOBAL_FENCE_NODE*>::iterator ii=fenceMap.begin(); ii!=fenceMap.end(); ++ii) {
166 g_lastRetiredId = (*ii).first;
167 deleteFenceNode((*ii).first);
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500168 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700169}
170
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600171static bool32_t validateCBMemRef(const XGL_CMD_BUFFER cb, uint32_t memRefCount, const XGL_MEMORY_REF* pMemRefs)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700172{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600173 bool32_t result = XGL_TRUE;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700174 GLOBAL_CB_NODE* pTrav = getGlobalCBNode(cb);
175 if (!pTrav) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700176 char str[1024];
177 sprintf(str, "Unable to find node for CB %p in order to check memory references", (void*)cb);
178 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_CB, "MEM", str);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600179 result = XGL_FALSE;
180 } else {
181 // Validate that all actual references are accounted for in pMemRefs
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600182 uint32_t i;
183 uint8_t found = 0;
184 uint64_t foundCount = 0;
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500185
186 for (list<XGL_GPU_MEMORY>::iterator it = pTrav->pMemObjList.begin(); it != pTrav->pMemObjList.end(); ++it) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600187 for (i = 0; i < memRefCount; i++) {
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500188 if ((*it) == pMemRefs[i].mem) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600189 char str[1024];
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500190 sprintf(str, "Found Mem Obj %p binding to CB %p", (*it), cb);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600191 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_NONE, "MEM", str);
192 found = 1;
193 foundCount++;
194 break;
195 }
196 }
197 if (!found) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700198 char str[1024];
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500199 sprintf(str, "Memory reference list for Command Buffer %p is missing ref to mem obj %p", cb, (*it));
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600200 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_CB_MISSING_MEM_REF, "MEM", str);
201 result = XGL_FALSE;
202 }
203 found = 0;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600204 }
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500205
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600206 if (result == XGL_TRUE) {
207 char str[1024];
208 sprintf(str, "Verified all %lu memory dependencies for CB %p are included in pMemRefs list", foundCount, cb);
209 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500210 // TODO : Could report mem refs in pMemRefs that AREN'T in mem list, that would be primarily informational
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600211 // Currently just noting that there is a difference
212 if (foundCount != memRefCount) {
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500213 sprintf(str, "There are %u mem refs included in pMemRefs list, but only %lu are required", memRefCount, foundCount);
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700214 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700215 }
216 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700217 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600218 return result;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700219}
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500220// Return ptr to node in map container containing mem, or NULL if not found
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -0700221// Calls to this function should be wrapped in mutex
Tobin Ehlisc145be82015-01-08 15:22:32 -0700222static GLOBAL_MEM_OBJ_NODE* getGlobalMemNode(const XGL_GPU_MEMORY mem)
223{
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500224 GLOBAL_MEM_OBJ_NODE* pMemNode = NULL;
225
226 if (memObjMap.find(mem) != memObjMap.end()) {
227 pMemNode = memObjMap[mem];
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600228 }
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500229 return pMemNode;
Tobin Ehlisc145be82015-01-08 15:22:32 -0700230}
231
Mark Lobodzinskic52b7752015-02-18 16:38:17 -0600232static void insertGlobalMemObj(const XGL_GPU_MEMORY mem, const XGL_MEMORY_ALLOC_INFO* pAllocInfo)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700233{
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500234 GLOBAL_MEM_OBJ_NODE* pTrav = new GLOBAL_MEM_OBJ_NODE;
235 pTrav->refCount = 0;
236 memset(&pTrav->allocInfo, 0, sizeof(XGL_MEMORY_ALLOC_INFO));
237
238 if (pAllocInfo) { // MEM alloc created by xglWsiX11CreatePresentableImage() doesn't have alloc info struct
239 memcpy(&pTrav->allocInfo, pAllocInfo, sizeof(XGL_MEMORY_ALLOC_INFO));
240 // TODO: Update for real hardware, actually process allocation info structures
241 pTrav->allocInfo.pNext = NULL;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700242 }
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500243 pTrav->mem = mem;
244 memObjMap[mem] = pTrav;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700245}
246
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500247// Find Global CB Node and add mem binding to list container
248// Find Global Mem Obj Node and add CB binding to list container
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600249static bool32_t updateCBBinding(const XGL_CMD_BUFFER cb, const XGL_GPU_MEMORY mem)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700250{
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500251 bool32_t result = XGL_TRUE;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700252 // First update CB binding in MemObj mini CB list
253 GLOBAL_MEM_OBJ_NODE* pMemTrav = getGlobalMemNode(mem);
254 if (!pMemTrav) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700255 char str[1024];
256 sprintf(str, "Trying to bind mem obj %p to CB %p but no Node for that mem obj.\n Was it correctly allocated? Did it already get freed?", mem, cb);
257 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600258 result = XGL_FALSE;
259 } else {
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500260 // Search for cmd buffer object in memory object's binding list
261 bool32_t found = XGL_FALSE;
262 for (list<XGL_CMD_BUFFER>::iterator it = pMemTrav->pCmdBufferBindings.begin(); it != pMemTrav->pCmdBufferBindings.end(); ++it) {
263 if ((*it) == cb) {
264 found = XGL_TRUE;
265 break;
266 }
267 }
268 // If not present, add to list
269 if (found == XGL_FALSE) {
270 pMemTrav->pCmdBufferBindings.push_front(cb);
271 pMemTrav->refCount++;
272 }
273
274 // Now update Global CB's Mem binding list
275 GLOBAL_CB_NODE* pCBTrav = getGlobalCBNode(cb);
276 if (!pCBTrav) {
277 char str[1024];
278 sprintf(str, "Trying to bind mem obj %p to CB %p but no Node for that CB. Was it CB incorrectly destroyed?", mem, cb);
279 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
280 result = XGL_FALSE;
281 } else {
282 // Search for memory object in cmd buffer's binding list
283 bool32_t found = XGL_FALSE;
284 for (list<XGL_GPU_MEMORY>::iterator it = pCBTrav->pMemObjList.begin(); it != pCBTrav->pMemObjList.end(); ++it) {
285 if ((*it) == mem) {
286 found = XGL_TRUE;
287 break;
288 }
289 }
290 // If not present, add to list
291 if (found == XGL_FALSE) {
292 pCBTrav->pMemObjList.push_front(mem);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600293 }
294 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700295 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600296 return result;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700297}
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600298
Tobin Ehlis6663f492014-11-10 12:29:12 -0700299// Clear the CB Binding for mem
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -0700300// Calls to this function should be wrapped in mutex
Tobin Ehlis6663f492014-11-10 12:29:12 -0700301static void clearCBBinding(const XGL_CMD_BUFFER cb, const XGL_GPU_MEMORY mem)
302{
303 GLOBAL_MEM_OBJ_NODE* pTrav = getGlobalMemNode(mem);
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -0700304 // TODO : Having this check is not ideal, really if mem node was deleted,
305 // its CB bindings should be cleared and then freeCBBindings wouldn't call
306 // us here with stale mem objs
307 if (pTrav) {
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500308 pTrav->pCmdBufferBindings.remove(cb);
309 pTrav->refCount--;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700310 }
311}
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600312
Tobin Ehlis6663f492014-11-10 12:29:12 -0700313// Free bindings related to CB
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600314static bool32_t freeCBBindings(const XGL_CMD_BUFFER cb)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700315{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600316 bool32_t result = XGL_TRUE;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700317 GLOBAL_CB_NODE* pCBTrav = getGlobalCBNode(cb);
318 if (!pCBTrav) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700319 char str[1024];
320 sprintf(str, "Unable to find global CB node %p for deletion", cb);
321 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_CB, "MEM", str);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600322 result = XGL_FALSE;
323 } else {
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500324 if (!fenceRetired(pCBTrav->fenceId)) {
325 deleteFenceNode(pCBTrav->fenceId);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600326 }
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500327
328 for (list<XGL_GPU_MEMORY>::iterator it=pCBTrav->pMemObjList.begin(); it!=pCBTrav->pMemObjList.end(); ++it) {
329 clearCBBinding(cb, (*it));
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600330 }
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500331 pCBTrav->pMemObjList.clear();
Tobin Ehlis6663f492014-11-10 12:29:12 -0700332 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600333 return result;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700334}
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600335
Tobin Ehlis6663f492014-11-10 12:29:12 -0700336// Delete Global CB Node from list along with all of it's mini mem obj node
337// and also clear Global mem references to CB
338// TODO : When should this be called? There's no Destroy of CBs that I see
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600339static bool32_t deleteGlobalCBNode(const XGL_CMD_BUFFER cb)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700340{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600341 bool32_t result = XGL_TRUE;
342 result = freeCBBindings(cb);
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500343 // Delete the Global CB node
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600344 if (result == XGL_TRUE) {
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500345 if (cbMap.find(cb) != cbMap.end()) {
346 GLOBAL_CB_NODE* pDelNode = cbMap[cb];
347 delete pDelNode;
348 cbMap.erase(cb);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600349 }
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700350 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600351 return result;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700352}
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600353
Tobin Ehlis6663f492014-11-10 12:29:12 -0700354// Delete the entire CB list
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600355static bool32_t deleteGlobalCBList()
Tobin Ehlis6663f492014-11-10 12:29:12 -0700356{
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600357 bool32_t result = XGL_TRUE;
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500358 for (map<XGL_CMD_BUFFER, GLOBAL_CB_NODE*>::iterator ii=cbMap.begin(); ii!=cbMap.end(); ++ii) {
359 freeCBBindings((*ii).first);
360 delete (*ii).second;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700361 }
362 return result;
363}
364
365// For given MemObj node, report Obj & CB bindings
366static void reportMemReferences(const GLOBAL_MEM_OBJ_NODE* pMemObjTrav)
367{
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600368 uint32_t refCount = 0; // Count found references
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500369
370 for (list<XGL_CMD_BUFFER>::const_iterator it = pMemObjTrav->pCmdBufferBindings.begin(); it != pMemObjTrav->pCmdBufferBindings.end(); ++it) {
Tobin Ehlis6663f492014-11-10 12:29:12 -0700371 refCount++;
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700372 char str[1024];
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500373 sprintf(str, "Command Buffer %p has reference to mem obj %p", (*it), pMemObjTrav->mem);
374 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, (*it), 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700375 }
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500376 for (list<XGL_OBJECT>::const_iterator it = pMemObjTrav->pObjBindings.begin(); it != pMemObjTrav->pObjBindings.end(); ++it) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700377 char str[1024];
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500378 sprintf(str, "XGL Object %p has reference to mem obj %p", (*it), pMemObjTrav->mem);
379 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, (*it), 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700380 }
381 if (refCount != pMemObjTrav->refCount) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700382 char str[1024];
383 sprintf(str, "Refcount of %u for Mem Obj %p does't match reported refs of %u", pMemObjTrav->refCount, pMemObjTrav->mem, refCount);
Mark Lobodzinskiae5f13b2015-02-26 15:18:57 -0600384 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, pMemObjTrav->mem, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700385 }
386}
387
388static void deleteGlobalMemNode(XGL_GPU_MEMORY mem)
389{
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500390 GLOBAL_MEM_OBJ_NODE* pDelNode = memObjMap[mem];
391 if (memObjMap.find(mem) != memObjMap.end()) {
392 GLOBAL_MEM_OBJ_NODE* pDelNode = memObjMap[mem];
393 delete pDelNode;
394 memObjMap.erase(mem);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700395 }
396}
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500397
Tobin Ehlis6663f492014-11-10 12:29:12 -0700398// Check if fence for given CB is completed
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600399static bool32_t checkCBCompleted(const XGL_CMD_BUFFER cb)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700400{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600401 bool32_t result = XGL_TRUE;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700402 GLOBAL_CB_NODE* pCBTrav = getGlobalCBNode(cb);
403 if (!pCBTrav) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700404 char str[1024];
405 sprintf(str, "Unable to find global CB node %p to check for completion", cb);
406 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_CB, "MEM", str);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600407 result = XGL_FALSE;
408 } else {
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500409 if (!fenceRetired(pCBTrav->fenceId)) {
410 // Explicitly call the internal xglGetFenceStatus routine
411 if (XGL_SUCCESS != xglGetFenceStatus(getFenceFromId(pCBTrav->fenceId))) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600412 char str[1024];
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500413 sprintf(str, "FenceId %" PRIx64", fence %p for CB %p has not completed", pCBTrav->fenceId, getFenceFromId(pCBTrav->fenceId), cb);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600414 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_NONE, "MEM", str);
415 result = XGL_FALSE;
416 }
417 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700418 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600419 return result;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700420}
421
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600422static bool32_t freeMemNode(XGL_GPU_MEMORY mem)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700423{
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600424 bool32_t result = XGL_TRUE;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700425 // Parse global list to find node w/ mem
426 GLOBAL_MEM_OBJ_NODE* pTrav = getGlobalMemNode(mem);
427 if (!pTrav) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700428 char str[1024];
429 sprintf(str, "Couldn't find mem node object for %p\n Was %p never allocated or previously freed?", (void*)mem, (void*)mem);
430 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600431 result = XGL_FALSE;
432 } else {
Mark Lobodzinski2f3b19b2015-02-18 18:06:24 -0600433 if (pTrav->allocInfo.allocationSize == 0) {
434 char str[1024];
435 sprintf(str, "Attempting to free memory associated with a Presentable Image, %p, this should not be explicitly freed\n", (void*)mem);
Mark Lobodzinski78a21972015-03-05 12:39:33 -0600436 layerCbMsg(XGL_DBG_MSG_WARNING, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700437 result = XGL_FALSE;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600438 } else {
439 // Clear any CB bindings for completed CBs
440 // TODO : Is there a better place to do this?
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500441
442 list<XGL_CMD_BUFFER>::iterator it = pTrav->pCmdBufferBindings.begin();
443 list<XGL_CMD_BUFFER>::iterator temp;
444 while (it != pTrav->pCmdBufferBindings.end()) {
445 if (XGL_TRUE == checkCBCompleted(*it)) {
446 temp = it;
447 ++temp;
448 freeCBBindings(*it);
449 it = temp;
450 } else {
451 ++it;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600452 }
453 }
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500454
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600455 // Now verify that no references to this mem obj remain
456 if (0 != pTrav->refCount) {
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500457 // If references remain, report the error and can search CB list to find references
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600458 char str[1024];
459 sprintf(str, "Freeing mem obj %p while it still has references", (void*)mem);
460 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_FREED_MEM_REF, "MEM", str);
461 reportMemReferences(pTrav);
462 result = XGL_FALSE;
463 }
464 // Delete global node
465 deleteGlobalMemNode(mem);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700466 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700467 }
468 return result;
469}
470
471// Return object node for 'object' or return NULL if no node exists
472static GLOBAL_OBJECT_NODE* getGlobalObjectNode(const XGL_OBJECT object)
473{
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500474 GLOBAL_OBJECT_NODE* pObjNode = NULL;
475
476 if (objectMap.find(object) != objectMap.end()) {
477 pObjNode = objectMap[object];
Tobin Ehlis6663f492014-11-10 12:29:12 -0700478 }
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500479 return pObjNode;
480}
481
482static GLOBAL_OBJECT_NODE* insertGlobalObjectNode(XGL_OBJECT object, XGL_STRUCTURE_TYPE sType, const void *pCreateInfo, const int struct_size, const char *name_prefix)
483{
484 GLOBAL_OBJECT_NODE* pTrav = new GLOBAL_OBJECT_NODE;
485 memset(pTrav, 0, sizeof(GLOBAL_OBJECT_NODE));
486 memcpy(&pTrav->create_info, pCreateInfo, struct_size);
487 sprintf(pTrav->object_name, "%s_%p", name_prefix, object);
488
489 pTrav->object = object;
490 pTrav->ref_count = 1;
491 pTrav->sType = sType;
492 objectMap[object] = pTrav;
493
Tobin Ehlis6663f492014-11-10 12:29:12 -0700494 return pTrav;
495}
496
Tobin Ehlis6663f492014-11-10 12:29:12 -0700497// Remove object binding performs 3 tasks:
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500498// 1. Remove object node from Global Mem Obj list container of obj bindings & free it
Tobin Ehlis6663f492014-11-10 12:29:12 -0700499// 2. Decrement refCount for Global Mem Obj
500// 3. Clear Global Mem Obj ptr from Global Object Node
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600501static bool32_t clearObjectBinding(XGL_OBJECT object)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700502{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600503 bool32_t result = XGL_FALSE;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700504 GLOBAL_OBJECT_NODE* pGlobalObjTrav = getGlobalObjectNode(object);
505 if (!pGlobalObjTrav) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700506 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -0600507 sprintf(str, "Attempting to clear mem binding for object %p: devices, queues, command buffers, shaders and memory objects do not have external memory requirements and it is unneccessary to call bind/unbindObjectMemory on them.", object);
508 layerCbMsg(XGL_DBG_MSG_WARNING, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INVALID_OBJECT, "MEM", str);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600509 } else {
510 if (!pGlobalObjTrav->pMemNode) {
511 char str[1024];
512 sprintf(str, "Attempting to clear mem binding on obj %p but it has no binding.", (void*)object);
513 layerCbMsg(XGL_DBG_MSG_WARNING, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MEM_OBJ_CLEAR_EMPTY_BINDINGS, "MEM", str);
514 } else {
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500515 for (list<XGL_OBJECT>::iterator it = pGlobalObjTrav->pMemNode->pObjBindings.begin(); it != pGlobalObjTrav->pMemNode->pObjBindings.end(); ++it) {
516 pGlobalObjTrav->pMemNode->refCount--;
517 pGlobalObjTrav->pMemNode = NULL;
518 it = pGlobalObjTrav->pMemNode->pObjBindings.erase(it);
519 result = XGL_TRUE;
520 break;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600521 }
522 if (result == XGL_FALSE) {
523 char str[1024];
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500524 sprintf(str, "While trying to clear mem binding for object %p, unable to find that object referenced by mem obj %p",
525 object, pGlobalObjTrav->pMemNode->mem);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600526 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
527 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700528 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700529 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600530 return result;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700531}
532
533// For NULL mem case, clear any previous binding Else...
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500534// Make sure given object is in global object map
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700535// IF a previous binding existed, clear it
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500536// Add reference from global object node to global memory node
537// Add reference off of global obj node
Tobin Ehlis6663f492014-11-10 12:29:12 -0700538// Return XGL_TRUE if addition is successful, XGL_FALSE otherwise
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600539static bool32_t updateObjectBinding(XGL_OBJECT object, XGL_GPU_MEMORY mem)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700540{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600541 bool32_t result = XGL_FALSE;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700542 // Handle NULL case separately, just clear previous binding & decrement reference
543 if (mem == XGL_NULL_HANDLE) {
544 clearObjectBinding(object);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600545 result = XGL_TRUE;
546 } else {
547 char str[1024];
548 GLOBAL_OBJECT_NODE* pGlobalObjTrav = getGlobalObjectNode(object);
549 if (!pGlobalObjTrav) {
550 sprintf(str, "Attempting to update Binding of Obj(%p) that's not in global list()", (void*)object);
551 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
552 return XGL_FALSE;
553 }
554 // non-null case so should have real mem obj
555 GLOBAL_MEM_OBJ_NODE* pTrav = getGlobalMemNode(mem);
556 if (!pTrav) {
557 sprintf(str, "While trying to bind mem for obj %p, couldn't find node for mem obj %p", (void*)object, (void*)mem);
558 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
559 } else {
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500560 // Search for object in memory object's binding list
561 bool32_t found = XGL_FALSE;
562 for (list<XGL_OBJECT>::iterator it = pTrav->pObjBindings.begin(); it != pTrav->pObjBindings.end(); ++it) {
563 if ((*it) == object) {
564 found = XGL_TRUE;
565 break;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600566 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600567 }
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500568 // If not present, add to list
569 if (found == XGL_FALSE) {
570 pTrav->pObjBindings.push_front(object);
571 pTrav->refCount++;
572 }
573
574 if (pGlobalObjTrav->pMemNode) {
575 clearObjectBinding(object); // Need to clear the previous object binding before setting new binding
576 sprintf(str, "Updating memory binding for object %p from mem obj %p to %p", object, pGlobalObjTrav->pMemNode->mem, mem);
577 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_NONE, "MEM", str);
578 }
579 // For image objects, make sure default memory state is correctly set
580 // TODO : What's the best/correct way to handle this?
581 if (XGL_STRUCTURE_TYPE_IMAGE_CREATE_INFO == pGlobalObjTrav->sType) {
582 if (pGlobalObjTrav->create_info.image_create_info.usage & (XGL_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | XGL_IMAGE_USAGE_DEPTH_STENCIL_BIT)) {
583 // TODO:: More memory state transition stuff.
584 }
585 }
586 pGlobalObjTrav->pMemNode = pTrav;
Tobin Ehlis8be20fd2015-01-07 17:49:29 -0700587 }
588 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700589 return XGL_TRUE;
590}
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600591
Tobin Ehlis6663f492014-11-10 12:29:12 -0700592// Print details of global Obj tracking list
593static void printObjList()
594{
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500595 GLOBAL_OBJECT_NODE* pTrav = NULL;
596 char str[1024];
597 sprintf(str, "Details of Global Object list of size %lu elements", objectMap.size());
598 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
599 for (map<XGL_OBJECT, GLOBAL_OBJECT_NODE*>::iterator ii=objectMap.begin(); ii!=objectMap.end(); ++ii) {
600 pTrav = (*ii).second;
601 sprintf(str, " GlobObjNode %p has object %p, pMemNode %p", pTrav, pTrav->object, pTrav->pMemNode);
602 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pTrav->object, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700603 }
604}
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600605
Tobin Ehlis6663f492014-11-10 12:29:12 -0700606// For given Object, get 'mem' obj that it's bound to or NULL if no binding
607static XGL_GPU_MEMORY getMemBindingFromObject(const XGL_OBJECT object)
608{
609 XGL_GPU_MEMORY mem = NULL;
610 GLOBAL_OBJECT_NODE* pObjNode = getGlobalObjectNode(object);
611 if (pObjNode) {
612 if (pObjNode->pMemNode) {
613 mem = pObjNode->pMemNode->mem;
614 }
615 else {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700616 char str[1024];
617 sprintf(str, "Trying to get mem binding for object %p but object has no mem binding", (void*)object);
618 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MISSING_MEM_BINDINGS, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700619 printObjList();
620 }
621 }
622 else {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700623 char str[1024];
624 sprintf(str, "Trying to get mem binding for object %p but no such object in global list", (void*)object);
625 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INVALID_OBJECT, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700626 printObjList();
627 }
628 return mem;
629}
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500630
Tobin Ehlis6663f492014-11-10 12:29:12 -0700631// Print details of global Mem Obj list
632static void printMemList()
633{
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500634 GLOBAL_MEM_OBJ_NODE* pTrav = NULL;
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700635 // Just printing each msg individually for now, may want to package these into single large print
636 char str[1024];
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500637 sprintf(str, "MEM INFO : Details of Global Memory Object list of size %lu elements", memObjMap.size());
638 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
639
640 for (map<XGL_GPU_MEMORY, GLOBAL_MEM_OBJ_NODE*>::iterator ii=memObjMap.begin(); ii!=memObjMap.end(); ++ii) {
641 pTrav = (*ii).second;
642
643 sprintf(str, " ===MemObj Node at %p===", (void*)pTrav);
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700644 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500645 sprintf(str, " Mem object: %p", (void*)pTrav->mem);
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700646 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500647 sprintf(str, " Ref Count: %u", pTrav->refCount);
648 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
649 if (0 != pTrav->allocInfo.allocationSize) {
650 string pAllocInfoMsg = xgl_print_xgl_memory_alloc_info(&pTrav->allocInfo, "{MEM}INFO : ");
651 sprintf(str, " Mem Alloc info:\n%s", pAllocInfoMsg.c_str());
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700652 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500653 } else {
654 sprintf(str, " Mem Alloc info is NULL (alloc done by xglWsiX11CreatePresentableImage())");
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700655 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500656 }
657
658 sprintf(str, " XGL OBJECT Binding list of size %lu elements:", pTrav->pObjBindings.size());
659 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
660 for (list<XGL_OBJECT>::iterator it = pTrav->pObjBindings.begin(); it != pTrav->pObjBindings.end(); ++it) {
661 sprintf(str, " XGL OBJECT %p", (*it));
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700662 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500663 }
664
665 sprintf(str, " XGL Command Buffer (CB) binding list of size %lu elements", pTrav->pCmdBufferBindings.size());
666 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
667 for (list<XGL_CMD_BUFFER>::iterator it = pTrav->pCmdBufferBindings.begin(); it != pTrav->pCmdBufferBindings.end(); ++it) {
668 sprintf(str, " XGL CB %p", (*it));
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700669 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700670 }
671 }
672}
673
674static void printGlobalCB()
675{
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700676 char str[1024] = {0};
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500677 GLOBAL_CB_NODE* pNode = NULL;
678 sprintf(str, "Details of Global CB list of size %lu elements", cbMap.size());
679 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
680
681 for (map<XGL_CMD_BUFFER, GLOBAL_CB_NODE*>::iterator ii=cbMap.begin(); ii!=cbMap.end(); ++ii) {
682 pNode = (*ii).second;
683
684 sprintf(str, " Global CB Node (%p) has CB %p, fenceId %" PRIx64", and fence %p",
685 (void*)pNode, (void*)pNode->cmdBuffer, pNode->fenceId,
686 (void*)getFenceFromId(pNode->fenceId));
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700687 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500688
689 for (list<XGL_GPU_MEMORY>::iterator it = pNode->pMemObjList.begin(); it != pNode->pMemObjList.end(); ++it) {
690 sprintf(str, " Mem obj %p", (*it));
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700691 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700692 }
693 }
694}
695
Mark Lobodzinskic52b7752015-02-18 16:38:17 -0600696static void initMemTracker(void)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700697{
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -0700698 const char *strOpt;
699 // initialize MemTracker options
Ian Elliotte7826712015-03-06 13:50:05 -0700700 getLayerOptionEnum("MemTrackerReportLevel", (uint32_t *) &g_reportingLevel);
701 g_actionIsDefault = getLayerOptionEnum("MemTrackerDebugAction", (uint32_t *) &g_debugAction);
Tobin Ehlisee702232015-01-08 14:26:53 -0700702
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -0700703 if (g_debugAction & XGL_DBG_LAYER_ACTION_LOG_MSG)
704 {
705 strOpt = getLayerOption("MemTrackerLogFilename");
706 if (strOpt)
707 {
708 g_logFile = fopen(strOpt, "w");
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -0700709 }
710 if (g_logFile == NULL)
711 g_logFile = stdout;
712 }
713
714 // initialize Layer dispatch table
715 // TODO handle multiple GPUs
Mark Lobodzinski391bb6d2015-01-09 15:12:03 -0600716 xglGetProcAddrType fpNextGPA;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700717 fpNextGPA = pCurObj->pGPA;
718 assert(fpNextGPA);
719
Chia-I Wuaa4121f2015-01-04 23:11:43 +0800720 layer_initialize_dispatch_table(&nextTable, fpNextGPA, (XGL_PHYSICAL_GPU) pCurObj->nextObject);
721
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500722 xglGetProcAddrType fpGetProcAddr = (xglGetProcAddrType)fpNextGPA((XGL_PHYSICAL_GPU) pCurObj->nextObject, (char *) "xglGetProcAddr");
Tobin Ehlis6663f492014-11-10 12:29:12 -0700723 nextTable.GetProcAddr = fpGetProcAddr;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600724
725 if (!globalLockInitialized)
726 {
727 // TODO/TBD: Need to delete this mutex sometime. How??? One
728 // suggestion is to call this during xglCreateInstance(), and then we
729 // can clean it up during xglDestroyInstance(). However, that requires
730 // that the layer have per-instance locks. We need to come back and
731 // address this soon.
732 loader_platform_thread_create_mutex(&globalLock);
733 globalLockInitialized = 1;
734 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700735}
736
Tobin Ehlis6663f492014-11-10 12:29:12 -0700737XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDevice(XGL_PHYSICAL_GPU gpu, const XGL_DEVICE_CREATE_INFO* pCreateInfo, XGL_DEVICE* pDevice)
738{
739 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
740 pCurObj = gpuw;
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700741 loader_platform_thread_once(&g_initOnce, initMemTracker);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700742 XGL_RESULT result = nextTable.CreateDevice((XGL_PHYSICAL_GPU)gpuw->nextObject, pCreateInfo, pDevice);
743 // Save off device in case we need it to create Fences
744 globalDevice = *pDevice;
745 return result;
746}
747
748XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDestroyDevice(XGL_DEVICE device)
749{
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700750 char str[1024];
751 sprintf(str, "Printing List details prior to xglDestroyDevice()");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600752 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700753 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, device, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700754 printMemList();
755 printGlobalCB();
756 printObjList();
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700757 if (XGL_FALSE == deleteGlobalCBList()) {
758 sprintf(str, "Issue deleting global CB list in xglDestroyDevice()");
759 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, device, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
760 }
Tobin Ehlisb54ef782014-11-25 18:01:12 -0700761 // Report any memory leaks
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500762 GLOBAL_MEM_OBJ_NODE* pTrav = NULL;
763 for (map<XGL_GPU_MEMORY, GLOBAL_MEM_OBJ_NODE*>::iterator ii=memObjMap.begin(); ii!=memObjMap.end(); ++ii) {
764 pTrav = (*ii).second;
765
Mark Lobodzinski2f3b19b2015-02-18 18:06:24 -0600766 if (pTrav->allocInfo.allocationSize != 0) {
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500767 sprintf(str, "Mem Object %p has not been freed. You should clean up this memory by calling xglFreeMemory(%p) prior to xglDestroyDevice().",
768 pTrav->mem, pTrav->mem);
Mark Lobodzinski2f3b19b2015-02-18 18:06:24 -0600769 layerCbMsg(XGL_DBG_MSG_WARNING, XGL_VALIDATION_LEVEL_0, pTrav->mem, 0, MEMTRACK_MEMORY_LEAK, "MEM", str);
770 }
Tobin Ehlisb54ef782014-11-25 18:01:12 -0700771 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600772 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700773 XGL_RESULT result = nextTable.DestroyDevice(device);
774 return result;
775}
776
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500777XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglEnumerateLayers(XGL_PHYSICAL_GPU gpu, size_t maxLayerCount,
778 size_t maxStringSize, size_t* pOutLayerCount, char* const* pOutLayers, void* pReserved)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700779{
Jon Ashburnf7a08742014-11-25 11:08:42 -0700780 if (gpu != NULL)
781 {
782 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
783 pCurObj = gpuw;
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700784 loader_platform_thread_once(&g_initOnce, initMemTracker);
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500785 XGL_RESULT result = nextTable.EnumerateLayers((XGL_PHYSICAL_GPU)gpuw->nextObject, maxLayerCount,
786 maxStringSize, pOutLayerCount, pOutLayers, pReserved);
Jon Ashburnf7a08742014-11-25 11:08:42 -0700787 return result;
788 } else
789 {
790 if (pOutLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL)
791 return XGL_ERROR_INVALID_POINTER;
792 // This layer compatible with all GPUs
793 *pOutLayerCount = 1;
Chia-I Wu1da4b9f2014-12-16 10:47:33 +0800794 strncpy((char *) pOutLayers[0], "MemTracker", maxStringSize);
Jon Ashburnf7a08742014-11-25 11:08:42 -0700795 return XGL_SUCCESS;
796 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700797}
798
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500799XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglQueueSubmit(XGL_QUEUE queue, uint32_t cmdBufferCount, const XGL_CMD_BUFFER* pCmdBuffers,
800 uint32_t memRefCount, const XGL_MEMORY_REF* pMemRefs, XGL_FENCE fence)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700801{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600802 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700803 // TODO : Need to track fence and clear mem references when fence clears
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500804 GLOBAL_CB_NODE* pCBNode = NULL;
805 uint64_t fenceId = addFenceNode(fence);
806 char str[1024];
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700807 sprintf(str, "In xglQueueSubmit(), checking %u cmdBuffers with %u memRefs", cmdBufferCount, memRefCount);
808 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, queue, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700809 printMemList();
810 printGlobalCB();
811 for (uint32_t i = 0; i < cmdBufferCount; i++) {
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500812 pCBNode = getGlobalCBNode(pCmdBuffers[i]);
813 pCBNode->fenceId = fenceId;
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700814 sprintf(str, "Verifying mem refs for CB %p", pCmdBuffers[i]);
815 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pCmdBuffers[i], 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700816 if (XGL_FALSE == validateCBMemRef(pCmdBuffers[i], memRefCount, pMemRefs)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700817 sprintf(str, "Unable to verify memory references for CB %p", (void*)pCmdBuffers[i]);
818 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, pCmdBuffers[i], 0, MEMTRACK_CB_MISSING_MEM_REF, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700819 }
820 }
821 printGlobalCB();
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600822 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500823 XGL_RESULT result = nextTable.QueueSubmit(queue, cmdBufferCount, pCmdBuffers, memRefCount, pMemRefs, getFenceFromId(fenceId));
Tobin Ehlis6663f492014-11-10 12:29:12 -0700824 return result;
825}
826
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600827XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglQueueSetGlobalMemReferences(XGL_QUEUE queue, uint32_t memRefCount, const XGL_MEMORY_REF* pMemRefs)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700828{
829 // TODO : Use global mem references as part of list checked on QueueSubmit above
830 XGL_RESULT result = nextTable.QueueSetGlobalMemReferences(queue, memRefCount, pMemRefs);
831 return result;
832}
833
Tobin Ehlis6663f492014-11-10 12:29:12 -0700834XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglAllocMemory(XGL_DEVICE device, const XGL_MEMORY_ALLOC_INFO* pAllocInfo, XGL_GPU_MEMORY* pMem)
835{
836 XGL_RESULT result = nextTable.AllocMemory(device, pAllocInfo, pMem);
837 // TODO : Track allocations and overall size here
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600838 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -0600839 insertGlobalMemObj(*pMem, pAllocInfo);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700840 printMemList();
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600841 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700842 return result;
843}
844
845XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglFreeMemory(XGL_GPU_MEMORY mem)
846{
Tobin Ehlisc0418f92014-11-25 14:47:20 -0700847 /* From spec : A memory object is freed by calling xglFreeMemory() when it is no longer needed. Before
848 * freeing a memory object, an application must ensure the memory object is unbound from
849 * all API objects referencing it and that it is not referenced by any queued command buffers
850 */
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600851 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700852 if (XGL_FALSE == freeMemNode(mem)) {
853 char str[1024];
854 sprintf(str, "Issue while freeing mem obj %p", (void*)mem);
855 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_FREE_MEM_ERROR, "MEM", str);
856 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700857 printMemList();
858 printObjList();
859 printGlobalCB();
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600860 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700861 XGL_RESULT result = nextTable.FreeMemory(mem);
862 return result;
863}
864
865XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglSetMemoryPriority(XGL_GPU_MEMORY mem, XGL_MEMORY_PRIORITY priority)
866{
867 // TODO : Update tracking for this alloc
868 // Make sure memory is not pinned, which can't have priority set
869 XGL_RESULT result = nextTable.SetMemoryPriority(mem, priority);
870 return result;
871}
872
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600873XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglMapMemory(XGL_GPU_MEMORY mem, XGL_FLAGS flags, void** ppData)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700874{
875 // TODO : Track when memory is mapped
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600876 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski95152dc2015-02-25 12:16:04 -0600877 GLOBAL_MEM_OBJ_NODE *pMemObj = getGlobalMemNode(mem);
878 if ((pMemObj->allocInfo.memProps & XGL_MEMORY_PROPERTY_CPU_VISIBLE_BIT) == 0) {
879 char str[1024];
880 sprintf(str, "Mapping Memory (%p) without XGL_MEMORY_PROPERTY_CPU_VISIBLE_BIT set", (void*)mem);
881 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_STATE, "MEM", str);
882 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600883 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700884 XGL_RESULT result = nextTable.MapMemory(mem, flags, ppData);
885 return result;
886}
887
888XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglUnmapMemory(XGL_GPU_MEMORY mem)
889{
890 // TODO : Track as memory gets unmapped, do we want to check what changed following map?
891 // Make sure that memory was ever mapped to begin with
892 XGL_RESULT result = nextTable.UnmapMemory(mem);
893 return result;
894}
895
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600896XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglPinSystemMemory(XGL_DEVICE device, const void* pSysMem, size_t memSize, XGL_GPU_MEMORY* pMem)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700897{
898 // TODO : Track this
899 // Verify that memory is actually pinnable
900 XGL_RESULT result = nextTable.PinSystemMemory(device, pSysMem, memSize, pMem);
901 return result;
902}
903
Tobin Ehlis6663f492014-11-10 12:29:12 -0700904XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglOpenSharedMemory(XGL_DEVICE device, const XGL_MEMORY_OPEN_INFO* pOpenInfo, XGL_GPU_MEMORY* pMem)
905{
906 // TODO : Track this
907 XGL_RESULT result = nextTable.OpenSharedMemory(device, pOpenInfo, pMem);
908 return result;
909}
910
Tobin Ehlis6663f492014-11-10 12:29:12 -0700911XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglOpenPeerMemory(XGL_DEVICE device, const XGL_PEER_MEMORY_OPEN_INFO* pOpenInfo, XGL_GPU_MEMORY* pMem)
912{
913 // TODO : Track this
914 XGL_RESULT result = nextTable.OpenPeerMemory(device, pOpenInfo, pMem);
915 return result;
916}
917
918XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglOpenPeerImage(XGL_DEVICE device, const XGL_PEER_IMAGE_OPEN_INFO* pOpenInfo, XGL_IMAGE* pImage, XGL_GPU_MEMORY* pMem)
919{
920 // TODO : Track this
921 XGL_RESULT result = nextTable.OpenPeerImage(device, pOpenInfo, pImage, pMem);
922 return result;
923}
924
925XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDestroyObject(XGL_OBJECT object)
926{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600927 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500928
Tobin Ehlisa98df732014-11-27 07:52:04 -0700929 // First check if this is a CmdBuffer
930 if (NULL != getGlobalCBNode((XGL_CMD_BUFFER)object)) {
931 deleteGlobalCBNode((XGL_CMD_BUFFER)object);
932 }
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500933
934 if (objectMap.find(object) != objectMap.end()) {
935 GLOBAL_OBJECT_NODE* pDelNode = objectMap[object];
936 if (pDelNode->pMemNode) {
Tobin Ehlisa98df732014-11-27 07:52:04 -0700937 // Wsi allocated Memory is tied to image object so clear the binding and free that memory automatically
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500938 if (0 == pDelNode->pMemNode->allocInfo.allocationSize) { // Wsi allocated memory has NULL allocInfo w/ 0 size
939 XGL_GPU_MEMORY memToFree = pDelNode->pMemNode->mem;
Tobin Ehlisa98df732014-11-27 07:52:04 -0700940 clearObjectBinding(object);
941 freeMemNode(memToFree);
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500942 } else {
Tobin Ehlisa98df732014-11-27 07:52:04 -0700943 char str[1024];
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500944 sprintf(str, "Destroying obj %p that is still bound to memory object %p\nYou should first clear binding by calling xglBindObjectMemory(%p, 0, XGL_NULL_HANDLE)", object, (void*)pDelNode->pMemNode->mem, object);
Tobin Ehlisa98df732014-11-27 07:52:04 -0700945 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_DESTROY_OBJECT_ERROR, "MEM", str);
946 // From the spec : If an object has previous memory binding, it is required to unbind memory from an API object before it is destroyed.
947 clearObjectBinding(object);
948 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700949 }
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500950 delete pDelNode;
951 objectMap.erase(object);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700952 }
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500953
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600954 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700955 XGL_RESULT result = nextTable.DestroyObject(object);
956 return result;
957}
958
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600959XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglGetObjectInfo(XGL_BASE_OBJECT object, XGL_OBJECT_INFO_TYPE infoType, size_t* pDataSize, void* pData)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700960{
961 // TODO : What to track here?
962 // Could potentially save returned mem requirements and validate values passed into BindObjectMemory for this object
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700963 // From spec : The only objects that are guaranteed to have no external memory requirements are devices, queues, command buffers, shaders and memory objects.
Tobin Ehlis6663f492014-11-10 12:29:12 -0700964 XGL_RESULT result = nextTable.GetObjectInfo(object, infoType, pDataSize, pData);
965 return result;
966}
967
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600968XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglBindObjectMemory(XGL_OBJECT object, uint32_t allocationIdx, XGL_GPU_MEMORY mem, XGL_GPU_SIZE offset)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700969{
Jon Ashburn9b6eae52015-01-15 10:39:19 -0700970 XGL_RESULT result = nextTable.BindObjectMemory(object, allocationIdx, mem, offset);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600971 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700972 // Track objects tied to memory
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700973 if (XGL_FALSE == updateObjectBinding(object, mem)) {
974 char str[1024];
975 sprintf(str, "Unable to set object %p binding to mem obj %p", (void*)object, (void*)mem);
976 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
977 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700978 printObjList();
979 printMemList();
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600980 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700981 return result;
982}
983
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -0700984XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateFence(XGL_DEVICE device, const XGL_FENCE_CREATE_INFO* pCreateInfo, XGL_FENCE* pFence)
985{
986 XGL_RESULT result = nextTable.CreateFence(device, pCreateInfo, pFence);
987 if (XGL_SUCCESS == result) {
988 loader_platform_thread_lock_mutex(&globalLock);
989 insertGlobalObjectNode(*pFence, pCreateInfo->sType, pCreateInfo, sizeof(XGL_FENCE_CREATE_INFO), "fence");
990 loader_platform_thread_unlock_mutex(&globalLock);
991 }
992 return result;
993}
994
995XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglGetFenceStatus(XGL_FENCE fence)
996{
997 XGL_RESULT result = nextTable.GetFenceStatus(fence);
998 if (XGL_SUCCESS == result) {
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500999 loader_platform_thread_lock_mutex(&globalLock);
1000 updateFenceTracking(fence);
1001 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001002 }
1003 return result;
1004}
1005
1006XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglWaitForFences(XGL_DEVICE device, uint32_t fenceCount, const XGL_FENCE* pFences, bool32_t waitAll, uint64_t timeout)
1007{
1008 XGL_RESULT result = nextTable.WaitForFences(device, fenceCount, pFences, waitAll, timeout);
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05001009 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001010 if (XGL_SUCCESS == result) {
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001011 if (waitAll) { // Clear all the fences
1012 for(uint32_t i = 0; i < fenceCount; i++) {
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05001013 updateFenceTracking(pFences[i]);
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001014 }
1015 }
1016 else { // Clear only completed fences
1017 for(uint32_t i = 0; i < fenceCount; i++) {
1018 if (XGL_SUCCESS == nextTable.GetFenceStatus(pFences[i])) {
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05001019 updateFenceTracking(pFences[i]);
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001020 }
1021 }
1022 }
1023 }
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05001024 loader_platform_thread_unlock_mutex(&globalLock);
1025 return result;
1026}
1027
1028XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglQueueWaitIdle(XGL_QUEUE queue)
1029{
1030 XGL_RESULT result = nextTable.QueueWaitIdle(queue);
1031 if (XGL_SUCCESS == result) {
1032 loader_platform_thread_lock_mutex(&globalLock);
1033 retireAllFences();
1034 loader_platform_thread_unlock_mutex(&globalLock);
1035 }
1036 return result;
1037}
1038
1039XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDeviceWaitIdle(XGL_DEVICE device)
1040{
1041 XGL_RESULT result = nextTable.DeviceWaitIdle(device);
1042 if (XGL_SUCCESS == result) {
1043 loader_platform_thread_lock_mutex(&globalLock);
1044 retireAllFences();
1045 loader_platform_thread_unlock_mutex(&globalLock);
1046 }
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001047 return result;
1048}
1049
Tobin Ehlis6663f492014-11-10 12:29:12 -07001050XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateEvent(XGL_DEVICE device, const XGL_EVENT_CREATE_INFO* pCreateInfo, XGL_EVENT* pEvent)
1051{
1052 XGL_RESULT result = nextTable.CreateEvent(device, pCreateInfo, pEvent);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001053 if (XGL_SUCCESS == result) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001054 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001055 insertGlobalObjectNode(*pEvent, pCreateInfo->sType, pCreateInfo, sizeof(XGL_EVENT_CREATE_INFO), "event");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001056 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001057 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001058 return result;
1059}
1060
Tobin Ehlis6663f492014-11-10 12:29:12 -07001061XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateQueryPool(XGL_DEVICE device, const XGL_QUERY_POOL_CREATE_INFO* pCreateInfo, XGL_QUERY_POOL* pQueryPool)
1062{
1063 XGL_RESULT result = nextTable.CreateQueryPool(device, pCreateInfo, pQueryPool);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001064 if (XGL_SUCCESS == result) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001065 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001066 insertGlobalObjectNode(*pQueryPool, pCreateInfo->sType, pCreateInfo, sizeof(XGL_QUERY_POOL_CREATE_INFO), "query_pool");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001067 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001068 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001069 return result;
1070}
1071
Tobin Ehlis7265e832015-01-19 08:42:29 -07001072XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateBuffer(XGL_DEVICE device, const XGL_BUFFER_CREATE_INFO* pCreateInfo, XGL_BUFFER* pBuffer)
1073{
1074 XGL_RESULT result = nextTable.CreateBuffer(device, pCreateInfo, pBuffer);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001075 if (XGL_SUCCESS == result) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001076 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001077 insertGlobalObjectNode(*pBuffer, pCreateInfo->sType, pCreateInfo, sizeof(XGL_BUFFER_CREATE_INFO), "buffer");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001078 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001079 }
Tobin Ehlis7265e832015-01-19 08:42:29 -07001080 return result;
1081}
1082
1083XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateBufferView(XGL_DEVICE device, const XGL_BUFFER_VIEW_CREATE_INFO* pCreateInfo, XGL_BUFFER_VIEW* pView)
1084{
1085 XGL_RESULT result = nextTable.CreateBufferView(device, pCreateInfo, pView);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001086 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001087 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001088 insertGlobalObjectNode(*pView, pCreateInfo->sType, pCreateInfo, sizeof(XGL_BUFFER_VIEW_CREATE_INFO), "buffer_view");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001089 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001090 }
Tobin Ehlis7265e832015-01-19 08:42:29 -07001091 return result;
1092}
1093
Tobin Ehlis6663f492014-11-10 12:29:12 -07001094XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateImage(XGL_DEVICE device, const XGL_IMAGE_CREATE_INFO* pCreateInfo, XGL_IMAGE* pImage)
1095{
1096 XGL_RESULT result = nextTable.CreateImage(device, pCreateInfo, pImage);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001097 if (XGL_SUCCESS == result) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001098 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001099 insertGlobalObjectNode(*pImage, pCreateInfo->sType, pCreateInfo, sizeof(XGL_IMAGE_CREATE_INFO), "image");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001100 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001101 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001102 return result;
1103}
1104
Tobin Ehlis6663f492014-11-10 12:29:12 -07001105XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateImageView(XGL_DEVICE device, const XGL_IMAGE_VIEW_CREATE_INFO* pCreateInfo, XGL_IMAGE_VIEW* pView)
1106{
1107 XGL_RESULT result = nextTable.CreateImageView(device, pCreateInfo, pView);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001108 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001109 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001110 insertGlobalObjectNode(*pView, pCreateInfo->sType, pCreateInfo, sizeof(XGL_IMAGE_VIEW_CREATE_INFO), "image_view");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001111 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001112 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001113 return result;
1114}
1115
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -05001116XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateColorAttachmentView(XGL_DEVICE device, const XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO* pCreateInfo,
1117 XGL_COLOR_ATTACHMENT_VIEW* pView)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001118{
1119 XGL_RESULT result = nextTable.CreateColorAttachmentView(device, pCreateInfo, pView);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001120 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001121 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001122 insertGlobalObjectNode(*pView, pCreateInfo->sType, pCreateInfo, sizeof(XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO), "color_attachment_view");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001123 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001124 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001125 return result;
1126}
1127
1128XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDepthStencilView(XGL_DEVICE device, const XGL_DEPTH_STENCIL_VIEW_CREATE_INFO* pCreateInfo, XGL_DEPTH_STENCIL_VIEW* pView)
1129{
1130 XGL_RESULT result = nextTable.CreateDepthStencilView(device, pCreateInfo, pView);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001131 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001132 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001133 insertGlobalObjectNode(*pView, pCreateInfo->sType, pCreateInfo, sizeof(XGL_DEPTH_STENCIL_VIEW_CREATE_INFO), "ds_view");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001134 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001135 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001136 return result;
1137}
1138
1139XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateShader(XGL_DEVICE device, const XGL_SHADER_CREATE_INFO* pCreateInfo, XGL_SHADER* pShader)
1140{
1141 XGL_RESULT result = nextTable.CreateShader(device, pCreateInfo, pShader);
1142 return result;
1143}
1144
1145XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateGraphicsPipeline(XGL_DEVICE device, const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo, XGL_PIPELINE* pPipeline)
1146{
1147 XGL_RESULT result = nextTable.CreateGraphicsPipeline(device, pCreateInfo, pPipeline);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001148 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001149 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001150 insertGlobalObjectNode(*pPipeline, pCreateInfo->sType, pCreateInfo, sizeof(XGL_GRAPHICS_PIPELINE_CREATE_INFO), "graphics_pipeline");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001151 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001152 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001153 return result;
1154}
1155
1156XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateComputePipeline(XGL_DEVICE device, const XGL_COMPUTE_PIPELINE_CREATE_INFO* pCreateInfo, XGL_PIPELINE* pPipeline)
1157{
1158 XGL_RESULT result = nextTable.CreateComputePipeline(device, pCreateInfo, pPipeline);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001159 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001160 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001161 insertGlobalObjectNode(*pPipeline, pCreateInfo->sType, pCreateInfo, sizeof(XGL_COMPUTE_PIPELINE_CREATE_INFO), "compute_pipeline");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001162 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001163 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001164 return result;
1165}
1166
Tobin Ehlis6663f492014-11-10 12:29:12 -07001167XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateSampler(XGL_DEVICE device, const XGL_SAMPLER_CREATE_INFO* pCreateInfo, XGL_SAMPLER* pSampler)
1168{
1169 XGL_RESULT result = nextTable.CreateSampler(device, pCreateInfo, pSampler);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001170 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001171 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001172 insertGlobalObjectNode(*pSampler, pCreateInfo->sType, pCreateInfo, sizeof(XGL_SAMPLER_CREATE_INFO), "sampler");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001173 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001174 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001175 return result;
1176}
1177
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -05001178XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDynamicViewportState(XGL_DEVICE device, const XGL_DYNAMIC_VP_STATE_CREATE_INFO* pCreateInfo,
1179 XGL_DYNAMIC_VP_STATE_OBJECT* pState)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001180{
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001181 XGL_RESULT result = nextTable.CreateDynamicViewportState(device, pCreateInfo, pState);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001182 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001183 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001184 insertGlobalObjectNode(*pState, pCreateInfo->sType, pCreateInfo, sizeof(XGL_DYNAMIC_VP_STATE_CREATE_INFO), "viewport_state");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001185 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001186 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001187 return result;
1188}
1189
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -05001190XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDynamicRasterState(XGL_DEVICE device, const XGL_DYNAMIC_RS_STATE_CREATE_INFO* pCreateInfo,
1191 XGL_DYNAMIC_RS_STATE_OBJECT* pState)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001192{
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001193 XGL_RESULT result = nextTable.CreateDynamicRasterState(device, pCreateInfo, pState);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001194 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001195 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001196 insertGlobalObjectNode(*pState, pCreateInfo->sType, pCreateInfo, sizeof(XGL_DYNAMIC_RS_STATE_CREATE_INFO), "raster_state");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001197 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001198 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001199 return result;
1200}
1201
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -05001202XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDynamicColorBlendState(XGL_DEVICE device, const XGL_DYNAMIC_CB_STATE_CREATE_INFO* pCreateInfo,
1203 XGL_DYNAMIC_CB_STATE_OBJECT* pState)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001204{
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001205 XGL_RESULT result = nextTable.CreateDynamicColorBlendState(device, pCreateInfo, pState);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001206 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001207 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001208 insertGlobalObjectNode(*pState, pCreateInfo->sType, pCreateInfo, sizeof(XGL_DYNAMIC_CB_STATE_CREATE_INFO), "cb_state");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001209 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001210 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001211 return result;
1212}
1213
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -05001214XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateDynamicDepthStencilState(XGL_DEVICE device, const XGL_DYNAMIC_DS_STATE_CREATE_INFO* pCreateInfo,
1215 XGL_DYNAMIC_DS_STATE_OBJECT* pState)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001216{
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001217 XGL_RESULT result = nextTable.CreateDynamicDepthStencilState(device, pCreateInfo, pState);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001218 if (result == XGL_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001219 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001220 insertGlobalObjectNode(*pState, pCreateInfo->sType, pCreateInfo, sizeof(XGL_DYNAMIC_DS_STATE_CREATE_INFO), "ds_state");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001221 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001222 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001223 return result;
1224}
1225
1226XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglCreateCommandBuffer(XGL_DEVICE device, const XGL_CMD_BUFFER_CREATE_INFO* pCreateInfo, XGL_CMD_BUFFER* pCmdBuffer)
1227{
1228 XGL_RESULT result = nextTable.CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
1229 // At time of cmd buffer creation, create global cmd buffer node for the returned cmd buffer
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001230 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001231 if (*pCmdBuffer)
1232 insertGlobalCB(*pCmdBuffer);
1233 printGlobalCB();
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001234 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001235 return result;
1236}
1237
Jon Ashburn86522372014-12-31 17:11:49 -07001238XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglBeginCommandBuffer(XGL_CMD_BUFFER cmdBuffer, const XGL_CMD_BUFFER_BEGIN_INFO* pBeginInfo)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001239{
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001240 // This implicitly resets the Cmd Buffer so make sure any fence is done and then clear memory references
1241 GLOBAL_CB_NODE* pCBTrav = getGlobalCBNode(cmdBuffer);
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05001242 if (pCBTrav && (!fenceRetired(pCBTrav->fenceId))) {
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001243 bool32_t cbDone = checkCBCompleted(cmdBuffer);
1244 if (XGL_FALSE == cbDone) {
1245 char str[1024];
1246 sprintf(str, "Calling xglBeginCommandBuffer() on active CB %p before it has completed. You must check CB flag before this call.", cmdBuffer);
1247 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_RESET_CB_WHILE_IN_FLIGHT, "MEM", str);
1248 }
1249 }
Jon Ashburn86522372014-12-31 17:11:49 -07001250 XGL_RESULT result = nextTable.BeginCommandBuffer(cmdBuffer, pBeginInfo);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001251 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001252 freeCBBindings(cmdBuffer);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001253 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001254 return result;
1255}
1256
1257XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglEndCommandBuffer(XGL_CMD_BUFFER cmdBuffer)
1258{
1259 // TODO : Anything to do here?
1260 XGL_RESULT result = nextTable.EndCommandBuffer(cmdBuffer);
1261 return result;
1262}
1263
1264XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglResetCommandBuffer(XGL_CMD_BUFFER cmdBuffer)
1265{
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001266 // Verify that CB is complete (not in-flight)
1267 GLOBAL_CB_NODE* pCBTrav = getGlobalCBNode(cmdBuffer);
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05001268 if (pCBTrav && (!fenceRetired(pCBTrav->fenceId))) {
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001269 bool32_t cbDone = checkCBCompleted(cmdBuffer);
1270 if (XGL_FALSE == cbDone) {
1271 char str[1024];
1272 sprintf(str, "Resetting CB %p before it has completed. You must check CB flag before calling xglResetCommandBuffer().", cmdBuffer);
1273 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_RESET_CB_WHILE_IN_FLIGHT, "MEM", str);
1274 }
1275 }
1276 // Clear memory references as this point.
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001277 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001278 freeCBBindings(cmdBuffer);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001279 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001280 XGL_RESULT result = nextTable.ResetCommandBuffer(cmdBuffer);
1281 return result;
1282}
1283// TODO : For any xglCmdBind* calls that include an object which has mem bound to it,
1284// need to account for that mem now having binding to given cmdBuffer
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001285XGL_LAYER_EXPORT void XGLAPI xglCmdBindPipeline(XGL_CMD_BUFFER cmdBuffer, XGL_PIPELINE_BIND_POINT pipelineBindPoint, XGL_PIPELINE pipeline)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001286{
Tobin Ehlisc145be82015-01-08 15:22:32 -07001287#if 0
1288 // TODO : If memory bound to pipeline, then need to tie that mem to cmdBuffer
1289 if (getPipeline(pipeline)) {
1290 GLOBAL_CB_NODE *pCBTrav = getGlobalCBNode(cmdBuffer);
1291 if (pCBTrav) {
1292 pCBTrav->pipelines[pipelineBindPoint] = pipeline;
1293 } else {
1294 char str[1024];
1295 sprintf(str, "Attempt to bind Pipeline %p to non-existant command buffer %p!", (void*)pipeline, cmdBuffer);
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001296 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_INVALID_CB, (char *) "DS", (char *) str);
Tobin Ehlisc145be82015-01-08 15:22:32 -07001297 }
1298 }
1299 else {
1300 char str[1024];
1301 sprintf(str, "Attempt to bind Pipeline %p that doesn't exist!", (void*)pipeline);
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001302 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, pipeline, 0, MEMTRACK_INVALID_OBJECT, (char *) "DS", (char *) str);
Tobin Ehlisc145be82015-01-08 15:22:32 -07001303 }
1304#endif
Tobin Ehlis6663f492014-11-10 12:29:12 -07001305 nextTable.CmdBindPipeline(cmdBuffer, pipelineBindPoint, pipeline);
1306}
1307
Tobin Ehlis7265e832015-01-19 08:42:29 -07001308XGL_LAYER_EXPORT void XGLAPI xglCmdBindDynamicStateObject(XGL_CMD_BUFFER cmdBuffer, XGL_STATE_BIND_POINT stateBindPoint, XGL_DYNAMIC_STATE_OBJECT state)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001309{
Tobin Ehlisc145be82015-01-08 15:22:32 -07001310 GLOBAL_OBJECT_NODE *pNode;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001311 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlisc145be82015-01-08 15:22:32 -07001312 GLOBAL_CB_NODE *pCmdBuf = getGlobalCBNode(cmdBuffer);
1313 if (!pCmdBuf) {
1314 char str[1024];
1315 sprintf(str, "Unable to find command buffer object %p, was it ever created?", (void*)cmdBuffer);
1316 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_INVALID_CB, "DD", str);
1317 }
1318 pNode = getGlobalObjectNode(state);
1319 if (!pNode) {
1320 char str[1024];
1321 sprintf(str, "Unable to find dynamic state object %p, was it ever created?", (void*)state);
1322 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, state, 0, MEMTRACK_INVALID_OBJECT, "DD", str);
1323 }
1324 pCmdBuf->pDynamicState[stateBindPoint] = pNode;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001325 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001326 nextTable.CmdBindDynamicStateObject(cmdBuffer, stateBindPoint, state);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001327}
1328
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -05001329XGL_LAYER_EXPORT void XGLAPI xglCmdBindDescriptorSet(XGL_CMD_BUFFER cmdBuffer, XGL_PIPELINE_BIND_POINT pipelineBindPoint,
1330 XGL_DESCRIPTOR_SET descriptorSet, const uint32_t* pUserData)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001331{
Tobin Ehlisc145be82015-01-08 15:22:32 -07001332 // TODO : Somewhere need to verify that all textures referenced by shaders in DS are in some type of *SHADER_READ* state
Tobin Ehlis7265e832015-01-19 08:42:29 -07001333 nextTable.CmdBindDescriptorSet(cmdBuffer, pipelineBindPoint, descriptorSet, pUserData);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001334}
1335
Tobin Ehlis7265e832015-01-19 08:42:29 -07001336XGL_LAYER_EXPORT void XGLAPI xglCmdBindVertexBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER buffer, XGL_GPU_SIZE offset, uint32_t binding)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001337{
Tobin Ehlis7265e832015-01-19 08:42:29 -07001338 nextTable.CmdBindVertexBuffer(cmdBuffer, buffer, offset, binding);
Chia-I Wu19156822015-01-05 13:42:56 +08001339}
1340
Tobin Ehlis7265e832015-01-19 08:42:29 -07001341XGL_LAYER_EXPORT void XGLAPI xglCmdBindIndexBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER buffer, XGL_GPU_SIZE offset, XGL_INDEX_TYPE indexType)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001342{
Tobin Ehlis7265e832015-01-19 08:42:29 -07001343 nextTable.CmdBindIndexBuffer(cmdBuffer, buffer, offset, indexType);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001344}
1345
Tobin Ehlis7265e832015-01-19 08:42:29 -07001346XGL_LAYER_EXPORT void XGLAPI xglCmdDrawIndirect(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER buffer, XGL_GPU_SIZE offset, uint32_t count, uint32_t stride)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001347{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001348 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001349 XGL_GPU_MEMORY mem = getMemBindingFromObject(buffer);
1350 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001351 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001352 sprintf(str, "In xglCmdDrawIndirect() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001353 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1354 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001355 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001356 nextTable.CmdDrawIndirect(cmdBuffer, buffer, offset, count, stride);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001357}
1358
Tobin Ehlis7265e832015-01-19 08:42:29 -07001359XGL_LAYER_EXPORT void XGLAPI xglCmdDrawIndexedIndirect(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER buffer, XGL_GPU_SIZE offset, uint32_t count, uint32_t stride)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001360{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001361 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001362 XGL_GPU_MEMORY mem = getMemBindingFromObject(buffer);
1363 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001364 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001365 sprintf(str, "In xglCmdDrawIndexedIndirect() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001366 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1367 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001368 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001369 nextTable.CmdDrawIndexedIndirect(cmdBuffer, buffer, offset, count, stride);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001370}
1371
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001372XGL_LAYER_EXPORT void XGLAPI xglCmdDispatchIndirect(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER buffer, XGL_GPU_SIZE offset)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001373{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001374 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001375 XGL_GPU_MEMORY mem = getMemBindingFromObject(buffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001376 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1377 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001378 sprintf(str, "In xglCmdDispatchIndirect() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001379 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1380 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001381 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001382 nextTable.CmdDispatchIndirect(cmdBuffer, buffer, offset);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001383}
1384
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -05001385XGL_LAYER_EXPORT void XGLAPI xglCmdCopyBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER srcBuffer, XGL_BUFFER destBuffer,
1386 uint32_t regionCount, const XGL_BUFFER_COPY* pRegions)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001387{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001388 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001389 XGL_GPU_MEMORY mem = getMemBindingFromObject(srcBuffer);
1390 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001391 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001392 sprintf(str, "In xglCmdCopyBuffer() call unable to update binding of srcBuffer %p to cmdBuffer %p", srcBuffer, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001393 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1394 }
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001395 mem = getMemBindingFromObject(destBuffer);
1396 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001397 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001398 sprintf(str, "In xglCmdCopyBuffer() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001399 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1400 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001401 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001402 nextTable.CmdCopyBuffer(cmdBuffer, srcBuffer, destBuffer, regionCount, pRegions);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001403}
1404
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -05001405XGL_LAYER_EXPORT void XGLAPI xglCmdCopyImage(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE srcImage, XGL_IMAGE destImage,
1406 uint32_t regionCount, const XGL_IMAGE_COPY* pRegions)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001407{
1408 // TODO : Each image will have mem mapping so track them
1409 nextTable.CmdCopyImage(cmdBuffer, srcImage, destImage, regionCount, pRegions);
1410}
1411
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -05001412XGL_LAYER_EXPORT void XGLAPI xglCmdCopyBufferToImage(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER srcBuffer, XGL_IMAGE destImage,
1413 uint32_t regionCount, const XGL_BUFFER_IMAGE_COPY* pRegions)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001414{
1415 // TODO : Track this
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001416 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001417 XGL_GPU_MEMORY mem = getMemBindingFromObject(destImage);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001418 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1419 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001420 sprintf(str, "In xglCmdCopyMemoryToImage() call unable to update binding of destImage buffer %p to cmdBuffer %p", destImage, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001421 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1422 }
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001423
1424 mem = getMemBindingFromObject(srcBuffer);
1425 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001426 char str[1024];
Tobin Ehlis7265e832015-01-19 08:42:29 -07001427 sprintf(str, "In xglCmdCopyMemoryToImage() call unable to update binding of srcBuffer %p to cmdBuffer %p", srcBuffer, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001428 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1429 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001430 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001431 nextTable.CmdCopyBufferToImage(cmdBuffer, srcBuffer, destImage, regionCount, pRegions);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001432}
1433
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -05001434XGL_LAYER_EXPORT void XGLAPI xglCmdCopyImageToBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE srcImage, XGL_BUFFER destBuffer,
1435 uint32_t regionCount, const XGL_BUFFER_IMAGE_COPY* pRegions)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001436{
1437 // TODO : Track this
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001438 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001439 XGL_GPU_MEMORY mem = getMemBindingFromObject(srcImage);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001440 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1441 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001442 sprintf(str, "In xglCmdCopyImageToMemory() call unable to update binding of srcImage buffer %p to cmdBuffer %p", srcImage, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001443 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1444 }
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001445 mem = getMemBindingFromObject(destBuffer);
1446 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001447 char str[1024];
Tobin Ehlis7265e832015-01-19 08:42:29 -07001448 sprintf(str, "In xglCmdCopyImageToMemory() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001449 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1450 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001451 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001452 nextTable.CmdCopyImageToBuffer(cmdBuffer, srcImage, destBuffer, regionCount, pRegions);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001453}
1454
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -05001455XGL_LAYER_EXPORT void XGLAPI xglCmdCloneImageData(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE srcImage, XGL_IMAGE_LAYOUT srcImageLayout,
1456 XGL_IMAGE destImage, XGL_IMAGE_LAYOUT destImageLayout)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001457{
1458 // TODO : Each image will have mem mapping so track them
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001459 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001460 XGL_GPU_MEMORY mem = getMemBindingFromObject(srcImage);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001461 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1462 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001463 sprintf(str, "In xglCmdCloneImageData() call unable to update binding of srcImage buffer %p to cmdBuffer %p", srcImage, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001464 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1465 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001466 mem = getMemBindingFromObject(destImage);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001467 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1468 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001469 sprintf(str, "In xglCmdCloneImageData() call unable to update binding of destImage buffer %p to cmdBuffer %p", destImage, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001470 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1471 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001472 loader_platform_thread_unlock_mutex(&globalLock);
Mike Stroyanfb80d5f2014-12-04 11:08:39 +00001473 nextTable.CmdCloneImageData(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001474}
1475
Tobin Ehlis7265e832015-01-19 08:42:29 -07001476XGL_LAYER_EXPORT void XGLAPI xglCmdUpdateBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER destBuffer, XGL_GPU_SIZE destOffset, XGL_GPU_SIZE dataSize, const uint32_t* pData)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001477{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001478 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001479 XGL_GPU_MEMORY mem = getMemBindingFromObject(destBuffer);
1480 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001481 char str[1024];
Tobin Ehlis7265e832015-01-19 08:42:29 -07001482 sprintf(str, "In xglCmdUpdateMemory() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001483 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1484 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001485 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001486 nextTable.CmdUpdateBuffer(cmdBuffer, destBuffer, destOffset, dataSize, pData);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001487}
1488
Tobin Ehlis7265e832015-01-19 08:42:29 -07001489XGL_LAYER_EXPORT void XGLAPI xglCmdFillBuffer(XGL_CMD_BUFFER cmdBuffer, XGL_BUFFER destBuffer, XGL_GPU_SIZE destOffset, XGL_GPU_SIZE fillSize, uint32_t data)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001490{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001491 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001492 XGL_GPU_MEMORY mem = getMemBindingFromObject(destBuffer);
1493 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001494 char str[1024];
Tobin Ehlis7265e832015-01-19 08:42:29 -07001495 sprintf(str, "In xglCmdFillMemory() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001496 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1497 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001498 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001499 nextTable.CmdFillBuffer(cmdBuffer, destBuffer, destOffset, fillSize, data);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001500}
1501
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -05001502XGL_LAYER_EXPORT void XGLAPI xglCmdClearColorImage(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE image, const float color[4],
1503 uint32_t rangeCount, const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001504{
Tobin Ehlisc145be82015-01-08 15:22:32 -07001505 // TODO : Verify memory is in XGL_IMAGE_STATE_CLEAR state
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001506 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001507 XGL_GPU_MEMORY mem = getMemBindingFromObject(image);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001508 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1509 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001510 sprintf(str, "In xglCmdClearColorImage() call unable to update binding of image buffer %p to cmdBuffer %p", image, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001511 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1512 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001513 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001514 nextTable.CmdClearColorImage(cmdBuffer, image, color, rangeCount, pRanges);
1515}
1516
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -05001517XGL_LAYER_EXPORT void XGLAPI xglCmdClearColorImageRaw(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE image, const uint32_t color[4],
1518 uint32_t rangeCount, const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001519{
Tobin Ehlisc145be82015-01-08 15:22:32 -07001520 // TODO : Verify memory is in XGL_IMAGE_STATE_CLEAR state
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001521 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001522 XGL_GPU_MEMORY mem = getMemBindingFromObject(image);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001523 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1524 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001525 sprintf(str, "In xglCmdClearColorImageRaw() call unable to update binding of image buffer %p to cmdBuffer %p", image, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001526 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1527 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001528 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001529 nextTable.CmdClearColorImageRaw(cmdBuffer, image, color, rangeCount, pRanges);
1530}
1531
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -05001532XGL_LAYER_EXPORT void XGLAPI xglCmdClearDepthStencil(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE image, float depth,
1533 uint32_t stencil, uint32_t rangeCount, const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001534{
Tobin Ehlisc145be82015-01-08 15:22:32 -07001535 // TODO : Verify memory is in XGL_IMAGE_STATE_CLEAR state
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001536 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001537 XGL_GPU_MEMORY mem = getMemBindingFromObject(image);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001538 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1539 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001540 sprintf(str, "In xglCmdClearDepthStencil() call unable to update binding of image buffer %p to cmdBuffer %p", image, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001541 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1542 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001543 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001544 nextTable.CmdClearDepthStencil(cmdBuffer, image, depth, stencil, rangeCount, pRanges);
1545}
1546
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -05001547XGL_LAYER_EXPORT void XGLAPI xglCmdResolveImage(XGL_CMD_BUFFER cmdBuffer, XGL_IMAGE srcImage, XGL_IMAGE destImage,
1548 uint32_t rectCount, const XGL_IMAGE_RESOLVE* pRects)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001549{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001550 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001551 XGL_GPU_MEMORY mem = getMemBindingFromObject(srcImage);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001552 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1553 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001554 sprintf(str, "In xglCmdResolveImage() call unable to update binding of srcImage buffer %p to cmdBuffer %p", srcImage, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001555 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1556 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001557 mem = getMemBindingFromObject(destImage);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001558 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1559 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001560 sprintf(str, "In xglCmdResolveImage() call unable to update binding of destImage buffer %p to cmdBuffer %p", destImage, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001561 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1562 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001563 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001564 nextTable.CmdResolveImage(cmdBuffer, srcImage, destImage, rectCount, pRects);
1565}
1566
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001567XGL_LAYER_EXPORT void XGLAPI xglCmdBeginQuery(XGL_CMD_BUFFER cmdBuffer, XGL_QUERY_POOL queryPool, uint32_t slot, XGL_FLAGS flags)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001568{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001569 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001570 XGL_GPU_MEMORY mem = getMemBindingFromObject(queryPool);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001571 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1572 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001573 sprintf(str, "In xglCmdBeginQuery() call unable to update binding of queryPool buffer %p to cmdBuffer %p", queryPool, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001574 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1575 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001576 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001577 nextTable.CmdBeginQuery(cmdBuffer, queryPool, slot, flags);
1578}
1579
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001580XGL_LAYER_EXPORT void XGLAPI xglCmdEndQuery(XGL_CMD_BUFFER cmdBuffer, XGL_QUERY_POOL queryPool, uint32_t slot)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001581{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001582 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001583 XGL_GPU_MEMORY mem = getMemBindingFromObject(queryPool);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001584 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1585 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001586 sprintf(str, "In xglCmdEndQuery() call unable to update binding of queryPool buffer %p to cmdBuffer %p", queryPool, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001587 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1588 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001589 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001590 nextTable.CmdEndQuery(cmdBuffer, queryPool, slot);
1591}
1592
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001593XGL_LAYER_EXPORT void XGLAPI xglCmdResetQueryPool(XGL_CMD_BUFFER cmdBuffer, XGL_QUERY_POOL queryPool, uint32_t startQuery, uint32_t queryCount)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001594{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001595 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001596 XGL_GPU_MEMORY mem = getMemBindingFromObject(queryPool);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001597 if (XGL_FALSE == updateCBBinding(cmdBuffer, mem)) {
1598 char str[1024];
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001599 sprintf(str, "In xglCmdResetQueryPool() call unable to update binding of queryPool buffer %p to cmdBuffer %p", queryPool, cmdBuffer);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001600 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1601 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001602 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001603 nextTable.CmdResetQueryPool(cmdBuffer, queryPool, startQuery, queryCount);
1604}
1605
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001606XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDbgRegisterMsgCallback(XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback, void* pUserData)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001607{
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001608 // This layer intercepts callbacks
1609 XGL_LAYER_DBG_FUNCTION_NODE *pNewDbgFuncNode = (XGL_LAYER_DBG_FUNCTION_NODE*)malloc(sizeof(XGL_LAYER_DBG_FUNCTION_NODE));
1610 if (!pNewDbgFuncNode)
1611 return XGL_ERROR_OUT_OF_MEMORY;
1612 pNewDbgFuncNode->pfnMsgCallback = pfnMsgCallback;
1613 pNewDbgFuncNode->pUserData = pUserData;
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -07001614 pNewDbgFuncNode->pNext = g_pDbgFunctionHead;
1615 g_pDbgFunctionHead = pNewDbgFuncNode;
Jon Ashburna8aa8372015-03-03 15:07:15 -07001616 // force callbacks if DebugAction hasn't been set already other than initial value
Courtney Goeltzenleuchter90d93202015-03-04 15:47:34 -07001617 if (g_actionIsDefault) {
Jon Ashburna8aa8372015-03-03 15:07:15 -07001618 g_debugAction = XGL_DBG_LAYER_ACTION_CALLBACK;
Courtney Goeltzenleuchter90d93202015-03-04 15:47:34 -07001619 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001620 XGL_RESULT result = nextTable.DbgRegisterMsgCallback(pfnMsgCallback, pUserData);
1621 return result;
1622}
1623
1624XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDbgUnregisterMsgCallback(XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback)
1625{
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -07001626 XGL_LAYER_DBG_FUNCTION_NODE *pTrav = g_pDbgFunctionHead;
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001627 XGL_LAYER_DBG_FUNCTION_NODE *pPrev = pTrav;
1628 while (pTrav) {
1629 if (pTrav->pfnMsgCallback == pfnMsgCallback) {
1630 pPrev->pNext = pTrav->pNext;
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -07001631 if (g_pDbgFunctionHead == pTrav)
1632 g_pDbgFunctionHead = pTrav->pNext;
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001633 free(pTrav);
1634 break;
1635 }
1636 pPrev = pTrav;
1637 pTrav = pTrav->pNext;
1638 }
Jon Ashburna8aa8372015-03-03 15:07:15 -07001639 if (g_pDbgFunctionHead == NULL)
1640 {
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -05001641 if (g_actionIsDefault) {
Jon Ashburna8aa8372015-03-03 15:07:15 -07001642 g_debugAction = XGL_DBG_LAYER_ACTION_LOG_MSG;
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -05001643 } else {
1644 g_debugAction = (XGL_LAYER_DBG_ACTION)(g_debugAction & ~((uint32_t)XGL_DBG_LAYER_ACTION_CALLBACK));
1645 }
Jon Ashburna8aa8372015-03-03 15:07:15 -07001646 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001647 XGL_RESULT result = nextTable.DbgUnregisterMsgCallback(pfnMsgCallback);
1648 return result;
1649}
1650
Jon Ashburn71c2b152015-03-02 16:51:38 -07001651#if !defined(WIN32)
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -05001652XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglWsiX11CreatePresentableImage(XGL_DEVICE device, const XGL_WSI_X11_PRESENTABLE_IMAGE_CREATE_INFO* pCreateInfo,
1653 XGL_IMAGE* pImage, XGL_GPU_MEMORY* pMem)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001654{
1655 XGL_RESULT result = nextTable.WsiX11CreatePresentableImage(device, pCreateInfo, pImage, pMem);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001656 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001657 if (XGL_SUCCESS == result) {
1658 // Add image object, then insert the new Mem Object and then bind it to created image
1659 insertGlobalObjectNode(*pImage, _XGL_STRUCTURE_TYPE_MAX_ENUM, pCreateInfo, sizeof(XGL_WSI_X11_PRESENTABLE_IMAGE_CREATE_INFO), "wsi_x11_image");
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001660 insertGlobalMemObj(*pMem, NULL);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001661 if (XGL_FALSE == updateObjectBinding(*pImage, *pMem)) {
1662 char str[1024];
1663 sprintf(str, "In xglWsiX11CreatePresentableImage(), unable to set image %p binding to mem obj %p", (void*)*pImage, (void*)*pMem);
1664 layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, *pImage, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1665 }
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001666 }
1667 printObjList();
1668 printMemList();
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001669 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001670 return result;
1671}
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05001672
1673XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglWsiX11QueuePresent(XGL_QUEUE queue, const XGL_WSI_X11_PRESENT_INFO* pPresentInfo, XGL_FENCE fence)
1674{
1675 loader_platform_thread_lock_mutex(&globalLock);
1676 addFenceNode(fence);
1677 char str[1024];
1678 sprintf(str, "In xglWsiX11QueuePresent(), checking queue %p for fence %p", queue, fence);
1679 layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, queue, 0, MEMTRACK_NONE, "MEM", str);
1680 loader_platform_thread_unlock_mutex(&globalLock);
1681 XGL_RESULT result = nextTable.WsiX11QueuePresent(queue, pPresentInfo, fence);
1682 return result;
1683}
Ian Elliott2d4ab1e2015-01-13 17:52:38 -07001684#endif // WIN32
Tobin Ehlis6663f492014-11-10 12:29:12 -07001685
Mark Lobodzinski17caf572015-01-29 08:55:56 -06001686XGL_LAYER_EXPORT void* XGLAPI xglGetProcAddr(XGL_PHYSICAL_GPU gpu, const char* funcName)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001687{
1688 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
Chia-I Wu4d11dcc2015-01-05 13:18:57 +08001689
Tobin Ehlis6663f492014-11-10 12:29:12 -07001690 if (gpu == NULL)
1691 return NULL;
1692 pCurObj = gpuw;
Ian Elliott2d4ab1e2015-01-13 17:52:38 -07001693 loader_platform_thread_once(&g_initOnce, initMemTracker);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001694
Jon Ashburn71c2b152015-03-02 16:51:38 -07001695 if (!strcmp(funcName, "xglGetProcAddr"))
1696 return (void *) xglGetProcAddr;
1697 if (!strcmp(funcName, "xglCreateDevice"))
1698 return (void*) xglCreateDevice;
1699 if (!strcmp(funcName, "xglDestroyDevice"))
1700 return (void*) xglDestroyDevice;
1701 if (!strcmp(funcName, "xglEnumerateLayers"))
1702 return (void*) xglEnumerateLayers;
1703 if (!strcmp(funcName, "xglQueueSubmit"))
1704 return (void*) xglQueueSubmit;
1705 if (!strcmp(funcName, "xglQueueSetGlobalMemReferences"))
1706 return (void*) xglQueueSetGlobalMemReferences;
1707 if (!strcmp(funcName, "xglAllocMemory"))
1708 return (void*) xglAllocMemory;
1709 if (!strcmp(funcName, "xglFreeMemory"))
1710 return (void*) xglFreeMemory;
1711 if (!strcmp(funcName, "xglSetMemoryPriority"))
1712 return (void*) xglSetMemoryPriority;
1713 if (!strcmp(funcName, "xglMapMemory"))
1714 return (void*) xglMapMemory;
1715 if (!strcmp(funcName, "xglUnmapMemory"))
1716 return (void*) xglUnmapMemory;
1717 if (!strcmp(funcName, "xglPinSystemMemory"))
1718 return (void*) xglPinSystemMemory;
1719 if (!strcmp(funcName, "xglOpenSharedMemory"))
1720 return (void*) xglOpenSharedMemory;
1721 if (!strcmp(funcName, "xglOpenPeerMemory"))
1722 return (void*) xglOpenPeerMemory;
1723 if (!strcmp(funcName, "xglOpenPeerImage"))
1724 return (void*) xglOpenPeerImage;
1725 if (!strcmp(funcName, "xglDestroyObject"))
1726 return (void*) xglDestroyObject;
1727 if (!strcmp(funcName, "xglGetObjectInfo"))
1728 return (void*) xglGetObjectInfo;
1729 if (!strcmp(funcName, "xglBindObjectMemory"))
1730 return (void*) xglBindObjectMemory;
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001731 if (!strcmp(funcName, "xglCreateFence"))
1732 return (void*) xglCreateFence;
1733 if (!strcmp(funcName, "xglGetFenceStatus"))
1734 return (void*) xglGetFenceStatus;
1735 if (!strcmp(funcName, "xglWaitForFences"))
1736 return (void*) xglWaitForFences;
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05001737 if (!strcmp(funcName, "xglQueueWaitIdle"))
1738 return (void*) xglQueueWaitIdle;
1739 if (!strcmp(funcName, "xglDeviceWaitIdle"))
1740 return (void*) xglDeviceWaitIdle;
Jon Ashburn71c2b152015-03-02 16:51:38 -07001741 if (!strcmp(funcName, "xglCreateEvent"))
1742 return (void*) xglCreateEvent;
1743 if (!strcmp(funcName, "xglCreateQueryPool"))
1744 return (void*) xglCreateQueryPool;
1745 if (!strcmp(funcName, "xglCreateBuffer"))
1746 return (void*) xglCreateBuffer;
1747 if (!strcmp(funcName, "xglCreateBufferView"))
1748 return (void*) xglCreateBufferView;
1749 if (!strcmp(funcName, "xglCreateImage"))
1750 return (void*) xglCreateImage;
1751 if (!strcmp(funcName, "xglCreateImageView"))
1752 return (void*) xglCreateImageView;
1753 if (!strcmp(funcName, "xglCreateColorAttachmentView"))
1754 return (void*) xglCreateColorAttachmentView;
1755 if (!strcmp(funcName, "xglCreateDepthStencilView"))
1756 return (void*) xglCreateDepthStencilView;
1757 if (!strcmp(funcName, "xglCreateShader"))
1758 return (void*) xglCreateShader;
1759 if (!strcmp(funcName, "xglCreateGraphicsPipeline"))
1760 return (void*) xglCreateGraphicsPipeline;
1761 if (!strcmp(funcName, "xglCreateComputePipeline"))
1762 return (void*) xglCreateComputePipeline;
1763 if (!strcmp(funcName, "xglCreateSampler"))
1764 return (void*) xglCreateSampler;
1765 if (!strcmp(funcName, "xglCreateDynamicViewportState"))
1766 return (void*) xglCreateDynamicViewportState;
1767 if (!strcmp(funcName, "xglCreateDynamicRasterState"))
1768 return (void*) xglCreateDynamicRasterState;
1769 if (!strcmp(funcName, "xglCreateDynamicColorBlendState"))
1770 return (void*) xglCreateDynamicColorBlendState;
1771 if (!strcmp(funcName, "xglCreateDynamicDepthStencilState"))
1772 return (void*) xglCreateDynamicDepthStencilState;
1773 if (!strcmp(funcName, "xglCreateCommandBuffer"))
1774 return (void*) xglCreateCommandBuffer;
1775 if (!strcmp(funcName, "xglBeginCommandBuffer"))
1776 return (void*) xglBeginCommandBuffer;
1777 if (!strcmp(funcName, "xglEndCommandBuffer"))
1778 return (void*) xglEndCommandBuffer;
1779 if (!strcmp(funcName, "xglResetCommandBuffer"))
1780 return (void*) xglResetCommandBuffer;
1781 if (!strcmp(funcName, "xglCmdBindPipeline"))
1782 return (void*) xglCmdBindPipeline;
1783 if (!strcmp(funcName, "xglCmdBindDynamicStateObject"))
1784 return (void*) xglCmdBindDynamicStateObject;
1785 if (!strcmp(funcName, "xglCmdBindDescriptorSet"))
1786 return (void*) xglCmdBindDescriptorSet;
1787 if (!strcmp(funcName, "xglCmdBindVertexBuffer"))
1788 return (void*) xglCmdBindVertexBuffer;
1789 if (!strcmp(funcName, "xglCmdBindIndexBuffer"))
1790 return (void*) xglCmdBindIndexBuffer;
1791 if (!strcmp(funcName, "xglCmdDrawIndirect"))
1792 return (void*) xglCmdDrawIndirect;
1793 if (!strcmp(funcName, "xglCmdDrawIndexedIndirect"))
1794 return (void*) xglCmdDrawIndexedIndirect;
1795 if (!strcmp(funcName, "xglCmdDispatchIndirect"))
1796 return (void*) xglCmdDispatchIndirect;
1797 if (!strcmp(funcName, "xglCmdCopyBuffer"))
1798 return (void*) xglCmdCopyBuffer;
1799 if (!strcmp(funcName, "xglCmdCopyImage"))
1800 return (void*) xglCmdCopyImage;
1801 if (!strcmp(funcName, "xglCmdCopyBufferToImage"))
1802 return (void*) xglCmdCopyBufferToImage;
1803 if (!strcmp(funcName, "xglCmdCopyImageToBuffer"))
1804 return (void*) xglCmdCopyImageToBuffer;
1805 if (!strcmp(funcName, "xglCmdCloneImageData"))
1806 return (void*) xglCmdCloneImageData;
1807 if (!strcmp(funcName, "xglCmdUpdateBuffer"))
1808 return (void*) xglCmdUpdateBuffer;
1809 if (!strcmp(funcName, "xglCmdFillBuffer"))
1810 return (void*) xglCmdFillBuffer;
1811 if (!strcmp(funcName, "xglCmdClearColorImage"))
1812 return (void*) xglCmdClearColorImage;
1813 if (!strcmp(funcName, "xglCmdClearColorImageRaw"))
1814 return (void*) xglCmdClearColorImageRaw;
1815 if (!strcmp(funcName, "xglCmdClearDepthStencil"))
1816 return (void*) xglCmdClearDepthStencil;
1817 if (!strcmp(funcName, "xglCmdResolveImage"))
1818 return (void*) xglCmdResolveImage;
1819 if (!strcmp(funcName, "xglCmdBeginQuery"))
1820 return (void*) xglCmdBeginQuery;
1821 if (!strcmp(funcName, "xglCmdEndQuery"))
1822 return (void*) xglCmdEndQuery;
1823 if (!strcmp(funcName, "xglCmdResetQueryPool"))
1824 return (void*) xglCmdResetQueryPool;
1825 if (!strcmp(funcName, "xglDbgRegisterMsgCallback"))
1826 return (void*) xglDbgRegisterMsgCallback;
1827 if (!strcmp(funcName, "xglDbgUnregisterMsgCallback"))
1828 return (void*) xglDbgUnregisterMsgCallback;
1829#if !defined(WIN32)
1830 if (!strcmp(funcName, "xglWsiX11CreatePresentableImage"))
1831 return (void*) xglWsiX11CreatePresentableImage;
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05001832 if (!strcmp(funcName, "xglWsiX11QueuePresent"))
1833 return (void*) xglWsiX11QueuePresent;
Jon Ashburn71c2b152015-03-02 16:51:38 -07001834#endif
Tobin Ehlis6663f492014-11-10 12:29:12 -07001835 else {
Tobin Ehlis6663f492014-11-10 12:29:12 -07001836 if (gpuw->pGPA == NULL)
1837 return NULL;
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -05001838 return gpuw->pGPA((XGL_PHYSICAL_GPU)gpuw->nextObject, funcName);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001839 }
1840}