RK3368 GPU: Rogue N Init.
[firefly-linux-kernel-4.4.55.git] / drivers / staging / imgtec / rogue / generated / rgxray_bridge / server_rgxray_bridge.c
1 /*************************************************************************/ /*!
2 @File
3 @Title          Server bridge for rgxray
4 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
5 @Description    Implements the server side of the bridge for rgxray
6 @License        Dual MIT/GPLv2
7
8 The contents of this file are subject to the MIT license as set out below.
9
10 Permission is hereby granted, free of charge, to any person obtaining a copy
11 of this software and associated documentation files (the "Software"), to deal
12 in the Software without restriction, including without limitation the rights
13 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 copies of the Software, and to permit persons to whom the Software is
15 furnished to do so, subject to the following conditions:
16
17 The above copyright notice and this permission notice shall be included in
18 all copies or substantial portions of the Software.
19
20 Alternatively, the contents of this file may be used under the terms of
21 the GNU General Public License Version 2 ("GPL") in which case the provisions
22 of GPL are applicable instead of those above.
23
24 If you wish to allow use of your version of this file only under the terms of
25 GPL, and not to allow others to use your version of this file under the terms
26 of the MIT license, indicate your decision by deleting the provisions above
27 and replace them with the notice and other provisions required by GPL as set
28 out in the file called "GPL-COPYING" included in this distribution. If you do
29 not delete the provisions above, a recipient may use your version of this file
30 under the terms of either the MIT license or GPL.
31
32 This License is also included in this distribution in the file called
33 "MIT-COPYING".
34
35 EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
36 PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
37 BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
38 PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
39 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
40 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
41 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
42 */ /**************************************************************************/
43
44 #include <stddef.h>
45 #include <asm/uaccess.h>
46
47 #include "img_defs.h"
48
49 #include "rgxray.h"
50 #include "devicemem_server.h"
51
52
53 #include "common_rgxray_bridge.h"
54
55 #include "allocmem.h"
56 #include "pvr_debug.h"
57 #include "connection_server.h"
58 #include "pvr_bridge.h"
59 #include "rgx_bridge.h"
60 #include "srvcore.h"
61 #include "handle.h"
62
63 #include <linux/slab.h>
64
65
66 #include "rgx_bvnc_defs_km.h"
67
68
69
70
71 /* ***************************************************************************
72  * Server-side bridge entry points
73  */
74  
75 static IMG_INT
76 PVRSRVBridgeRGXCreateRPMFreeList(IMG_UINT32 ui32DispatchTableEntry,
77                                           PVRSRV_BRIDGE_IN_RGXCREATERPMFREELIST *psRGXCreateRPMFreeListIN,
78                                           PVRSRV_BRIDGE_OUT_RGXCREATERPMFREELIST *psRGXCreateRPMFreeListOUT,
79                                          CONNECTION_DATA *psConnection)
80 {
81         IMG_HANDLE hRPMContext = psRGXCreateRPMFreeListIN->hRPMContext;
82         RGX_SERVER_RPM_CONTEXT * psRPMContextInt = NULL;
83         RGX_RPM_FREELIST * psCleanupCookieInt = NULL;
84
85
86         {
87                 PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevData(psConnection);
88
89                 /* Check that device supports the required feature */
90                 if ((psDeviceNode->pfnCheckDeviceFeature) &&
91                         !psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_RAY_TRACING_BIT_MASK))
92                 {
93                         psRGXCreateRPMFreeListOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
94
95                         goto RGXCreateRPMFreeList_exit;
96                 }
97         }
98
99
100
101
102
103         /* Lock over handle lookup. */
104         LockHandle();
105
106
107
108
109
110                                 {
111                                         /* Look up the address from the handle */
112                                         psRGXCreateRPMFreeListOUT->eError =
113                                                 PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
114                                                                                         (void **) &psRPMContextInt,
115                                                                                         hRPMContext,
116                                                                                         PVRSRV_HANDLE_TYPE_RGX_SERVER_RPM_CONTEXT,
117                                                                                         IMG_TRUE);
118                                         if(psRGXCreateRPMFreeListOUT->eError != PVRSRV_OK)
119                                         {
120                                                 UnlockHandle();
121                                                 goto RGXCreateRPMFreeList_exit;
122                                         }
123                                 }
124         /* Release now we have looked up handles. */
125         UnlockHandle();
126
127         psRGXCreateRPMFreeListOUT->eError =
128                 RGXCreateRPMFreeList(psConnection, OSGetDevData(psConnection),
129                                         psRPMContextInt,
130                                         psRGXCreateRPMFreeListIN->ui32InitFLPages,
131                                         psRGXCreateRPMFreeListIN->ui32GrowFLPages,
132                                         psRGXCreateRPMFreeListIN->sFreeListDevVAddr,
133                                         &psCleanupCookieInt,
134                                         &psRGXCreateRPMFreeListOUT->ui32HWFreeList,
135                                         psRGXCreateRPMFreeListIN->bIsExternal);
136         /* Exit early if bridged call fails */
137         if(psRGXCreateRPMFreeListOUT->eError != PVRSRV_OK)
138         {
139                 goto RGXCreateRPMFreeList_exit;
140         }
141
142         /* Lock over handle creation. */
143         LockHandle();
144
145
146
147
148
149         psRGXCreateRPMFreeListOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
150
151                                                         &psRGXCreateRPMFreeListOUT->hCleanupCookie,
152                                                         (void *) psCleanupCookieInt,
153                                                         PVRSRV_HANDLE_TYPE_RGX_RPM_FREELIST,
154                                                         PVRSRV_HANDLE_ALLOC_FLAG_NONE
155                                                         ,(PFN_HANDLE_RELEASE)&RGXDestroyRPMFreeList);
156         if (psRGXCreateRPMFreeListOUT->eError != PVRSRV_OK)
157         {
158                 UnlockHandle();
159                 goto RGXCreateRPMFreeList_exit;
160         }
161
162         /* Release now we have created handles. */
163         UnlockHandle();
164
165
166
167 RGXCreateRPMFreeList_exit:
168
169         /* Lock over handle lookup cleanup. */
170         LockHandle();
171
172
173
174
175
176
177                                 {
178                                         /* Unreference the previously looked up handle */
179                                                 if(psRPMContextInt)
180                                                 {
181                                                         PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
182                                                                                         hRPMContext,
183                                                                                         PVRSRV_HANDLE_TYPE_RGX_SERVER_RPM_CONTEXT);
184                                                 }
185                                 }
186         /* Release now we have cleaned up look up handles. */
187         UnlockHandle();
188
189         if (psRGXCreateRPMFreeListOUT->eError != PVRSRV_OK)
190         {
191                 if (psCleanupCookieInt)
192                 {
193                         RGXDestroyRPMFreeList(psCleanupCookieInt);
194                 }
195         }
196
197
198         return 0;
199 }
200
201
202 static IMG_INT
203 PVRSRVBridgeRGXDestroyRPMFreeList(IMG_UINT32 ui32DispatchTableEntry,
204                                           PVRSRV_BRIDGE_IN_RGXDESTROYRPMFREELIST *psRGXDestroyRPMFreeListIN,
205                                           PVRSRV_BRIDGE_OUT_RGXDESTROYRPMFREELIST *psRGXDestroyRPMFreeListOUT,
206                                          CONNECTION_DATA *psConnection)
207 {
208
209
210         {
211                 PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevData(psConnection);
212
213                 /* Check that device supports the required feature */
214                 if ((psDeviceNode->pfnCheckDeviceFeature) &&
215                         !psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_RAY_TRACING_BIT_MASK))
216                 {
217                         psRGXDestroyRPMFreeListOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
218
219                         goto RGXDestroyRPMFreeList_exit;
220                 }
221         }
222
223
224
225
226
227
228
229         /* Lock over handle destruction. */
230         LockHandle();
231
232
233
234
235
236         psRGXDestroyRPMFreeListOUT->eError =
237                 PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
238                                         (IMG_HANDLE) psRGXDestroyRPMFreeListIN->hCleanupCookie,
239                                         PVRSRV_HANDLE_TYPE_RGX_RPM_FREELIST);
240         if ((psRGXDestroyRPMFreeListOUT->eError != PVRSRV_OK) &&
241             (psRGXDestroyRPMFreeListOUT->eError != PVRSRV_ERROR_RETRY))
242         {
243                 PVR_DPF((PVR_DBG_ERROR,
244                         "PVRSRVBridgeRGXDestroyRPMFreeList: %s",
245                         PVRSRVGetErrorStringKM(psRGXDestroyRPMFreeListOUT->eError)));
246                 PVR_ASSERT(0);
247                 UnlockHandle();
248                 goto RGXDestroyRPMFreeList_exit;
249         }
250
251         /* Release now we have destroyed handles. */
252         UnlockHandle();
253
254
255
256 RGXDestroyRPMFreeList_exit:
257
258
259
260
261         return 0;
262 }
263
264
265 static IMG_INT
266 PVRSRVBridgeRGXCreateRPMContext(IMG_UINT32 ui32DispatchTableEntry,
267                                           PVRSRV_BRIDGE_IN_RGXCREATERPMCONTEXT *psRGXCreateRPMContextIN,
268                                           PVRSRV_BRIDGE_OUT_RGXCREATERPMCONTEXT *psRGXCreateRPMContextOUT,
269                                          CONNECTION_DATA *psConnection)
270 {
271         RGX_SERVER_RPM_CONTEXT * psCleanupCookieInt = NULL;
272         IMG_HANDLE hSceneHeap = psRGXCreateRPMContextIN->hSceneHeap;
273         DEVMEMINT_HEAP * psSceneHeapInt = NULL;
274         IMG_HANDLE hRPMPageTableHeap = psRGXCreateRPMContextIN->hRPMPageTableHeap;
275         DEVMEMINT_HEAP * psRPMPageTableHeapInt = NULL;
276         DEVMEM_MEMDESC * psHWMemDescInt = NULL;
277
278
279         {
280                 PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevData(psConnection);
281
282                 /* Check that device supports the required feature */
283                 if ((psDeviceNode->pfnCheckDeviceFeature) &&
284                         !psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_RAY_TRACING_BIT_MASK))
285                 {
286                         psRGXCreateRPMContextOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
287
288                         goto RGXCreateRPMContext_exit;
289                 }
290         }
291
292
293
294         psRGXCreateRPMContextOUT->hCleanupCookie = NULL;
295
296
297         /* Lock over handle lookup. */
298         LockHandle();
299
300
301
302
303
304                                 {
305                                         /* Look up the address from the handle */
306                                         psRGXCreateRPMContextOUT->eError =
307                                                 PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
308                                                                                         (void **) &psSceneHeapInt,
309                                                                                         hSceneHeap,
310                                                                                         PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP,
311                                                                                         IMG_TRUE);
312                                         if(psRGXCreateRPMContextOUT->eError != PVRSRV_OK)
313                                         {
314                                                 UnlockHandle();
315                                                 goto RGXCreateRPMContext_exit;
316                                         }
317                                 }
318
319
320
321
322
323                                 {
324                                         /* Look up the address from the handle */
325                                         psRGXCreateRPMContextOUT->eError =
326                                                 PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
327                                                                                         (void **) &psRPMPageTableHeapInt,
328                                                                                         hRPMPageTableHeap,
329                                                                                         PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP,
330                                                                                         IMG_TRUE);
331                                         if(psRGXCreateRPMContextOUT->eError != PVRSRV_OK)
332                                         {
333                                                 UnlockHandle();
334                                                 goto RGXCreateRPMContext_exit;
335                                         }
336                                 }
337         /* Release now we have looked up handles. */
338         UnlockHandle();
339
340         psRGXCreateRPMContextOUT->eError =
341                 RGXCreateRPMContext(psConnection, OSGetDevData(psConnection),
342                                         &psCleanupCookieInt,
343                                         psRGXCreateRPMContextIN->ui32TotalRPMPages,
344                                         psRGXCreateRPMContextIN->ui32Log2DopplerPageSize,
345                                         psRGXCreateRPMContextIN->sSceneMemoryBaseAddr,
346                                         psRGXCreateRPMContextIN->sDopplerHeapBaseAddr,
347                                         psSceneHeapInt,
348                                         psRGXCreateRPMContextIN->sRPMPageTableBaseAddr,
349                                         psRPMPageTableHeapInt,
350                                         &psHWMemDescInt,
351                                         &psRGXCreateRPMContextOUT->ui32HWFrameData);
352         /* Exit early if bridged call fails */
353         if(psRGXCreateRPMContextOUT->eError != PVRSRV_OK)
354         {
355                 goto RGXCreateRPMContext_exit;
356         }
357
358         /* Lock over handle creation. */
359         LockHandle();
360
361
362
363
364
365         psRGXCreateRPMContextOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
366
367                                                         &psRGXCreateRPMContextOUT->hCleanupCookie,
368                                                         (void *) psCleanupCookieInt,
369                                                         PVRSRV_HANDLE_TYPE_RGX_SERVER_RPM_CONTEXT,
370                                                         PVRSRV_HANDLE_ALLOC_FLAG_NONE
371                                                         ,(PFN_HANDLE_RELEASE)&RGXDestroyRPMContext);
372         if (psRGXCreateRPMContextOUT->eError != PVRSRV_OK)
373         {
374                 UnlockHandle();
375                 goto RGXCreateRPMContext_exit;
376         }
377
378
379
380
381
382
383         psRGXCreateRPMContextOUT->eError = PVRSRVAllocSubHandleUnlocked(psConnection->psHandleBase,
384
385                                                         &psRGXCreateRPMContextOUT->hHWMemDesc,
386                                                         (void *) psHWMemDescInt,
387                                                         PVRSRV_HANDLE_TYPE_RGX_FW_MEMDESC,
388                                                         PVRSRV_HANDLE_ALLOC_FLAG_NONE
389                                                         ,psRGXCreateRPMContextOUT->hCleanupCookie);
390         if (psRGXCreateRPMContextOUT->eError != PVRSRV_OK)
391         {
392                 UnlockHandle();
393                 goto RGXCreateRPMContext_exit;
394         }
395
396         /* Release now we have created handles. */
397         UnlockHandle();
398
399
400
401 RGXCreateRPMContext_exit:
402
403         /* Lock over handle lookup cleanup. */
404         LockHandle();
405
406
407
408
409
410
411                                 {
412                                         /* Unreference the previously looked up handle */
413                                                 if(psSceneHeapInt)
414                                                 {
415                                                         PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
416                                                                                         hSceneHeap,
417                                                                                         PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP);
418                                                 }
419                                 }
420
421
422
423
424
425                                 {
426                                         /* Unreference the previously looked up handle */
427                                                 if(psRPMPageTableHeapInt)
428                                                 {
429                                                         PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
430                                                                                         hRPMPageTableHeap,
431                                                                                         PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP);
432                                                 }
433                                 }
434         /* Release now we have cleaned up look up handles. */
435         UnlockHandle();
436
437         if (psRGXCreateRPMContextOUT->eError != PVRSRV_OK)
438         {
439                 /* Lock over handle creation cleanup. */
440                 LockHandle();
441                 if (psRGXCreateRPMContextOUT->hCleanupCookie)
442                 {
443
444
445                         PVRSRV_ERROR eError = PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
446                                                 (IMG_HANDLE) psRGXCreateRPMContextOUT->hCleanupCookie,
447                                                 PVRSRV_HANDLE_TYPE_RGX_SERVER_RPM_CONTEXT);
448                         if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))
449                         {
450                                 PVR_DPF((PVR_DBG_ERROR,
451                                         "PVRSRVBridgeRGXCreateRPMContext: %s",
452                                         PVRSRVGetErrorStringKM(eError)));
453                         }
454                         /* Releasing the handle should free/destroy/release the resource.
455                          * This should never fail... */
456                         PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY));
457
458                         /* Avoid freeing/destroying/releasing the resource a second time below */
459                         psCleanupCookieInt = NULL;
460                 }
461
462
463                 /* Release now we have cleaned up creation handles. */
464                 UnlockHandle();
465                 if (psCleanupCookieInt)
466                 {
467                         RGXDestroyRPMContext(psCleanupCookieInt);
468                 }
469         }
470
471
472         return 0;
473 }
474
475
476 static IMG_INT
477 PVRSRVBridgeRGXDestroyRPMContext(IMG_UINT32 ui32DispatchTableEntry,
478                                           PVRSRV_BRIDGE_IN_RGXDESTROYRPMCONTEXT *psRGXDestroyRPMContextIN,
479                                           PVRSRV_BRIDGE_OUT_RGXDESTROYRPMCONTEXT *psRGXDestroyRPMContextOUT,
480                                          CONNECTION_DATA *psConnection)
481 {
482
483
484         {
485                 PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevData(psConnection);
486
487                 /* Check that device supports the required feature */
488                 if ((psDeviceNode->pfnCheckDeviceFeature) &&
489                         !psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_RAY_TRACING_BIT_MASK))
490                 {
491                         psRGXDestroyRPMContextOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
492
493                         goto RGXDestroyRPMContext_exit;
494                 }
495         }
496
497
498
499
500
501
502
503         /* Lock over handle destruction. */
504         LockHandle();
505
506
507
508
509
510         psRGXDestroyRPMContextOUT->eError =
511                 PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
512                                         (IMG_HANDLE) psRGXDestroyRPMContextIN->hCleanupCookie,
513                                         PVRSRV_HANDLE_TYPE_RGX_SERVER_RPM_CONTEXT);
514         if ((psRGXDestroyRPMContextOUT->eError != PVRSRV_OK) &&
515             (psRGXDestroyRPMContextOUT->eError != PVRSRV_ERROR_RETRY))
516         {
517                 PVR_DPF((PVR_DBG_ERROR,
518                         "PVRSRVBridgeRGXDestroyRPMContext: %s",
519                         PVRSRVGetErrorStringKM(psRGXDestroyRPMContextOUT->eError)));
520                 PVR_ASSERT(0);
521                 UnlockHandle();
522                 goto RGXDestroyRPMContext_exit;
523         }
524
525         /* Release now we have destroyed handles. */
526         UnlockHandle();
527
528
529
530 RGXDestroyRPMContext_exit:
531
532
533
534
535         return 0;
536 }
537
538
539 static IMG_INT
540 PVRSRVBridgeRGXKickRS(IMG_UINT32 ui32DispatchTableEntry,
541                                           PVRSRV_BRIDGE_IN_RGXKICKRS *psRGXKickRSIN,
542                                           PVRSRV_BRIDGE_OUT_RGXKICKRS *psRGXKickRSOUT,
543                                          CONNECTION_DATA *psConnection)
544 {
545         IMG_HANDLE hRayContext = psRGXKickRSIN->hRayContext;
546         RGX_SERVER_RAY_CONTEXT * psRayContextInt = NULL;
547         SYNC_PRIMITIVE_BLOCK * *psClientFenceUFOSyncPrimBlockInt = NULL;
548         IMG_HANDLE *hClientFenceUFOSyncPrimBlockInt2 = NULL;
549         IMG_UINT32 *ui32ClientFenceSyncOffsetInt = NULL;
550         IMG_UINT32 *ui32ClientFenceValueInt = NULL;
551         SYNC_PRIMITIVE_BLOCK * *psClientUpdateUFOSyncPrimBlockInt = NULL;
552         IMG_HANDLE *hClientUpdateUFOSyncPrimBlockInt2 = NULL;
553         IMG_UINT32 *ui32ClientUpdateSyncOffsetInt = NULL;
554         IMG_UINT32 *ui32ClientUpdateValueInt = NULL;
555         IMG_UINT32 *ui32ServerSyncFlagsInt = NULL;
556         SERVER_SYNC_PRIMITIVE * *psServerSyncsInt = NULL;
557         IMG_HANDLE *hServerSyncsInt2 = NULL;
558         IMG_BYTE *psDMCmdInt = NULL;
559         IMG_BYTE *psFCDMCmdInt = NULL;
560
561         IMG_UINT32 ui32NextOffset = 0;
562         IMG_BYTE   *pArrayArgsBuffer = NULL;
563 #if !defined(INTEGRITY_OS)
564         IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
565 #endif
566
567         IMG_UINT32 ui32BufferSize = 
568                         (psRGXKickRSIN->ui32ClientFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *)) +
569                         (psRGXKickRSIN->ui32ClientFenceCount * sizeof(IMG_HANDLE)) +
570                         (psRGXKickRSIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) +
571                         (psRGXKickRSIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) +
572                         (psRGXKickRSIN->ui32ClientUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *)) +
573                         (psRGXKickRSIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) +
574                         (psRGXKickRSIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) +
575                         (psRGXKickRSIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) +
576                         (psRGXKickRSIN->ui32ServerSyncCount * sizeof(IMG_UINT32)) +
577                         (psRGXKickRSIN->ui32ServerSyncCount * sizeof(SERVER_SYNC_PRIMITIVE *)) +
578                         (psRGXKickRSIN->ui32ServerSyncCount * sizeof(IMG_HANDLE)) +
579                         (psRGXKickRSIN->ui32CmdSize * sizeof(IMG_BYTE)) +
580                         (psRGXKickRSIN->ui32FCCmdSize * sizeof(IMG_BYTE)) +
581                         0;
582
583         {
584                 PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevData(psConnection);
585
586                 /* Check that device supports the required feature */
587                 if ((psDeviceNode->pfnCheckDeviceFeature) &&
588                         !psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_RAY_TRACING_BIT_MASK))
589                 {
590                         psRGXKickRSOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
591
592                         goto RGXKickRS_exit;
593                 }
594         }
595
596
597
598
599         if (ui32BufferSize != 0)
600         {
601 #if !defined(INTEGRITY_OS)
602                 /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
603                 IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psRGXKickRSIN), sizeof(unsigned long));
604                 IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
605                         PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
606
607                 bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
608                 if (bHaveEnoughSpace)
609                 {
610                         IMG_BYTE *pInputBuffer = (IMG_BYTE *)psRGXKickRSIN;
611
612                         pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];           }
613                 else
614 #endif
615                 {
616                         pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
617
618                         if(!pArrayArgsBuffer)
619                         {
620                                 psRGXKickRSOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
621                                 goto RGXKickRS_exit;
622                         }
623                 }
624         }
625
626         if (psRGXKickRSIN->ui32ClientFenceCount != 0)
627         {
628                 psClientFenceUFOSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
629                 ui32NextOffset += psRGXKickRSIN->ui32ClientFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *);
630                 hClientFenceUFOSyncPrimBlockInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
631                 ui32NextOffset += psRGXKickRSIN->ui32ClientFenceCount * sizeof(IMG_HANDLE);
632         }
633
634                         /* Copy the data over */
635                         if (psRGXKickRSIN->ui32ClientFenceCount * sizeof(IMG_HANDLE) > 0)
636                         {
637                                 if ( OSCopyFromUser(NULL, hClientFenceUFOSyncPrimBlockInt2, psRGXKickRSIN->phClientFenceUFOSyncPrimBlock, psRGXKickRSIN->ui32ClientFenceCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
638                                 {
639                                         psRGXKickRSOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
640
641                                         goto RGXKickRS_exit;
642                                 }
643                         }
644         if (psRGXKickRSIN->ui32ClientFenceCount != 0)
645         {
646                 ui32ClientFenceSyncOffsetInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
647                 ui32NextOffset += psRGXKickRSIN->ui32ClientFenceCount * sizeof(IMG_UINT32);
648         }
649
650                         /* Copy the data over */
651                         if (psRGXKickRSIN->ui32ClientFenceCount * sizeof(IMG_UINT32) > 0)
652                         {
653                                 if ( OSCopyFromUser(NULL, ui32ClientFenceSyncOffsetInt, psRGXKickRSIN->pui32ClientFenceSyncOffset, psRGXKickRSIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
654                                 {
655                                         psRGXKickRSOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
656
657                                         goto RGXKickRS_exit;
658                                 }
659                         }
660         if (psRGXKickRSIN->ui32ClientFenceCount != 0)
661         {
662                 ui32ClientFenceValueInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
663                 ui32NextOffset += psRGXKickRSIN->ui32ClientFenceCount * sizeof(IMG_UINT32);
664         }
665
666                         /* Copy the data over */
667                         if (psRGXKickRSIN->ui32ClientFenceCount * sizeof(IMG_UINT32) > 0)
668                         {
669                                 if ( OSCopyFromUser(NULL, ui32ClientFenceValueInt, psRGXKickRSIN->pui32ClientFenceValue, psRGXKickRSIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
670                                 {
671                                         psRGXKickRSOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
672
673                                         goto RGXKickRS_exit;
674                                 }
675                         }
676         if (psRGXKickRSIN->ui32ClientUpdateCount != 0)
677         {
678                 psClientUpdateUFOSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
679                 ui32NextOffset += psRGXKickRSIN->ui32ClientUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *);
680                 hClientUpdateUFOSyncPrimBlockInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
681                 ui32NextOffset += psRGXKickRSIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE);
682         }
683
684                         /* Copy the data over */
685                         if (psRGXKickRSIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE) > 0)
686                         {
687                                 if ( OSCopyFromUser(NULL, hClientUpdateUFOSyncPrimBlockInt2, psRGXKickRSIN->phClientUpdateUFOSyncPrimBlock, psRGXKickRSIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
688                                 {
689                                         psRGXKickRSOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
690
691                                         goto RGXKickRS_exit;
692                                 }
693                         }
694         if (psRGXKickRSIN->ui32ClientUpdateCount != 0)
695         {
696                 ui32ClientUpdateSyncOffsetInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
697                 ui32NextOffset += psRGXKickRSIN->ui32ClientUpdateCount * sizeof(IMG_UINT32);
698         }
699
700                         /* Copy the data over */
701                         if (psRGXKickRSIN->ui32ClientUpdateCount * sizeof(IMG_UINT32) > 0)
702                         {
703                                 if ( OSCopyFromUser(NULL, ui32ClientUpdateSyncOffsetInt, psRGXKickRSIN->pui32ClientUpdateSyncOffset, psRGXKickRSIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
704                                 {
705                                         psRGXKickRSOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
706
707                                         goto RGXKickRS_exit;
708                                 }
709                         }
710         if (psRGXKickRSIN->ui32ClientUpdateCount != 0)
711         {
712                 ui32ClientUpdateValueInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
713                 ui32NextOffset += psRGXKickRSIN->ui32ClientUpdateCount * sizeof(IMG_UINT32);
714         }
715
716                         /* Copy the data over */
717                         if (psRGXKickRSIN->ui32ClientUpdateCount * sizeof(IMG_UINT32) > 0)
718                         {
719                                 if ( OSCopyFromUser(NULL, ui32ClientUpdateValueInt, psRGXKickRSIN->pui32ClientUpdateValue, psRGXKickRSIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
720                                 {
721                                         psRGXKickRSOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
722
723                                         goto RGXKickRS_exit;
724                                 }
725                         }
726         if (psRGXKickRSIN->ui32ServerSyncCount != 0)
727         {
728                 ui32ServerSyncFlagsInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
729                 ui32NextOffset += psRGXKickRSIN->ui32ServerSyncCount * sizeof(IMG_UINT32);
730         }
731
732                         /* Copy the data over */
733                         if (psRGXKickRSIN->ui32ServerSyncCount * sizeof(IMG_UINT32) > 0)
734                         {
735                                 if ( OSCopyFromUser(NULL, ui32ServerSyncFlagsInt, psRGXKickRSIN->pui32ServerSyncFlags, psRGXKickRSIN->ui32ServerSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
736                                 {
737                                         psRGXKickRSOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
738
739                                         goto RGXKickRS_exit;
740                                 }
741                         }
742         if (psRGXKickRSIN->ui32ServerSyncCount != 0)
743         {
744                 psServerSyncsInt = (SERVER_SYNC_PRIMITIVE **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
745                 ui32NextOffset += psRGXKickRSIN->ui32ServerSyncCount * sizeof(SERVER_SYNC_PRIMITIVE *);
746                 hServerSyncsInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
747                 ui32NextOffset += psRGXKickRSIN->ui32ServerSyncCount * sizeof(IMG_HANDLE);
748         }
749
750                         /* Copy the data over */
751                         if (psRGXKickRSIN->ui32ServerSyncCount * sizeof(IMG_HANDLE) > 0)
752                         {
753                                 if ( OSCopyFromUser(NULL, hServerSyncsInt2, psRGXKickRSIN->phServerSyncs, psRGXKickRSIN->ui32ServerSyncCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
754                                 {
755                                         psRGXKickRSOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
756
757                                         goto RGXKickRS_exit;
758                                 }
759                         }
760         if (psRGXKickRSIN->ui32CmdSize != 0)
761         {
762                 psDMCmdInt = (IMG_BYTE*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
763                 ui32NextOffset += psRGXKickRSIN->ui32CmdSize * sizeof(IMG_BYTE);
764         }
765
766                         /* Copy the data over */
767                         if (psRGXKickRSIN->ui32CmdSize * sizeof(IMG_BYTE) > 0)
768                         {
769                                 if ( OSCopyFromUser(NULL, psDMCmdInt, psRGXKickRSIN->psDMCmd, psRGXKickRSIN->ui32CmdSize * sizeof(IMG_BYTE)) != PVRSRV_OK )
770                                 {
771                                         psRGXKickRSOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
772
773                                         goto RGXKickRS_exit;
774                                 }
775                         }
776         if (psRGXKickRSIN->ui32FCCmdSize != 0)
777         {
778                 psFCDMCmdInt = (IMG_BYTE*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
779                 ui32NextOffset += psRGXKickRSIN->ui32FCCmdSize * sizeof(IMG_BYTE);
780         }
781
782                         /* Copy the data over */
783                         if (psRGXKickRSIN->ui32FCCmdSize * sizeof(IMG_BYTE) > 0)
784                         {
785                                 if ( OSCopyFromUser(NULL, psFCDMCmdInt, psRGXKickRSIN->psFCDMCmd, psRGXKickRSIN->ui32FCCmdSize * sizeof(IMG_BYTE)) != PVRSRV_OK )
786                                 {
787                                         psRGXKickRSOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
788
789                                         goto RGXKickRS_exit;
790                                 }
791                         }
792
793         /* Lock over handle lookup. */
794         LockHandle();
795
796
797
798
799
800                                 {
801                                         /* Look up the address from the handle */
802                                         psRGXKickRSOUT->eError =
803                                                 PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
804                                                                                         (void **) &psRayContextInt,
805                                                                                         hRayContext,
806                                                                                         PVRSRV_HANDLE_TYPE_RGX_SERVER_RAY_CONTEXT,
807                                                                                         IMG_TRUE);
808                                         if(psRGXKickRSOUT->eError != PVRSRV_OK)
809                                         {
810                                                 UnlockHandle();
811                                                 goto RGXKickRS_exit;
812                                         }
813                                 }
814
815
816
817
818
819         {
820                 IMG_UINT32 i;
821
822                 for (i=0;i<psRGXKickRSIN->ui32ClientFenceCount;i++)
823                 {
824                                 {
825                                         /* Look up the address from the handle */
826                                         psRGXKickRSOUT->eError =
827                                                 PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
828                                                                                         (void **) &psClientFenceUFOSyncPrimBlockInt[i],
829                                                                                         hClientFenceUFOSyncPrimBlockInt2[i],
830                                                                                         PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
831                                                                                         IMG_TRUE);
832                                         if(psRGXKickRSOUT->eError != PVRSRV_OK)
833                                         {
834                                                 UnlockHandle();
835                                                 goto RGXKickRS_exit;
836                                         }
837                                 }
838                 }
839         }
840
841
842
843
844
845         {
846                 IMG_UINT32 i;
847
848                 for (i=0;i<psRGXKickRSIN->ui32ClientUpdateCount;i++)
849                 {
850                                 {
851                                         /* Look up the address from the handle */
852                                         psRGXKickRSOUT->eError =
853                                                 PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
854                                                                                         (void **) &psClientUpdateUFOSyncPrimBlockInt[i],
855                                                                                         hClientUpdateUFOSyncPrimBlockInt2[i],
856                                                                                         PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
857                                                                                         IMG_TRUE);
858                                         if(psRGXKickRSOUT->eError != PVRSRV_OK)
859                                         {
860                                                 UnlockHandle();
861                                                 goto RGXKickRS_exit;
862                                         }
863                                 }
864                 }
865         }
866
867
868
869
870
871         {
872                 IMG_UINT32 i;
873
874                 for (i=0;i<psRGXKickRSIN->ui32ServerSyncCount;i++)
875                 {
876                                 {
877                                         /* Look up the address from the handle */
878                                         psRGXKickRSOUT->eError =
879                                                 PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
880                                                                                         (void **) &psServerSyncsInt[i],
881                                                                                         hServerSyncsInt2[i],
882                                                                                         PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE,
883                                                                                         IMG_TRUE);
884                                         if(psRGXKickRSOUT->eError != PVRSRV_OK)
885                                         {
886                                                 UnlockHandle();
887                                                 goto RGXKickRS_exit;
888                                         }
889                                 }
890                 }
891         }
892         /* Release now we have looked up handles. */
893         UnlockHandle();
894
895         psRGXKickRSOUT->eError =
896                 PVRSRVRGXKickRSKM(
897                                         psRayContextInt,
898                                         psRGXKickRSIN->ui32ClientCacheOpSeqNum,
899                                         psRGXKickRSIN->ui32ClientFenceCount,
900                                         psClientFenceUFOSyncPrimBlockInt,
901                                         ui32ClientFenceSyncOffsetInt,
902                                         ui32ClientFenceValueInt,
903                                         psRGXKickRSIN->ui32ClientUpdateCount,
904                                         psClientUpdateUFOSyncPrimBlockInt,
905                                         ui32ClientUpdateSyncOffsetInt,
906                                         ui32ClientUpdateValueInt,
907                                         psRGXKickRSIN->ui32ServerSyncCount,
908                                         ui32ServerSyncFlagsInt,
909                                         psServerSyncsInt,
910                                         psRGXKickRSIN->ui32CmdSize,
911                                         psDMCmdInt,
912                                         psRGXKickRSIN->ui32FCCmdSize,
913                                         psFCDMCmdInt,
914                                         psRGXKickRSIN->ui32FrameContext,
915                                         psRGXKickRSIN->ui32PDumpFlags,
916                                         psRGXKickRSIN->ui32ExtJobRef);
917
918
919
920
921 RGXKickRS_exit:
922
923         /* Lock over handle lookup cleanup. */
924         LockHandle();
925
926
927
928
929
930
931                                 {
932                                         /* Unreference the previously looked up handle */
933                                                 if(psRayContextInt)
934                                                 {
935                                                         PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
936                                                                                         hRayContext,
937                                                                                         PVRSRV_HANDLE_TYPE_RGX_SERVER_RAY_CONTEXT);
938                                                 }
939                                 }
940
941
942
943
944
945         {
946                 IMG_UINT32 i;
947
948                 for (i=0;i<psRGXKickRSIN->ui32ClientFenceCount;i++)
949                 {
950                                 {
951                                         /* Unreference the previously looked up handle */
952                                                 if(psClientFenceUFOSyncPrimBlockInt[i])
953                                                 {
954                                                         PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
955                                                                                         hClientFenceUFOSyncPrimBlockInt2[i],
956                                                                                         PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
957                                                 }
958                                 }
959                 }
960         }
961
962
963
964
965
966         {
967                 IMG_UINT32 i;
968
969                 for (i=0;i<psRGXKickRSIN->ui32ClientUpdateCount;i++)
970                 {
971                                 {
972                                         /* Unreference the previously looked up handle */
973                                                 if(psClientUpdateUFOSyncPrimBlockInt[i])
974                                                 {
975                                                         PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
976                                                                                         hClientUpdateUFOSyncPrimBlockInt2[i],
977                                                                                         PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
978                                                 }
979                                 }
980                 }
981         }
982
983
984
985
986
987         {
988                 IMG_UINT32 i;
989
990                 for (i=0;i<psRGXKickRSIN->ui32ServerSyncCount;i++)
991                 {
992                                 {
993                                         /* Unreference the previously looked up handle */
994                                                 if(psServerSyncsInt[i])
995                                                 {
996                                                         PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
997                                                                                         hServerSyncsInt2[i],
998                                                                                         PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
999                                                 }
1000                                 }
1001                 }
1002         }
1003         /* Release now we have cleaned up look up handles. */
1004         UnlockHandle();
1005
1006         /* Allocated space should be equal to the last updated offset */
1007         PVR_ASSERT(ui32BufferSize == ui32NextOffset);
1008
1009 #if defined(INTEGRITY_OS)
1010         if(pArrayArgsBuffer)
1011 #else
1012         if(!bHaveEnoughSpace && pArrayArgsBuffer)
1013 #endif
1014                 OSFreeMemNoStats(pArrayArgsBuffer);
1015
1016
1017         return 0;
1018 }
1019
1020
1021 static IMG_INT
1022 PVRSRVBridgeRGXKickVRDM(IMG_UINT32 ui32DispatchTableEntry,
1023                                           PVRSRV_BRIDGE_IN_RGXKICKVRDM *psRGXKickVRDMIN,
1024                                           PVRSRV_BRIDGE_OUT_RGXKICKVRDM *psRGXKickVRDMOUT,
1025                                          CONNECTION_DATA *psConnection)
1026 {
1027         IMG_HANDLE hRayContext = psRGXKickVRDMIN->hRayContext;
1028         RGX_SERVER_RAY_CONTEXT * psRayContextInt = NULL;
1029         SYNC_PRIMITIVE_BLOCK * *psClientFenceUFOSyncPrimBlockInt = NULL;
1030         IMG_HANDLE *hClientFenceUFOSyncPrimBlockInt2 = NULL;
1031         IMG_UINT32 *ui32ClientFenceSyncOffsetInt = NULL;
1032         IMG_UINT32 *ui32ClientFenceValueInt = NULL;
1033         SYNC_PRIMITIVE_BLOCK * *psClientUpdateUFOSyncPrimBlockInt = NULL;
1034         IMG_HANDLE *hClientUpdateUFOSyncPrimBlockInt2 = NULL;
1035         IMG_UINT32 *ui32ClientUpdateSyncOffsetInt = NULL;
1036         IMG_UINT32 *ui32ClientUpdateValueInt = NULL;
1037         IMG_UINT32 *ui32ServerSyncFlagsInt = NULL;
1038         SERVER_SYNC_PRIMITIVE * *psServerSyncsInt = NULL;
1039         IMG_HANDLE *hServerSyncsInt2 = NULL;
1040         IMG_BYTE *psDMCmdInt = NULL;
1041
1042         IMG_UINT32 ui32NextOffset = 0;
1043         IMG_BYTE   *pArrayArgsBuffer = NULL;
1044 #if !defined(INTEGRITY_OS)
1045         IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
1046 #endif
1047
1048         IMG_UINT32 ui32BufferSize = 
1049                         (psRGXKickVRDMIN->ui32ClientFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *)) +
1050                         (psRGXKickVRDMIN->ui32ClientFenceCount * sizeof(IMG_HANDLE)) +
1051                         (psRGXKickVRDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) +
1052                         (psRGXKickVRDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) +
1053                         (psRGXKickVRDMIN->ui32ClientUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *)) +
1054                         (psRGXKickVRDMIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) +
1055                         (psRGXKickVRDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) +
1056                         (psRGXKickVRDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) +
1057                         (psRGXKickVRDMIN->ui32ServerSyncCount * sizeof(IMG_UINT32)) +
1058                         (psRGXKickVRDMIN->ui32ServerSyncCount * sizeof(SERVER_SYNC_PRIMITIVE *)) +
1059                         (psRGXKickVRDMIN->ui32ServerSyncCount * sizeof(IMG_HANDLE)) +
1060                         (psRGXKickVRDMIN->ui32CmdSize * sizeof(IMG_BYTE)) +
1061                         0;
1062
1063         {
1064                 PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevData(psConnection);
1065
1066                 /* Check that device supports the required feature */
1067                 if ((psDeviceNode->pfnCheckDeviceFeature) &&
1068                         !psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_RAY_TRACING_BIT_MASK))
1069                 {
1070                         psRGXKickVRDMOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
1071
1072                         goto RGXKickVRDM_exit;
1073                 }
1074         }
1075
1076
1077
1078
1079         if (ui32BufferSize != 0)
1080         {
1081 #if !defined(INTEGRITY_OS)
1082                 /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
1083                 IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psRGXKickVRDMIN), sizeof(unsigned long));
1084                 IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
1085                         PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
1086
1087                 bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
1088                 if (bHaveEnoughSpace)
1089                 {
1090                         IMG_BYTE *pInputBuffer = (IMG_BYTE *)psRGXKickVRDMIN;
1091
1092                         pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];           }
1093                 else
1094 #endif
1095                 {
1096                         pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
1097
1098                         if(!pArrayArgsBuffer)
1099                         {
1100                                 psRGXKickVRDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1101                                 goto RGXKickVRDM_exit;
1102                         }
1103                 }
1104         }
1105
1106         if (psRGXKickVRDMIN->ui32ClientFenceCount != 0)
1107         {
1108                 psClientFenceUFOSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
1109                 ui32NextOffset += psRGXKickVRDMIN->ui32ClientFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *);
1110                 hClientFenceUFOSyncPrimBlockInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
1111                 ui32NextOffset += psRGXKickVRDMIN->ui32ClientFenceCount * sizeof(IMG_HANDLE);
1112         }
1113
1114                         /* Copy the data over */
1115                         if (psRGXKickVRDMIN->ui32ClientFenceCount * sizeof(IMG_HANDLE) > 0)
1116                         {
1117                                 if ( OSCopyFromUser(NULL, hClientFenceUFOSyncPrimBlockInt2, psRGXKickVRDMIN->phClientFenceUFOSyncPrimBlock, psRGXKickVRDMIN->ui32ClientFenceCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
1118                                 {
1119                                         psRGXKickVRDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
1120
1121                                         goto RGXKickVRDM_exit;
1122                                 }
1123                         }
1124         if (psRGXKickVRDMIN->ui32ClientFenceCount != 0)
1125         {
1126                 ui32ClientFenceSyncOffsetInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
1127                 ui32NextOffset += psRGXKickVRDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32);
1128         }
1129
1130                         /* Copy the data over */
1131                         if (psRGXKickVRDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32) > 0)
1132                         {
1133                                 if ( OSCopyFromUser(NULL, ui32ClientFenceSyncOffsetInt, psRGXKickVRDMIN->pui32ClientFenceSyncOffset, psRGXKickVRDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
1134                                 {
1135                                         psRGXKickVRDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
1136
1137                                         goto RGXKickVRDM_exit;
1138                                 }
1139                         }
1140         if (psRGXKickVRDMIN->ui32ClientFenceCount != 0)
1141         {
1142                 ui32ClientFenceValueInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
1143                 ui32NextOffset += psRGXKickVRDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32);
1144         }
1145
1146                         /* Copy the data over */
1147                         if (psRGXKickVRDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32) > 0)
1148                         {
1149                                 if ( OSCopyFromUser(NULL, ui32ClientFenceValueInt, psRGXKickVRDMIN->pui32ClientFenceValue, psRGXKickVRDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
1150                                 {
1151                                         psRGXKickVRDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
1152
1153                                         goto RGXKickVRDM_exit;
1154                                 }
1155                         }
1156         if (psRGXKickVRDMIN->ui32ClientUpdateCount != 0)
1157         {
1158                 psClientUpdateUFOSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
1159                 ui32NextOffset += psRGXKickVRDMIN->ui32ClientUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *);
1160                 hClientUpdateUFOSyncPrimBlockInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
1161                 ui32NextOffset += psRGXKickVRDMIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE);
1162         }
1163
1164                         /* Copy the data over */
1165                         if (psRGXKickVRDMIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE) > 0)
1166                         {
1167                                 if ( OSCopyFromUser(NULL, hClientUpdateUFOSyncPrimBlockInt2, psRGXKickVRDMIN->phClientUpdateUFOSyncPrimBlock, psRGXKickVRDMIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
1168                                 {
1169                                         psRGXKickVRDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
1170
1171                                         goto RGXKickVRDM_exit;
1172                                 }
1173                         }
1174         if (psRGXKickVRDMIN->ui32ClientUpdateCount != 0)
1175         {
1176                 ui32ClientUpdateSyncOffsetInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
1177                 ui32NextOffset += psRGXKickVRDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32);
1178         }
1179
1180                         /* Copy the data over */
1181                         if (psRGXKickVRDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32) > 0)
1182                         {
1183                                 if ( OSCopyFromUser(NULL, ui32ClientUpdateSyncOffsetInt, psRGXKickVRDMIN->pui32ClientUpdateSyncOffset, psRGXKickVRDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
1184                                 {
1185                                         psRGXKickVRDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
1186
1187                                         goto RGXKickVRDM_exit;
1188                                 }
1189                         }
1190         if (psRGXKickVRDMIN->ui32ClientUpdateCount != 0)
1191         {
1192                 ui32ClientUpdateValueInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
1193                 ui32NextOffset += psRGXKickVRDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32);
1194         }
1195
1196                         /* Copy the data over */
1197                         if (psRGXKickVRDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32) > 0)
1198                         {
1199                                 if ( OSCopyFromUser(NULL, ui32ClientUpdateValueInt, psRGXKickVRDMIN->pui32ClientUpdateValue, psRGXKickVRDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
1200                                 {
1201                                         psRGXKickVRDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
1202
1203                                         goto RGXKickVRDM_exit;
1204                                 }
1205                         }
1206         if (psRGXKickVRDMIN->ui32ServerSyncCount != 0)
1207         {
1208                 ui32ServerSyncFlagsInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
1209                 ui32NextOffset += psRGXKickVRDMIN->ui32ServerSyncCount * sizeof(IMG_UINT32);
1210         }
1211
1212                         /* Copy the data over */
1213                         if (psRGXKickVRDMIN->ui32ServerSyncCount * sizeof(IMG_UINT32) > 0)
1214                         {
1215                                 if ( OSCopyFromUser(NULL, ui32ServerSyncFlagsInt, psRGXKickVRDMIN->pui32ServerSyncFlags, psRGXKickVRDMIN->ui32ServerSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
1216                                 {
1217                                         psRGXKickVRDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
1218
1219                                         goto RGXKickVRDM_exit;
1220                                 }
1221                         }
1222         if (psRGXKickVRDMIN->ui32ServerSyncCount != 0)
1223         {
1224                 psServerSyncsInt = (SERVER_SYNC_PRIMITIVE **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
1225                 ui32NextOffset += psRGXKickVRDMIN->ui32ServerSyncCount * sizeof(SERVER_SYNC_PRIMITIVE *);
1226                 hServerSyncsInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
1227                 ui32NextOffset += psRGXKickVRDMIN->ui32ServerSyncCount * sizeof(IMG_HANDLE);
1228         }
1229
1230                         /* Copy the data over */
1231                         if (psRGXKickVRDMIN->ui32ServerSyncCount * sizeof(IMG_HANDLE) > 0)
1232                         {
1233                                 if ( OSCopyFromUser(NULL, hServerSyncsInt2, psRGXKickVRDMIN->phServerSyncs, psRGXKickVRDMIN->ui32ServerSyncCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
1234                                 {
1235                                         psRGXKickVRDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
1236
1237                                         goto RGXKickVRDM_exit;
1238                                 }
1239                         }
1240         if (psRGXKickVRDMIN->ui32CmdSize != 0)
1241         {
1242                 psDMCmdInt = (IMG_BYTE*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
1243                 ui32NextOffset += psRGXKickVRDMIN->ui32CmdSize * sizeof(IMG_BYTE);
1244         }
1245
1246                         /* Copy the data over */
1247                         if (psRGXKickVRDMIN->ui32CmdSize * sizeof(IMG_BYTE) > 0)
1248                         {
1249                                 if ( OSCopyFromUser(NULL, psDMCmdInt, psRGXKickVRDMIN->psDMCmd, psRGXKickVRDMIN->ui32CmdSize * sizeof(IMG_BYTE)) != PVRSRV_OK )
1250                                 {
1251                                         psRGXKickVRDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
1252
1253                                         goto RGXKickVRDM_exit;
1254                                 }
1255                         }
1256
1257         /* Lock over handle lookup. */
1258         LockHandle();
1259
1260
1261
1262
1263
1264                                 {
1265                                         /* Look up the address from the handle */
1266                                         psRGXKickVRDMOUT->eError =
1267                                                 PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
1268                                                                                         (void **) &psRayContextInt,
1269                                                                                         hRayContext,
1270                                                                                         PVRSRV_HANDLE_TYPE_RGX_SERVER_RAY_CONTEXT,
1271                                                                                         IMG_TRUE);
1272                                         if(psRGXKickVRDMOUT->eError != PVRSRV_OK)
1273                                         {
1274                                                 UnlockHandle();
1275                                                 goto RGXKickVRDM_exit;
1276                                         }
1277                                 }
1278
1279
1280
1281
1282
1283         {
1284                 IMG_UINT32 i;
1285
1286                 for (i=0;i<psRGXKickVRDMIN->ui32ClientFenceCount;i++)
1287                 {
1288                                 {
1289                                         /* Look up the address from the handle */
1290                                         psRGXKickVRDMOUT->eError =
1291                                                 PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
1292                                                                                         (void **) &psClientFenceUFOSyncPrimBlockInt[i],
1293                                                                                         hClientFenceUFOSyncPrimBlockInt2[i],
1294                                                                                         PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
1295                                                                                         IMG_TRUE);
1296                                         if(psRGXKickVRDMOUT->eError != PVRSRV_OK)
1297                                         {
1298                                                 UnlockHandle();
1299                                                 goto RGXKickVRDM_exit;
1300                                         }
1301                                 }
1302                 }
1303         }
1304
1305
1306
1307
1308
1309         {
1310                 IMG_UINT32 i;
1311
1312                 for (i=0;i<psRGXKickVRDMIN->ui32ClientUpdateCount;i++)
1313                 {
1314                                 {
1315                                         /* Look up the address from the handle */
1316                                         psRGXKickVRDMOUT->eError =
1317                                                 PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
1318                                                                                         (void **) &psClientUpdateUFOSyncPrimBlockInt[i],
1319                                                                                         hClientUpdateUFOSyncPrimBlockInt2[i],
1320                                                                                         PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
1321                                                                                         IMG_TRUE);
1322                                         if(psRGXKickVRDMOUT->eError != PVRSRV_OK)
1323                                         {
1324                                                 UnlockHandle();
1325                                                 goto RGXKickVRDM_exit;
1326                                         }
1327                                 }
1328                 }
1329         }
1330
1331
1332
1333
1334
1335         {
1336                 IMG_UINT32 i;
1337
1338                 for (i=0;i<psRGXKickVRDMIN->ui32ServerSyncCount;i++)
1339                 {
1340                                 {
1341                                         /* Look up the address from the handle */
1342                                         psRGXKickVRDMOUT->eError =
1343                                                 PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
1344                                                                                         (void **) &psServerSyncsInt[i],
1345                                                                                         hServerSyncsInt2[i],
1346                                                                                         PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE,
1347                                                                                         IMG_TRUE);
1348                                         if(psRGXKickVRDMOUT->eError != PVRSRV_OK)
1349                                         {
1350                                                 UnlockHandle();
1351                                                 goto RGXKickVRDM_exit;
1352                                         }
1353                                 }
1354                 }
1355         }
1356         /* Release now we have looked up handles. */
1357         UnlockHandle();
1358
1359         psRGXKickVRDMOUT->eError =
1360                 PVRSRVRGXKickVRDMKM(
1361                                         psRayContextInt,
1362                                         psRGXKickVRDMIN->ui32ClientCacheOpSeqNum,
1363                                         psRGXKickVRDMIN->ui32ClientFenceCount,
1364                                         psClientFenceUFOSyncPrimBlockInt,
1365                                         ui32ClientFenceSyncOffsetInt,
1366                                         ui32ClientFenceValueInt,
1367                                         psRGXKickVRDMIN->ui32ClientUpdateCount,
1368                                         psClientUpdateUFOSyncPrimBlockInt,
1369                                         ui32ClientUpdateSyncOffsetInt,
1370                                         ui32ClientUpdateValueInt,
1371                                         psRGXKickVRDMIN->ui32ServerSyncCount,
1372                                         ui32ServerSyncFlagsInt,
1373                                         psServerSyncsInt,
1374                                         psRGXKickVRDMIN->ui32CmdSize,
1375                                         psDMCmdInt,
1376                                         psRGXKickVRDMIN->ui32PDumpFlags,
1377                                         psRGXKickVRDMIN->ui32ExtJobRef);
1378
1379
1380
1381
1382 RGXKickVRDM_exit:
1383
1384         /* Lock over handle lookup cleanup. */
1385         LockHandle();
1386
1387
1388
1389
1390
1391
1392                                 {
1393                                         /* Unreference the previously looked up handle */
1394                                                 if(psRayContextInt)
1395                                                 {
1396                                                         PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
1397                                                                                         hRayContext,
1398                                                                                         PVRSRV_HANDLE_TYPE_RGX_SERVER_RAY_CONTEXT);
1399                                                 }
1400                                 }
1401
1402
1403
1404
1405
1406         {
1407                 IMG_UINT32 i;
1408
1409                 for (i=0;i<psRGXKickVRDMIN->ui32ClientFenceCount;i++)
1410                 {
1411                                 {
1412                                         /* Unreference the previously looked up handle */
1413                                                 if(psClientFenceUFOSyncPrimBlockInt[i])
1414                                                 {
1415                                                         PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
1416                                                                                         hClientFenceUFOSyncPrimBlockInt2[i],
1417                                                                                         PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
1418                                                 }
1419                                 }
1420                 }
1421         }
1422
1423
1424
1425
1426
1427         {
1428                 IMG_UINT32 i;
1429
1430                 for (i=0;i<psRGXKickVRDMIN->ui32ClientUpdateCount;i++)
1431                 {
1432                                 {
1433                                         /* Unreference the previously looked up handle */
1434                                                 if(psClientUpdateUFOSyncPrimBlockInt[i])
1435                                                 {
1436                                                         PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
1437                                                                                         hClientUpdateUFOSyncPrimBlockInt2[i],
1438                                                                                         PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
1439                                                 }
1440                                 }
1441                 }
1442         }
1443
1444
1445
1446
1447
1448         {
1449                 IMG_UINT32 i;
1450
1451                 for (i=0;i<psRGXKickVRDMIN->ui32ServerSyncCount;i++)
1452                 {
1453                                 {
1454                                         /* Unreference the previously looked up handle */
1455                                                 if(psServerSyncsInt[i])
1456                                                 {
1457                                                         PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
1458                                                                                         hServerSyncsInt2[i],
1459                                                                                         PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
1460                                                 }
1461                                 }
1462                 }
1463         }
1464         /* Release now we have cleaned up look up handles. */
1465         UnlockHandle();
1466
1467         /* Allocated space should be equal to the last updated offset */
1468         PVR_ASSERT(ui32BufferSize == ui32NextOffset);
1469
1470 #if defined(INTEGRITY_OS)
1471         if(pArrayArgsBuffer)
1472 #else
1473         if(!bHaveEnoughSpace && pArrayArgsBuffer)
1474 #endif
1475                 OSFreeMemNoStats(pArrayArgsBuffer);
1476
1477
1478         return 0;
1479 }
1480
1481
1482 static IMG_INT
1483 PVRSRVBridgeRGXCreateRayContext(IMG_UINT32 ui32DispatchTableEntry,
1484                                           PVRSRV_BRIDGE_IN_RGXCREATERAYCONTEXT *psRGXCreateRayContextIN,
1485                                           PVRSRV_BRIDGE_OUT_RGXCREATERAYCONTEXT *psRGXCreateRayContextOUT,
1486                                          CONNECTION_DATA *psConnection)
1487 {
1488         IMG_BYTE *psFrameworkCmdInt = NULL;
1489         IMG_HANDLE hPrivData = psRGXCreateRayContextIN->hPrivData;
1490         IMG_HANDLE hPrivDataInt = NULL;
1491         RGX_SERVER_RAY_CONTEXT * psRayContextInt = NULL;
1492
1493         IMG_UINT32 ui32NextOffset = 0;
1494         IMG_BYTE   *pArrayArgsBuffer = NULL;
1495 #if !defined(INTEGRITY_OS)
1496         IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
1497 #endif
1498
1499         IMG_UINT32 ui32BufferSize = 
1500                         (psRGXCreateRayContextIN->ui32FrameworkCmdSize * sizeof(IMG_BYTE)) +
1501                         0;
1502
1503         {
1504                 PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevData(psConnection);
1505
1506                 /* Check that device supports the required feature */
1507                 if ((psDeviceNode->pfnCheckDeviceFeature) &&
1508                         !psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_RAY_TRACING_BIT_MASK))
1509                 {
1510                         psRGXCreateRayContextOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
1511
1512                         goto RGXCreateRayContext_exit;
1513                 }
1514         }
1515
1516
1517
1518
1519         if (ui32BufferSize != 0)
1520         {
1521 #if !defined(INTEGRITY_OS)
1522                 /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
1523                 IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psRGXCreateRayContextIN), sizeof(unsigned long));
1524                 IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
1525                         PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
1526
1527                 bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
1528                 if (bHaveEnoughSpace)
1529                 {
1530                         IMG_BYTE *pInputBuffer = (IMG_BYTE *)psRGXCreateRayContextIN;
1531
1532                         pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];           }
1533                 else
1534 #endif
1535                 {
1536                         pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
1537
1538                         if(!pArrayArgsBuffer)
1539                         {
1540                                 psRGXCreateRayContextOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1541                                 goto RGXCreateRayContext_exit;
1542                         }
1543                 }
1544         }
1545
1546         if (psRGXCreateRayContextIN->ui32FrameworkCmdSize != 0)
1547         {
1548                 psFrameworkCmdInt = (IMG_BYTE*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
1549                 ui32NextOffset += psRGXCreateRayContextIN->ui32FrameworkCmdSize * sizeof(IMG_BYTE);
1550         }
1551
1552                         /* Copy the data over */
1553                         if (psRGXCreateRayContextIN->ui32FrameworkCmdSize * sizeof(IMG_BYTE) > 0)
1554                         {
1555                                 if ( OSCopyFromUser(NULL, psFrameworkCmdInt, psRGXCreateRayContextIN->psFrameworkCmd, psRGXCreateRayContextIN->ui32FrameworkCmdSize * sizeof(IMG_BYTE)) != PVRSRV_OK )
1556                                 {
1557                                         psRGXCreateRayContextOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
1558
1559                                         goto RGXCreateRayContext_exit;
1560                                 }
1561                         }
1562
1563         /* Lock over handle lookup. */
1564         LockHandle();
1565
1566
1567
1568
1569
1570                                 {
1571                                         /* Look up the address from the handle */
1572                                         psRGXCreateRayContextOUT->eError =
1573                                                 PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
1574                                                                                         (void **) &hPrivDataInt,
1575                                                                                         hPrivData,
1576                                                                                         PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA,
1577                                                                                         IMG_TRUE);
1578                                         if(psRGXCreateRayContextOUT->eError != PVRSRV_OK)
1579                                         {
1580                                                 UnlockHandle();
1581                                                 goto RGXCreateRayContext_exit;
1582                                         }
1583                                 }
1584         /* Release now we have looked up handles. */
1585         UnlockHandle();
1586
1587         psRGXCreateRayContextOUT->eError =
1588                 PVRSRVRGXCreateRayContextKM(psConnection, OSGetDevData(psConnection),
1589                                         psRGXCreateRayContextIN->ui32Priority,
1590                                         psRGXCreateRayContextIN->sMCUFenceAddr,
1591                                         psRGXCreateRayContextIN->sVRMCallStackAddr,
1592                                         psRGXCreateRayContextIN->ui32FrameworkCmdSize,
1593                                         psFrameworkCmdInt,
1594                                         hPrivDataInt,
1595                                         &psRayContextInt);
1596         /* Exit early if bridged call fails */
1597         if(psRGXCreateRayContextOUT->eError != PVRSRV_OK)
1598         {
1599                 goto RGXCreateRayContext_exit;
1600         }
1601
1602         /* Lock over handle creation. */
1603         LockHandle();
1604
1605
1606
1607
1608
1609         psRGXCreateRayContextOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
1610
1611                                                         &psRGXCreateRayContextOUT->hRayContext,
1612                                                         (void *) psRayContextInt,
1613                                                         PVRSRV_HANDLE_TYPE_RGX_SERVER_RAY_CONTEXT,
1614                                                         PVRSRV_HANDLE_ALLOC_FLAG_MULTI
1615                                                         ,(PFN_HANDLE_RELEASE)&PVRSRVRGXDestroyRayContextKM);
1616         if (psRGXCreateRayContextOUT->eError != PVRSRV_OK)
1617         {
1618                 UnlockHandle();
1619                 goto RGXCreateRayContext_exit;
1620         }
1621
1622         /* Release now we have created handles. */
1623         UnlockHandle();
1624
1625
1626
1627 RGXCreateRayContext_exit:
1628
1629         /* Lock over handle lookup cleanup. */
1630         LockHandle();
1631
1632
1633
1634
1635
1636
1637                                 {
1638                                         /* Unreference the previously looked up handle */
1639                                                 if(hPrivDataInt)
1640                                                 {
1641                                                         PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
1642                                                                                         hPrivData,
1643                                                                                         PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA);
1644                                                 }
1645                                 }
1646         /* Release now we have cleaned up look up handles. */
1647         UnlockHandle();
1648
1649         if (psRGXCreateRayContextOUT->eError != PVRSRV_OK)
1650         {
1651                 if (psRayContextInt)
1652                 {
1653                         PVRSRVRGXDestroyRayContextKM(psRayContextInt);
1654                 }
1655         }
1656
1657         /* Allocated space should be equal to the last updated offset */
1658         PVR_ASSERT(ui32BufferSize == ui32NextOffset);
1659
1660 #if defined(INTEGRITY_OS)
1661         if(pArrayArgsBuffer)
1662 #else
1663         if(!bHaveEnoughSpace && pArrayArgsBuffer)
1664 #endif
1665                 OSFreeMemNoStats(pArrayArgsBuffer);
1666
1667
1668         return 0;
1669 }
1670
1671
1672 static IMG_INT
1673 PVRSRVBridgeRGXDestroyRayContext(IMG_UINT32 ui32DispatchTableEntry,
1674                                           PVRSRV_BRIDGE_IN_RGXDESTROYRAYCONTEXT *psRGXDestroyRayContextIN,
1675                                           PVRSRV_BRIDGE_OUT_RGXDESTROYRAYCONTEXT *psRGXDestroyRayContextOUT,
1676                                          CONNECTION_DATA *psConnection)
1677 {
1678
1679
1680         {
1681                 PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevData(psConnection);
1682
1683                 /* Check that device supports the required feature */
1684                 if ((psDeviceNode->pfnCheckDeviceFeature) &&
1685                         !psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_RAY_TRACING_BIT_MASK))
1686                 {
1687                         psRGXDestroyRayContextOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
1688
1689                         goto RGXDestroyRayContext_exit;
1690                 }
1691         }
1692
1693
1694
1695
1696
1697
1698
1699         /* Lock over handle destruction. */
1700         LockHandle();
1701
1702
1703
1704
1705
1706         psRGXDestroyRayContextOUT->eError =
1707                 PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
1708                                         (IMG_HANDLE) psRGXDestroyRayContextIN->hRayContext,
1709                                         PVRSRV_HANDLE_TYPE_RGX_SERVER_RAY_CONTEXT);
1710         if ((psRGXDestroyRayContextOUT->eError != PVRSRV_OK) &&
1711             (psRGXDestroyRayContextOUT->eError != PVRSRV_ERROR_RETRY))
1712         {
1713                 PVR_DPF((PVR_DBG_ERROR,
1714                         "PVRSRVBridgeRGXDestroyRayContext: %s",
1715                         PVRSRVGetErrorStringKM(psRGXDestroyRayContextOUT->eError)));
1716                 PVR_ASSERT(0);
1717                 UnlockHandle();
1718                 goto RGXDestroyRayContext_exit;
1719         }
1720
1721         /* Release now we have destroyed handles. */
1722         UnlockHandle();
1723
1724
1725
1726 RGXDestroyRayContext_exit:
1727
1728
1729
1730
1731         return 0;
1732 }
1733
1734
1735 static IMG_INT
1736 PVRSRVBridgeRGXSetRayContextPriority(IMG_UINT32 ui32DispatchTableEntry,
1737                                           PVRSRV_BRIDGE_IN_RGXSETRAYCONTEXTPRIORITY *psRGXSetRayContextPriorityIN,
1738                                           PVRSRV_BRIDGE_OUT_RGXSETRAYCONTEXTPRIORITY *psRGXSetRayContextPriorityOUT,
1739                                          CONNECTION_DATA *psConnection)
1740 {
1741         IMG_HANDLE hRayContext = psRGXSetRayContextPriorityIN->hRayContext;
1742         RGX_SERVER_RAY_CONTEXT * psRayContextInt = NULL;
1743
1744
1745         {
1746                 PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevData(psConnection);
1747
1748                 /* Check that device supports the required feature */
1749                 if ((psDeviceNode->pfnCheckDeviceFeature) &&
1750                         !psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_RAY_TRACING_BIT_MASK))
1751                 {
1752                         psRGXSetRayContextPriorityOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
1753
1754                         goto RGXSetRayContextPriority_exit;
1755                 }
1756         }
1757
1758
1759
1760
1761
1762         /* Lock over handle lookup. */
1763         LockHandle();
1764
1765
1766
1767
1768
1769                                 {
1770                                         /* Look up the address from the handle */
1771                                         psRGXSetRayContextPriorityOUT->eError =
1772                                                 PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
1773                                                                                         (void **) &psRayContextInt,
1774                                                                                         hRayContext,
1775                                                                                         PVRSRV_HANDLE_TYPE_RGX_SERVER_RAY_CONTEXT,
1776                                                                                         IMG_TRUE);
1777                                         if(psRGXSetRayContextPriorityOUT->eError != PVRSRV_OK)
1778                                         {
1779                                                 UnlockHandle();
1780                                                 goto RGXSetRayContextPriority_exit;
1781                                         }
1782                                 }
1783         /* Release now we have looked up handles. */
1784         UnlockHandle();
1785
1786         psRGXSetRayContextPriorityOUT->eError =
1787                 PVRSRVRGXSetRayContextPriorityKM(psConnection, OSGetDevData(psConnection),
1788                                         psRayContextInt,
1789                                         psRGXSetRayContextPriorityIN->ui32Priority);
1790
1791
1792
1793
1794 RGXSetRayContextPriority_exit:
1795
1796         /* Lock over handle lookup cleanup. */
1797         LockHandle();
1798
1799
1800
1801
1802
1803
1804                                 {
1805                                         /* Unreference the previously looked up handle */
1806                                                 if(psRayContextInt)
1807                                                 {
1808                                                         PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
1809                                                                                         hRayContext,
1810                                                                                         PVRSRV_HANDLE_TYPE_RGX_SERVER_RAY_CONTEXT);
1811                                                 }
1812                                 }
1813         /* Release now we have cleaned up look up handles. */
1814         UnlockHandle();
1815
1816
1817         return 0;
1818 }
1819
1820
1821
1822
1823 /* *************************************************************************** 
1824  * Server bridge dispatch related glue 
1825  */
1826
1827 static IMG_BOOL bUseLock = IMG_TRUE;
1828
1829 PVRSRV_ERROR InitRGXRAYBridge(void);
1830 PVRSRV_ERROR DeinitRGXRAYBridge(void);
1831
1832 /*
1833  * Register all RGXRAY functions with services
1834  */
1835 PVRSRV_ERROR InitRGXRAYBridge(void)
1836 {
1837
1838         SetDispatchTableEntry(PVRSRV_BRIDGE_RGXRAY, PVRSRV_BRIDGE_RGXRAY_RGXCREATERPMFREELIST, PVRSRVBridgeRGXCreateRPMFreeList,
1839                                         NULL, bUseLock);
1840
1841         SetDispatchTableEntry(PVRSRV_BRIDGE_RGXRAY, PVRSRV_BRIDGE_RGXRAY_RGXDESTROYRPMFREELIST, PVRSRVBridgeRGXDestroyRPMFreeList,
1842                                         NULL, bUseLock);
1843
1844         SetDispatchTableEntry(PVRSRV_BRIDGE_RGXRAY, PVRSRV_BRIDGE_RGXRAY_RGXCREATERPMCONTEXT, PVRSRVBridgeRGXCreateRPMContext,
1845                                         NULL, bUseLock);
1846
1847         SetDispatchTableEntry(PVRSRV_BRIDGE_RGXRAY, PVRSRV_BRIDGE_RGXRAY_RGXDESTROYRPMCONTEXT, PVRSRVBridgeRGXDestroyRPMContext,
1848                                         NULL, bUseLock);
1849
1850         SetDispatchTableEntry(PVRSRV_BRIDGE_RGXRAY, PVRSRV_BRIDGE_RGXRAY_RGXKICKRS, PVRSRVBridgeRGXKickRS,
1851                                         NULL, bUseLock);
1852
1853         SetDispatchTableEntry(PVRSRV_BRIDGE_RGXRAY, PVRSRV_BRIDGE_RGXRAY_RGXKICKVRDM, PVRSRVBridgeRGXKickVRDM,
1854                                         NULL, bUseLock);
1855
1856         SetDispatchTableEntry(PVRSRV_BRIDGE_RGXRAY, PVRSRV_BRIDGE_RGXRAY_RGXCREATERAYCONTEXT, PVRSRVBridgeRGXCreateRayContext,
1857                                         NULL, bUseLock);
1858
1859         SetDispatchTableEntry(PVRSRV_BRIDGE_RGXRAY, PVRSRV_BRIDGE_RGXRAY_RGXDESTROYRAYCONTEXT, PVRSRVBridgeRGXDestroyRayContext,
1860                                         NULL, bUseLock);
1861
1862         SetDispatchTableEntry(PVRSRV_BRIDGE_RGXRAY, PVRSRV_BRIDGE_RGXRAY_RGXSETRAYCONTEXTPRIORITY, PVRSRVBridgeRGXSetRayContextPriority,
1863                                         NULL, bUseLock);
1864
1865
1866         return PVRSRV_OK;
1867 }
1868
1869 /*
1870  * Unregister all rgxray functions with services
1871  */
1872 PVRSRV_ERROR DeinitRGXRAYBridge(void)
1873 {
1874         return PVRSRV_OK;
1875 }