VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_glsl.c@ 57542

Last change on this file since 57542 was 53088, checked in by vboxsync, 10 years ago

Host 3D: reduce amount of debug logging.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 42.1 KB
Line 
1/* $Id: state_glsl.c 53088 2014-10-17 14:50:07Z vboxsync $ */
2
3/** @file
4 * VBox OpenGL: GLSL state tracking
5 */
6
7/*
8 * Copyright (C) 2009-2012 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19#include "state.h"
20#include "state/cr_statetypes.h"
21#include "state/cr_statefuncs.h"
22#include "state_internals.h"
23#include "cr_mem.h"
24#include "cr_string.h"
25
26static CRGLSLShader* crStateGetShaderObj(GLuint id)
27{
28 CRContext *g = GetCurrentContext();
29
30 if (!g)
31 {
32 crWarning("crStateGetShaderObj called without current ctx");
33 }
34
35 return !g ? NULL : (CRGLSLShader *) crHashtableSearch(g->glsl.shaders, id);
36}
37
38static CRGLSLProgram* crStateGetProgramObj(GLuint id)
39{
40 CRContext *g = GetCurrentContext();
41
42 if (!g)
43 {
44 crWarning("crStateGetProgramObj called without current ctx");
45 }
46
47 return !g ? NULL : (CRGLSLProgram *) crHashtableSearch(g->glsl.programs, id);
48}
49
50static void crStateFreeGLSLShader(void *data)
51{
52 CRGLSLShader* pShader = (CRGLSLShader *) data;
53
54 if (pShader->source)
55 crFree(pShader->source);
56
57 crFree(pShader);
58}
59
60#ifdef IN_GUEST
61static void crStateFreeProgramAttribsLocationCache(CRGLSLProgram* pProgram)
62{
63 if (pProgram->pAttribs) crFree(pProgram->pAttribs);
64
65 pProgram->pAttribs = NULL;
66 pProgram->cAttribs = 0;
67}
68#endif
69
70static void crStateFreeProgramAttribs(CRGLSLProgram* pProgram)
71{
72 GLuint i;
73
74 for (i=0; i<pProgram->activeState.cAttribs; ++i)
75 {
76 crFree(pProgram->activeState.pAttribs[i].name);
77 }
78
79 for (i=0; i<pProgram->currentState.cAttribs; ++i)
80 {
81 crFree(pProgram->currentState.pAttribs[i].name);
82 }
83
84 if (pProgram->activeState.pAttribs)
85 crFree(pProgram->activeState.pAttribs);
86
87 if (pProgram->currentState.pAttribs)
88 crFree(pProgram->currentState.pAttribs);
89
90#ifdef IN_GUEST
91 crStateFreeProgramAttribsLocationCache(pProgram);
92
93 pProgram->bAttribsSynced = GL_FALSE;
94#endif
95
96}
97
98static void crStateFreeProgramUniforms(CRGLSLProgram* pProgram)
99{
100 GLuint i;
101
102 for (i=0; i<pProgram->cUniforms; ++i)
103 {
104 if (pProgram->pUniforms[i].name) crFree(pProgram->pUniforms[i].name);
105 if (pProgram->pUniforms[i].data) crFree(pProgram->pUniforms[i].data);
106 }
107
108 if (pProgram->pUniforms) crFree(pProgram->pUniforms);
109
110 pProgram->pUniforms = NULL;
111 pProgram->cUniforms = 0;
112
113#ifdef IN_GUEST
114 pProgram->bUniformsSynced = GL_FALSE;
115#endif
116}
117
118static void crStateShaderDecRefCount(void *data)
119{
120 CRGLSLShader *pShader = (CRGLSLShader *) data;
121
122 CRASSERT(pShader->refCount>0);
123
124 pShader->refCount--;
125
126 if (0==pShader->refCount && pShader->deleted)
127 {
128 CRContext *g = GetCurrentContext();
129 crHashtableDelete(g->glsl.shaders, pShader->id, crStateFreeGLSLShader);
130 }
131}
132
133static void crStateFakeDecRefCountCB(unsigned long key, void *data1, void *data2)
134{
135 CRGLSLShader *pShader = (CRGLSLShader *) data1;
136 CRContext *ctx = (CRContext*) data2;
137 CRGLSLShader *pRealShader;
138 (void) key;
139
140 pRealShader = crStateGetShaderObj(pShader->id);
141
142 if (pRealShader)
143 {
144 crStateShaderDecRefCount(pRealShader);
145 }
146 else
147 {
148 crWarning("crStateFakeDecRefCountCB: NULL pRealShader");
149 }
150}
151
152static void crStateFreeGLSLProgram(void *data)
153{
154 CRGLSLProgram* pProgram = (CRGLSLProgram *) data;
155
156 crFreeHashtable(pProgram->currentState.attachedShaders, crStateShaderDecRefCount);
157
158 if (pProgram->activeState.attachedShaders)
159 {
160 CRContext *g = GetCurrentContext();
161 crHashtableWalk(pProgram->activeState.attachedShaders, crStateFakeDecRefCountCB, g);
162 crFreeHashtable(pProgram->activeState.attachedShaders, crStateFreeGLSLShader);
163 }
164
165 crStateFreeProgramAttribs(pProgram);
166
167 crStateFreeProgramUniforms(pProgram);
168
169 crFree(pProgram);
170}
171
172DECLEXPORT(void) STATE_APIENTRY crStateGLSLInit(CRContext *ctx)
173{
174 ctx->glsl.shaders = crAllocHashtable();
175 ctx->glsl.programs = crAllocHashtable();
176 ctx->glsl.activeProgram = NULL;
177 ctx->glsl.bResyncNeeded = GL_FALSE;
178
179 if (!ctx->glsl.shaders || !ctx->glsl.programs)
180 {
181 crWarning("crStateGLSLInit: Out of memory!");
182 return;
183 }
184}
185
186DECLEXPORT(void) STATE_APIENTRY crStateGLSLDestroy(CRContext *ctx)
187{
188 CRContext *g = GetCurrentContext();
189
190 /*@todo: hack to allow crStateFreeGLSLProgram to work correctly,
191 as the current context isn't the one being destroyed*/
192#ifdef CHROMIUM_THREADSAFE
193 CRASSERT(g != ctx);
194 VBoxTlsRefAddRef(ctx); /* <- this is a hack to avoid subsequent SetCurrentContext(g) do recursive Destroy for ctx */
195 if (g)
196 VBoxTlsRefAddRef(g); /* <- ensure the g is not destroyed by the following SetCurrentContext call */
197 SetCurrentContext(ctx);
198#else
199 __currentContext = ctx;
200#endif
201
202 crFreeHashtable(ctx->glsl.programs, crStateFreeGLSLProgram);
203 crFreeHashtable(ctx->glsl.shaders, crStateFreeGLSLShader);
204
205#ifdef CHROMIUM_THREADSAFE
206 SetCurrentContext(g);
207 if (g)
208 VBoxTlsRefRelease(g);
209 VBoxTlsRefRelease(ctx); /* <- restore back the cRefs (see above) */
210#else
211 __currentContext = g;
212#endif
213
214}
215
216DECLEXPORT(GLuint) STATE_APIENTRY crStateGetShaderHWID(GLuint id)
217{
218 CRGLSLShader *pShader = crStateGetShaderObj(id);
219#ifdef IN_GUEST
220 CRASSERT(!pShader || pShader->hwid == id);
221#endif
222 return pShader ? pShader->hwid : 0;
223}
224
225DECLEXPORT(GLuint) STATE_APIENTRY crStateGetProgramHWID(GLuint id)
226{
227 CRGLSLProgram *pProgram = crStateGetProgramObj(id);
228#ifdef IN_GUEST
229 CRASSERT(!pProgram || pProgram->hwid == id);
230#endif
231 return pProgram ? pProgram->hwid : 0;
232}
233
234static void crStateCheckShaderHWIDCB(unsigned long key, void *data1, void *data2)
235{
236 CRGLSLShader *pShader = (CRGLSLShader *) data1;
237 crCheckIDHWID_t *pParms = (crCheckIDHWID_t*) data2;
238 (void) key;
239
240 if (pShader->hwid==pParms->hwid)
241 pParms->id = pShader->id;
242}
243
244static void crStateCheckProgramHWIDCB(unsigned long key, void *data1, void *data2)
245{
246 CRGLSLProgram *pProgram = (CRGLSLProgram *) data1;
247 crCheckIDHWID_t *pParms = (crCheckIDHWID_t*) data2;
248 (void) key;
249
250 if (pProgram->hwid==pParms->hwid)
251 pParms->id = pProgram->id;
252}
253
254DECLEXPORT(GLuint) STATE_APIENTRY crStateGLSLShaderHWIDtoID(GLuint hwid)
255{
256 CRContext *g = GetCurrentContext();
257 crCheckIDHWID_t parms;
258
259 parms.id = hwid;
260 parms.hwid = hwid;
261
262 crHashtableWalk(g->glsl.shaders, crStateCheckShaderHWIDCB, &parms);
263 return parms.id;
264}
265
266DECLEXPORT(GLuint) STATE_APIENTRY crStateGLSLProgramHWIDtoID(GLuint hwid)
267{
268 CRContext *g = GetCurrentContext();
269 crCheckIDHWID_t parms;
270
271 parms.id = hwid;
272 parms.hwid = hwid;
273
274 crHashtableWalk(g->glsl.programs, crStateCheckProgramHWIDCB, &parms);
275 return parms.id;
276}
277
278DECLEXPORT(GLuint) STATE_APIENTRY crStateDeleteObjectARB( VBoxGLhandleARB obj )
279{
280 GLuint hwId = crStateGetProgramHWID(obj);
281 if (hwId)
282 {
283 crStateDeleteProgram(obj);
284 }
285 else
286 {
287 hwId = crStateGetShaderHWID(obj);
288 crStateDeleteShader(obj);
289 }
290 return hwId;
291}
292
293DECLEXPORT(GLuint) STATE_APIENTRY crStateCreateShader(GLuint hwid, GLenum type)
294{
295 CRGLSLShader *pShader;
296 CRContext *g = GetCurrentContext();
297 GLuint stateId = hwid;
298
299#ifdef IN_GUEST
300 CRASSERT(!crStateGetShaderObj(stateId));
301#else
302 /* the proogram and shader names must not intersect because DeleteObjectARB must distinguish between them
303 * see crStateDeleteObjectARB
304 * this is why use programs table for shader keys allocation */
305 stateId = crHashtableAllocKeys(g->glsl.programs, 1);
306 if (!stateId)
307 {
308 crWarning("failed to allocate program key");
309 return 0;
310 }
311
312 Assert((pShader = crStateGetShaderObj(stateId)) == NULL);
313#endif
314
315 pShader = (CRGLSLShader *) crAlloc(sizeof(*pShader));
316 if (!pShader)
317 {
318 crWarning("crStateCreateShader: Out of memory!");
319 return 0;
320 }
321
322 pShader->id = stateId;
323 pShader->hwid = hwid;
324 pShader->type = type;
325 pShader->source = NULL;
326 pShader->compiled = GL_FALSE;
327 pShader->deleted = GL_FALSE;
328 pShader->refCount = 0;
329
330 crHashtableAdd(g->glsl.shaders, stateId, pShader);
331
332 return stateId;
333}
334
335DECLEXPORT(GLuint) STATE_APIENTRY crStateCreateProgram(GLuint hwid)
336{
337 CRGLSLProgram *pProgram;
338 CRContext *g = GetCurrentContext();
339 GLuint stateId = hwid;
340
341#ifdef IN_GUEST
342 pProgram = crStateGetProgramObj(stateId);
343 if (pProgram)
344 {
345 crWarning("Program object %d already exists!", stateId);
346 crStateDeleteProgram(stateId);
347 CRASSERT(!crStateGetProgramObj(stateId));
348 }
349#else
350 stateId = crHashtableAllocKeys(g->glsl.programs, 1);
351 if (!stateId)
352 {
353 crWarning("failed to allocate program key");
354 return 0;
355 }
356#endif
357
358 pProgram = (CRGLSLProgram *) crAlloc(sizeof(*pProgram));
359 if (!pProgram)
360 {
361 crWarning("crStateCreateProgram: Out of memory!");
362 return 0;
363 }
364
365 pProgram->id = stateId;
366 pProgram->hwid = hwid;
367 pProgram->validated = GL_FALSE;
368 pProgram->linked = GL_FALSE;
369 pProgram->deleted = GL_FALSE;
370 pProgram->activeState.attachedShaders = NULL;
371 pProgram->currentState.attachedShaders = crAllocHashtable();
372
373 pProgram->activeState.cAttribs = 0;
374 pProgram->activeState.pAttribs = NULL;
375 pProgram->currentState.cAttribs = 0;
376 pProgram->currentState.pAttribs = NULL;
377
378 pProgram->pUniforms = NULL;
379 pProgram->cUniforms = 0;
380
381#ifdef IN_GUEST
382 pProgram->pAttribs = NULL;
383 pProgram->cAttribs = 0;
384
385 pProgram->bUniformsSynced = GL_FALSE;
386 pProgram->bAttribsSynced = GL_FALSE;
387#endif
388
389 crHashtableAdd(g->glsl.programs, stateId, pProgram);
390
391 return stateId;
392}
393
394DECLEXPORT(void) STATE_APIENTRY crStateCompileShader(GLuint shader)
395{
396 CRGLSLShader *pShader = crStateGetShaderObj(shader);
397 if (!pShader)
398 {
399 crWarning("Unknown shader %d", shader);
400 return;
401 }
402
403 pShader->compiled = GL_TRUE;
404}
405
406static void crStateDbgCheckNoProgramOfId(void *data)
407{
408 crError("Unexpected Program id");
409}
410
411DECLEXPORT(void) STATE_APIENTRY crStateDeleteShader(GLuint shader)
412{
413 CRGLSLShader *pShader = crStateGetShaderObj(shader);
414 if (!pShader)
415 {
416 crWarning("Unknown shader %d", shader);
417 return;
418 }
419
420 pShader->deleted = GL_TRUE;
421
422 if (0==pShader->refCount)
423 {
424 CRContext *g = GetCurrentContext();
425 crHashtableDelete(g->glsl.shaders, shader, crStateFreeGLSLShader);
426 /* since we use programs table for key allocation key allocation, we need to
427 * free the key in the programs table.
428 * See comment in crStateCreateShader */
429 crHashtableDelete(g->glsl.programs, shader, crStateDbgCheckNoProgramOfId);
430 }
431}
432
433DECLEXPORT(void) STATE_APIENTRY crStateAttachShader(GLuint program, GLuint shader)
434{
435 CRGLSLProgram *pProgram = crStateGetProgramObj(program);
436 CRGLSLShader *pShader;
437
438 if (!pProgram)
439 {
440 crWarning("Unknown program %d", program);
441 return;
442 }
443
444 if (crHashtableSearch(pProgram->currentState.attachedShaders, shader))
445 {
446 /*shader already attached to this program*/
447 return;
448 }
449
450 pShader = crStateGetShaderObj(shader);
451
452 if (!pShader)
453 {
454 crWarning("Unknown shader %d", shader);
455 return;
456 }
457
458 pShader->refCount++;
459
460 crHashtableAdd(pProgram->currentState.attachedShaders, shader, pShader);
461}
462
463DECLEXPORT(void) STATE_APIENTRY crStateDetachShader(GLuint program, GLuint shader)
464{
465 CRGLSLProgram *pProgram = crStateGetProgramObj(program);
466 CRGLSLShader *pShader;
467
468 if (!pProgram)
469 {
470 crWarning("Unknown program %d", program);
471 return;
472 }
473
474 pShader = (CRGLSLShader *) crHashtableSearch(pProgram->currentState.attachedShaders, shader);
475 if (!pShader)
476 {
477 crWarning("Shader %d isn't attached to program %d", shader, program);
478 return;
479 }
480
481 crHashtableDelete(pProgram->currentState.attachedShaders, shader, NULL);
482
483 CRASSERT(pShader->refCount>0);
484 pShader->refCount--;
485
486 if (0==pShader->refCount)
487 {
488 CRContext *g = GetCurrentContext();
489 crHashtableDelete(g->glsl.shaders, shader, crStateFreeGLSLShader);
490 }
491}
492
493DECLEXPORT(void) STATE_APIENTRY crStateUseProgram(GLuint program)
494{
495 CRContext *g = GetCurrentContext();
496
497 if (program>0)
498 {
499 CRGLSLProgram *pProgram = crStateGetProgramObj(program);
500
501 if (!pProgram)
502 {
503 crWarning("Unknown program %d", program);
504 return;
505 }
506
507 g->glsl.activeProgram = pProgram;
508 }
509 else
510 {
511 g->glsl.activeProgram = NULL;
512 }
513}
514
515DECLEXPORT(void) STATE_APIENTRY crStateDeleteProgram(GLuint program)
516{
517 CRContext *g = GetCurrentContext();
518 CRGLSLProgram *pProgram = crStateGetProgramObj(program);
519
520 if (!pProgram)
521 {
522 crWarning("Unknown program %d", program);
523 return;
524 }
525
526 if (g->glsl.activeProgram == pProgram)
527 {
528 g->glsl.activeProgram = NULL;
529 }
530
531 crHashtableDelete(g->glsl.programs, program, crStateFreeGLSLProgram);
532}
533
534DECLEXPORT(void) STATE_APIENTRY crStateValidateProgram(GLuint program)
535{
536 CRGLSLProgram *pProgram = crStateGetProgramObj(program);
537
538 if (!pProgram)
539 {
540 crWarning("Unknown program %d", program);
541 return;
542 }
543
544 pProgram->validated = GL_TRUE;
545}
546
547static void crStateCopyShaderCB(unsigned long key, void *data1, void *data2)
548{
549 CRGLSLShader *pRealShader = (CRGLSLShader *) data1;
550 CRGLSLProgram *pProgram = (CRGLSLProgram *) data2;
551 CRGLSLShader *pShader;
552 GLint sLen=0;
553
554 CRASSERT(pRealShader);
555 pRealShader->refCount++;
556
557 pShader = (CRGLSLShader *) crAlloc(sizeof(*pShader));
558 if (!pShader)
559 {
560 crWarning("crStateCopyShaderCB: Out of memory!");
561 return;
562 }
563
564 crMemcpy(pShader, pRealShader, sizeof(*pShader));
565
566 diff_api.GetShaderiv(pShader->hwid, GL_SHADER_SOURCE_LENGTH, &sLen);
567 if (sLen>0)
568 {
569 pShader->source = (GLchar*) crAlloc(sLen);
570 diff_api.GetShaderSource(pShader->hwid, sLen, NULL, pShader->source);
571 }
572
573 crHashtableAdd(pProgram->activeState.attachedShaders, key, pShader);
574}
575
576DECLEXPORT(void) STATE_APIENTRY crStateLinkProgram(GLuint program)
577{
578 CRGLSLProgram *pProgram = crStateGetProgramObj(program);
579 GLuint i;
580
581 if (!pProgram)
582 {
583 crWarning("Unknown program %d", program);
584 return;
585 }
586
587 pProgram->linked = GL_TRUE;
588
589 /*Free program's active state*/
590 if (pProgram->activeState.attachedShaders)
591 {
592 crHashtableWalk(pProgram->activeState.attachedShaders, crStateFakeDecRefCountCB, NULL);
593 crFreeHashtable(pProgram->activeState.attachedShaders, crStateFreeGLSLShader);
594 pProgram->activeState.attachedShaders = NULL;
595 }
596 for (i=0; i<pProgram->activeState.cAttribs; ++i)
597 {
598 crFree(pProgram->activeState.pAttribs[i].name);
599 }
600 if (pProgram->activeState.pAttribs) crFree(pProgram->activeState.pAttribs);
601
602 /*copy current state to active state*/
603 crMemcpy(&pProgram->activeState, &pProgram->currentState, sizeof(CRGLSLProgramState));
604
605 pProgram->activeState.attachedShaders = crAllocHashtable();
606 if (!pProgram->activeState.attachedShaders)
607 {
608 crWarning("crStateLinkProgram: Out of memory!");
609 return;
610 }
611 crHashtableWalk(pProgram->currentState.attachedShaders, crStateCopyShaderCB, pProgram);
612
613 /*that's not a bug, note the memcpy above*/
614 if (pProgram->activeState.pAttribs)
615 {
616 pProgram->activeState.pAttribs = (CRGLSLAttrib *) crAlloc(pProgram->activeState.cAttribs * sizeof(CRGLSLAttrib));
617 }
618
619 for (i=0; i<pProgram->activeState.cAttribs; ++i)
620 {
621 crMemcpy(&pProgram->activeState.pAttribs[i], &pProgram->currentState.pAttribs[i], sizeof(CRGLSLAttrib));
622 pProgram->activeState.pAttribs[i].name = crStrdup(pProgram->currentState.pAttribs[i].name);
623 }
624
625#ifdef IN_GUEST
626 crStateFreeProgramAttribsLocationCache(pProgram);
627#endif
628
629 crStateFreeProgramUniforms(pProgram);
630}
631
632DECLEXPORT(void) STATE_APIENTRY crStateBindAttribLocation(GLuint program, GLuint index, const char * name)
633{
634 CRGLSLProgram *pProgram = crStateGetProgramObj(program);
635 GLuint i;
636 CRGLSLAttrib *pAttribs;
637
638 if (!pProgram)
639 {
640 crWarning("Unknown program %d", program);
641 return;
642 }
643
644 if (index>=CR_MAX_VERTEX_ATTRIBS)
645 {
646 crWarning("crStateBindAttribLocation: Index too big %d", index);
647 return;
648 }
649
650 for (i=0; i<pProgram->currentState.cAttribs; ++i)
651 {
652 if (!crStrcmp(pProgram->currentState.pAttribs[i].name, name))
653 {
654 pProgram->currentState.pAttribs[i].index = index;
655 return;
656 }
657 }
658
659 pAttribs = (CRGLSLAttrib*) crAlloc((pProgram->currentState.cAttribs+1)*sizeof(CRGLSLAttrib));
660 if (!pAttribs)
661 {
662 crWarning("crStateBindAttribLocation: Out of memory!");
663 return;
664 }
665
666 if (pProgram->currentState.cAttribs)
667 {
668 crMemcpy(&pAttribs[0], &pProgram->currentState.pAttribs[0], pProgram->currentState.cAttribs*sizeof(CRGLSLAttrib));
669 }
670 pAttribs[pProgram->currentState.cAttribs].index = index;
671 pAttribs[pProgram->currentState.cAttribs].name = crStrdup(name);
672
673 pProgram->currentState.cAttribs++;
674 if (pProgram->currentState.pAttribs) crFree(pProgram->currentState.pAttribs);
675 pProgram->currentState.pAttribs = pAttribs;
676}
677
678DECLEXPORT(GLint) STATE_APIENTRY crStateGetUniformSize(GLenum type)
679{
680 GLint size;
681
682 switch (type)
683 {
684 case GL_FLOAT:
685 size = 1;
686 break;
687 case GL_FLOAT_VEC2:
688 size = 2;
689 break;
690 case GL_FLOAT_VEC3:
691 size = 3;
692 break;
693 case GL_FLOAT_VEC4:
694 size = 4;
695 break;
696 case GL_INT:
697 size = 1;
698 break;
699 case GL_INT_VEC2:
700 size = 2;
701 break;
702 case GL_INT_VEC3:
703 size = 3;
704 break;
705 case GL_INT_VEC4:
706 size = 4;
707 break;
708 case GL_BOOL:
709 size = 1;
710 break;
711 case GL_BOOL_VEC2:
712 size = 2;
713 break;
714 case GL_BOOL_VEC3:
715 size = 3;
716 break;
717 case GL_BOOL_VEC4:
718 size = 4;
719 break;
720 case GL_FLOAT_MAT2:
721 size = 8;
722 break;
723 case GL_FLOAT_MAT3:
724 size = 12;
725 break;
726 case GL_FLOAT_MAT4:
727 size = 16;
728 break;
729 case GL_SAMPLER_1D:
730 case GL_SAMPLER_2D:
731 case GL_SAMPLER_3D:
732 case GL_SAMPLER_CUBE:
733 case GL_SAMPLER_1D_SHADOW:
734 case GL_SAMPLER_2D_SHADOW:
735 case GL_SAMPLER_2D_RECT_ARB:
736 case GL_SAMPLER_2D_RECT_SHADOW_ARB:
737 size = 1;
738 break;
739#ifdef CR_OPENGL_VERSION_2_1
740 case GL_FLOAT_MAT2x3:
741 size = 8;
742 break;
743 case GL_FLOAT_MAT2x4:
744 size = 8;
745 break;
746 case GL_FLOAT_MAT3x2:
747 size = 12;
748 break;
749 case GL_FLOAT_MAT3x4:
750 size = 12;
751 break;
752 case GL_FLOAT_MAT4x2:
753 size = 16;
754 break;
755 case GL_FLOAT_MAT4x3:
756 size = 16;
757 break;
758#endif
759 default:
760 crWarning("crStateGetUniformSize: unknown uniform type 0x%x", (GLint)type);
761 size = 16;
762 break;
763 }
764
765 return size;
766}
767
768DECLEXPORT(GLboolean) STATE_APIENTRY crStateIsIntUniform(GLenum type)
769{
770 if (GL_INT==type
771 || GL_INT_VEC2==type
772 || GL_INT_VEC3==type
773 || GL_INT_VEC4==type
774 || GL_BOOL==type
775 || GL_BOOL_VEC2==type
776 || GL_BOOL_VEC3==type
777 || GL_BOOL_VEC4==type
778 || GL_SAMPLER_1D==type
779 || GL_SAMPLER_2D==type
780 || GL_SAMPLER_3D==type
781 || GL_SAMPLER_CUBE==type
782 || GL_SAMPLER_1D_SHADOW==type
783 || GL_SAMPLER_2D_SHADOW==type
784 || GL_SAMPLER_2D_RECT_ARB==type
785 || GL_SAMPLER_2D_RECT_SHADOW_ARB==type)
786 {
787 return GL_TRUE;
788 }
789 else return GL_FALSE;
790}
791
792DECLEXPORT(GLboolean) STATE_APIENTRY crStateIsProgramUniformsCached(GLuint program)
793{
794 CRGLSLProgram *pProgram = crStateGetProgramObj(program);
795
796 if (!pProgram)
797 {
798 WARN(("Unknown program %d", program));
799 return GL_FALSE;
800 }
801
802#ifdef IN_GUEST
803 return pProgram->bUniformsSynced;
804#else
805 WARN(("crStateIsProgramUniformsCached called on host side!!"));
806 return GL_FALSE;
807#endif
808}
809
810DECLEXPORT(GLboolean) STATE_APIENTRY crStateIsProgramAttribsCached(GLuint program)
811{
812 CRGLSLProgram *pProgram = crStateGetProgramObj(program);
813
814 if (!pProgram)
815 {
816 WARN(("Unknown program %d", program));
817 return GL_FALSE;
818 }
819
820#ifdef IN_GUEST
821 return pProgram->bAttribsSynced;
822#else
823 WARN(("crStateIsProgramAttribsCached called on host side!!"));
824 return GL_FALSE;
825#endif
826}
827
828/*@todo: one of those functions should ignore uniforms starting with "gl"*/
829
830#ifdef IN_GUEST
831DECLEXPORT(void) STATE_APIENTRY
832crStateGLSLProgramCacheUniforms(GLuint program, GLsizei cbData, GLvoid *pData)
833{
834 CRGLSLProgram *pProgram = crStateGetProgramObj(program);
835 char *pCurrent = pData;
836 GLsizei cbRead, cbName;
837 GLuint i;
838
839 if (!pProgram)
840 {
841 crWarning("Unknown program %d", program);
842 return;
843 }
844
845 if (pProgram->bUniformsSynced)
846 {
847 crWarning("crStateGLSLProgramCacheUniforms: this shouldn't happen!");
848 crStateFreeProgramUniforms(pProgram);
849 }
850
851 if (cbData<sizeof(GLsizei))
852 {
853 crWarning("crStateGLSLProgramCacheUniforms: data too short");
854 return;
855 }
856
857 pProgram->cUniforms = ((GLsizei*)pCurrent)[0];
858 pCurrent += sizeof(GLsizei);
859 cbRead = sizeof(GLsizei);
860
861 //crDebug("crStateGLSLProgramCacheUniforms: %i active uniforms", pProgram->cUniforms);
862
863 if (pProgram->cUniforms)
864 {
865 pProgram->pUniforms = crAlloc(pProgram->cUniforms*sizeof(CRGLSLUniform));
866 if (!pProgram->pUniforms)
867 {
868 crWarning("crStateGLSLProgramCacheUniforms: no memory");
869 pProgram->cUniforms = 0;
870 return;
871 }
872 }
873
874 for (i=0; i<pProgram->cUniforms; ++i)
875 {
876 cbRead += sizeof(GLuint)+sizeof(GLsizei);
877 if (cbRead>cbData)
878 {
879 crWarning("crStateGLSLProgramCacheUniforms: out of data reading uniform %i", i);
880 return;
881 }
882 pProgram->pUniforms[i].data = NULL;
883 pProgram->pUniforms[i].location = ((GLint*)pCurrent)[0];
884 pCurrent += sizeof(GLint);
885 cbName = ((GLsizei*)pCurrent)[0];
886 pCurrent += sizeof(GLsizei);
887
888 cbRead += cbName;
889 if (cbRead>cbData)
890 {
891 crWarning("crStateGLSLProgramCacheUniforms: out of data reading uniform's name %i", i);
892 return;
893 }
894
895 pProgram->pUniforms[i].name = crStrndup(pCurrent, cbName);
896 pCurrent += cbName;
897
898 //crDebug("crStateGLSLProgramCacheUniforms: uniform[%i]=%d, %s", i, pProgram->pUniforms[i].location, pProgram->pUniforms[i].name);
899 }
900
901 pProgram->bUniformsSynced = GL_TRUE;
902
903 CRASSERT((pCurrent-((char*)pData))==cbRead);
904 CRASSERT(cbRead==cbData);
905}
906
907DECLEXPORT(void) STATE_APIENTRY
908crStateGLSLProgramCacheAttribs(GLuint program, GLsizei cbData, GLvoid *pData)
909{
910 CRGLSLProgram *pProgram = crStateGetProgramObj(program);
911 char *pCurrent = pData;
912 GLsizei cbRead, cbName;
913 GLuint i;
914
915 if (!pProgram)
916 {
917 WARN(("Unknown program %d", program));
918 return;
919 }
920
921 if (pProgram->bAttribsSynced)
922 {
923 WARN(("crStateGLSLProgramCacheAttribs: this shouldn't happen!"));
924 crStateFreeProgramAttribsLocationCache(pProgram);
925 }
926
927 if (cbData<sizeof(GLsizei))
928 {
929 WARN(("crStateGLSLProgramCacheAttribs: data too short"));
930 return;
931 }
932
933 pProgram->cAttribs = ((GLsizei*)pCurrent)[0];
934 pCurrent += sizeof(GLsizei);
935 cbRead = sizeof(GLsizei);
936
937 crDebug("crStateGLSLProgramCacheAttribs: %i active attribs", pProgram->cAttribs);
938
939 if (pProgram->cAttribs)
940 {
941 pProgram->pAttribs = crAlloc(pProgram->cAttribs*sizeof(CRGLSLAttrib));
942 if (!pProgram->pAttribs)
943 {
944 WARN(("crStateGLSLProgramCacheAttribs: no memory"));
945 pProgram->cAttribs = 0;
946 return;
947 }
948 }
949
950 for (i=0; i<pProgram->cAttribs; ++i)
951 {
952 cbRead += sizeof(GLuint)+sizeof(GLsizei);
953 if (cbRead>cbData)
954 {
955 crWarning("crStateGLSLProgramCacheAttribs: out of data reading attrib %i", i);
956 return;
957 }
958 pProgram->pAttribs[i].index = ((GLint*)pCurrent)[0];
959 pCurrent += sizeof(GLint);
960 cbName = ((GLsizei*)pCurrent)[0];
961 pCurrent += sizeof(GLsizei);
962
963 cbRead += cbName;
964 if (cbRead>cbData)
965 {
966 crWarning("crStateGLSLProgramCacheAttribs: out of data reading attrib's name %i", i);
967 return;
968 }
969
970 pProgram->pAttribs[i].name = crStrndup(pCurrent, cbName);
971 pCurrent += cbName;
972
973 crDebug("crStateGLSLProgramCacheAttribs: attribs[%i]=%d, %s", i, pProgram->pAttribs[i].index, pProgram->pAttribs[i].name);
974 }
975
976 pProgram->bAttribsSynced = GL_TRUE;
977
978 CRASSERT((pCurrent-((char*)pData))==cbRead);
979 CRASSERT(cbRead==cbData);
980}
981#else /* IN_GUEST */
982static GLboolean crStateGLSLProgramCacheOneUniform(GLuint location, GLsizei cbName, GLchar *pName,
983 char **pCurrent, GLsizei *pcbWritten, GLsizei maxcbData)
984{
985 *pcbWritten += sizeof(GLint)+sizeof(GLsizei)+cbName;
986 if (*pcbWritten>maxcbData)
987 {
988 crWarning("crStateGLSLProgramCacheUniforms: buffer too small");
989 crFree(pName);
990 return GL_FALSE;
991 }
992
993 //crDebug("crStateGLSLProgramCacheUniforms: uniform[%i]=%s.", location, pName);
994
995 ((GLint*)*pCurrent)[0] = location;
996 *pCurrent += sizeof(GLint);
997 ((GLsizei*)*pCurrent)[0] = cbName;
998 *pCurrent += sizeof(GLsizei);
999 crMemcpy(*pCurrent, pName, cbName);
1000 *pCurrent += cbName;
1001
1002 return GL_TRUE;
1003}
1004
1005DECLEXPORT(void) STATE_APIENTRY
1006crStateGLSLProgramCacheUniforms(GLuint program, GLsizei maxcbData, GLsizei *cbData, GLvoid *pData)
1007{
1008 CRGLSLProgram *pProgram = crStateGetProgramObj(program);
1009 GLint maxUniformLen, activeUniforms=0, fakeUniformsCount, i, j;
1010 char *pCurrent = pData;
1011 GLsizei cbWritten;
1012
1013 if (!pProgram)
1014 {
1015 crWarning("Unknown program %d", program);
1016 return;
1017 }
1018
1019 diff_api.GetProgramiv(pProgram->hwid, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformLen);
1020 diff_api.GetProgramiv(pProgram->hwid, GL_ACTIVE_UNIFORMS, &activeUniforms);
1021
1022 *cbData = 0;
1023
1024 cbWritten = sizeof(GLsizei);
1025 if (cbWritten>maxcbData)
1026 {
1027 crWarning("crStateGLSLProgramCacheUniforms: buffer too small");
1028 return;
1029 }
1030 ((GLsizei*)pCurrent)[0] = activeUniforms;
1031 fakeUniformsCount = activeUniforms;
1032 pCurrent += sizeof(GLsizei);
1033
1034 crDebug("crStateGLSLProgramCacheUniforms: %i active uniforms", activeUniforms);
1035
1036 if (activeUniforms>0)
1037 {
1038 /*+8 to make sure our array uniforms with higher indices and [] will fit in as well*/
1039 GLchar *name = (GLchar *) crAlloc(maxUniformLen+8);
1040 GLenum type;
1041 GLint size;
1042 GLsizei cbName;
1043 GLint location;
1044
1045 if (!name)
1046 {
1047 crWarning("crStateGLSLProgramCacheUniforms: no memory");
1048 return;
1049 }
1050
1051 for (i=0; i<activeUniforms; ++i)
1052 {
1053 diff_api.GetActiveUniform(pProgram->hwid, i, maxUniformLen, &cbName, &size, &type, name);
1054 location = diff_api.GetUniformLocation(pProgram->hwid, name);
1055
1056 if (!crStateGLSLProgramCacheOneUniform(location, cbName, name, &pCurrent, &cbWritten, maxcbData))
1057 return;
1058
1059 /* Only one active uniform variable will be reported for a uniform array by glGetActiveUniform,
1060 * so we insert fake elements for other array elements.
1061 */
1062 if (size!=1)
1063 {
1064 char *pIndexStr = crStrchr(name, '[');
1065 GLint firstIndex=1;
1066 fakeUniformsCount += size;
1067
1068 crDebug("crStateGLSLProgramCacheUniforms: expanding array uniform, size=%i", size);
1069
1070 /*For array uniforms it's valid to query location of 1st element as both uniform and uniform[0].
1071 *The name returned by glGetActiveUniform is driver dependent,
1072 *atleast it's with [0] on win/ati and without [0] on linux/nvidia.
1073 */
1074 if (!pIndexStr)
1075 {
1076 pIndexStr = name+cbName;
1077 firstIndex=0;
1078 }
1079 else
1080 {
1081 cbName = pIndexStr-name;
1082 if (!crStateGLSLProgramCacheOneUniform(location, cbName, name, &pCurrent, &cbWritten, maxcbData))
1083 return;
1084 }
1085
1086 for (j=firstIndex; j<size; ++j)
1087 {
1088 sprintf(pIndexStr, "[%i]", j);
1089 cbName = crStrlen(name);
1090
1091 location = diff_api.GetUniformLocation(pProgram->hwid, name);
1092
1093 if (!crStateGLSLProgramCacheOneUniform(location, cbName, name, &pCurrent, &cbWritten, maxcbData))
1094 return;
1095 }
1096 }
1097 }
1098
1099 crFree(name);
1100 }
1101
1102 if (fakeUniformsCount!=activeUniforms)
1103 {
1104 ((GLsizei*)pData)[0] = fakeUniformsCount;
1105 crDebug("FakeCount %i", fakeUniformsCount);
1106 }
1107
1108 *cbData = cbWritten;
1109
1110 CRASSERT((pCurrent-((char*)pData))==cbWritten);
1111}
1112
1113static GLboolean crStateGLSLProgramCacheOneAttrib(GLuint location, GLsizei cbName, GLchar *pName,
1114 char **pCurrent, GLsizei *pcbWritten, GLsizei maxcbData)
1115{
1116 *pcbWritten += sizeof(GLint)+sizeof(GLsizei)+cbName;
1117 if (*pcbWritten>maxcbData)
1118 {
1119 WARN(("crStateGLSLProgramCacheOneAttrib: buffer too small"));
1120 crFree(pName);
1121 return GL_FALSE;
1122 }
1123
1124 crDebug("crStateGLSLProgramCacheOneAttrib: attrib[%i]=%s.", location, pName);
1125
1126 ((GLint*)*pCurrent)[0] = location;
1127 *pCurrent += sizeof(GLint);
1128 ((GLsizei*)*pCurrent)[0] = cbName;
1129 *pCurrent += sizeof(GLsizei);
1130 crMemcpy(*pCurrent, pName, cbName);
1131 *pCurrent += cbName;
1132
1133 return GL_TRUE;
1134}
1135
1136DECLEXPORT(void) STATE_APIENTRY
1137crStateGLSLProgramCacheAttribs(GLuint program, GLsizei maxcbData, GLsizei *cbData, GLvoid *pData)
1138{
1139 CRGLSLProgram *pProgram = crStateGetProgramObj(program);
1140 GLint maxAttribLen, activeAttribs=0, fakeAttribsCount, i, j;
1141 char *pCurrent = pData;
1142 GLsizei cbWritten;
1143
1144 if (!pProgram)
1145 {
1146 crWarning("Unknown program %d", program);
1147 return;
1148 }
1149
1150 diff_api.GetProgramiv(pProgram->hwid, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxAttribLen);
1151 diff_api.GetProgramiv(pProgram->hwid, GL_ACTIVE_ATTRIBUTES, &activeAttribs);
1152
1153 *cbData = 0;
1154
1155 cbWritten = sizeof(GLsizei);
1156 if (cbWritten>maxcbData)
1157 {
1158 crWarning("crStateGLSLProgramCacheAttribs: buffer too small");
1159 return;
1160 }
1161 ((GLsizei*)pCurrent)[0] = activeAttribs;
1162 fakeAttribsCount = activeAttribs;
1163 pCurrent += sizeof(GLsizei);
1164
1165 crDebug("crStateGLSLProgramCacheAttribs: %i active attribs", activeAttribs);
1166
1167 if (activeAttribs>0)
1168 {
1169 /*+8 to make sure our array attribs with higher indices and [] will fit in as well*/
1170 GLchar *name = (GLchar *) crAlloc(maxAttribLen+8);
1171 GLenum type;
1172 GLint size;
1173 GLsizei cbName;
1174 GLint location;
1175
1176 if (!name)
1177 {
1178 crWarning("crStateGLSLProgramCacheAttribs: no memory");
1179 return;
1180 }
1181
1182 for (i=0; i<activeAttribs; ++i)
1183 {
1184 diff_api.GetActiveAttrib(pProgram->hwid, i, maxAttribLen, &cbName, &size, &type, name);
1185 location = diff_api.GetAttribLocation(pProgram->hwid, name);
1186
1187 if (!crStateGLSLProgramCacheOneAttrib(location, cbName, name, &pCurrent, &cbWritten, maxcbData))
1188 return;
1189
1190 /* Only one active attrib variable will be reported for a attrib array by glGetActiveAttrib,
1191 * so we insert fake elements for other array elements.
1192 */
1193 if (size!=1)
1194 {
1195 char *pIndexStr = crStrchr(name, '[');
1196 GLint firstIndex=1;
1197 fakeAttribsCount += size;
1198
1199 crDebug("crStateGLSLProgramCacheAttribs: expanding array attrib, size=%i", size);
1200
1201 /*For array attribs it's valid to query location of 1st element as both attrib and attrib[0].
1202 *The name returned by glGetActiveAttrib is driver dependent,
1203 *atleast it's with [0] on win/ati and without [0] on linux/nvidia.
1204 */
1205 if (!pIndexStr)
1206 {
1207 pIndexStr = name+cbName;
1208 firstIndex=0;
1209 }
1210 else
1211 {
1212 cbName = pIndexStr-name;
1213 if (!crStateGLSLProgramCacheOneAttrib(location, cbName, name, &pCurrent, &cbWritten, maxcbData))
1214 return;
1215 }
1216
1217 for (j=firstIndex; j<size; ++j)
1218 {
1219 sprintf(pIndexStr, "[%i]", j);
1220 cbName = crStrlen(name);
1221
1222 location = diff_api.GetAttribLocation(pProgram->hwid, name);
1223
1224 if (!crStateGLSLProgramCacheOneAttrib(location, cbName, name, &pCurrent, &cbWritten, maxcbData))
1225 return;
1226 }
1227 }
1228 }
1229
1230 crFree(name);
1231 }
1232
1233 if (fakeAttribsCount!=activeAttribs)
1234 {
1235 ((GLsizei*)pData)[0] = fakeAttribsCount;
1236 crDebug("FakeCount %i", fakeAttribsCount);
1237 }
1238
1239 *cbData = cbWritten;
1240
1241 CRASSERT((pCurrent-((char*)pData))==cbWritten);
1242}
1243#endif
1244
1245DECLEXPORT(GLint) STATE_APIENTRY crStateGetUniformLocation(GLuint program, const char * name)
1246{
1247#ifdef IN_GUEST
1248 CRGLSLProgram *pProgram = crStateGetProgramObj(program);
1249 GLint result=-1;
1250 GLuint i;
1251
1252 if (!pProgram)
1253 {
1254 crWarning("Unknown program %d", program);
1255 return -1;
1256 }
1257
1258 if (!pProgram->bUniformsSynced)
1259 {
1260 crWarning("crStateGetUniformLocation called for uncached uniforms");
1261 return -1;
1262 }
1263
1264 for (i=0; i<pProgram->cUniforms; ++i)
1265 {
1266 if (!crStrcmp(name, pProgram->pUniforms[i].name))
1267 {
1268 result = pProgram->pUniforms[i].location;
1269 break;
1270 }
1271 }
1272
1273 return result;
1274#else
1275 crWarning("crStateGetUniformLocation called on host side!!");
1276 return -1;
1277#endif
1278}
1279
1280DECLEXPORT(GLint) STATE_APIENTRY crStateGetAttribLocation(GLuint program, const char * name)
1281{
1282#ifdef IN_GUEST
1283 CRGLSLProgram *pProgram = crStateGetProgramObj(program);
1284 GLint result=-1;
1285 GLuint i;
1286
1287 if (!pProgram)
1288 {
1289 WARN(("Unknown program %d", program));
1290 return -1;
1291 }
1292
1293 if (!pProgram->bAttribsSynced)
1294 {
1295 WARN(("crStateGetAttribLocation called for uncached attribs"));
1296 return -1;
1297 }
1298
1299 for (i=0; i<pProgram->cAttribs; ++i)
1300 {
1301 if (!crStrcmp(name, pProgram->pAttribs[i].name))
1302 {
1303 result = pProgram->pAttribs[i].index;
1304 break;
1305 }
1306 }
1307
1308 return result;
1309#else
1310 crWarning("crStateGetAttribLocation called on host side!!");
1311 return -1;
1312#endif
1313}
1314
1315static void crStateGLSLCreateShadersCB(unsigned long key, void *data1, void *data2)
1316{
1317 CRGLSLShader *pShader = (CRGLSLShader*) data1;
1318 CRContext *ctx = (CRContext *) data2;
1319
1320 pShader->hwid = diff_api.CreateShader(pShader->type);
1321}
1322
1323static void crStateFixAttachedShaderHWIDsCB(unsigned long key, void *data1, void *data2)
1324{
1325 CRGLSLShader *pShader = (CRGLSLShader*) data1;
1326 CRGLSLShader *pRealShader;
1327 CRContext *pCtx = (CRContext *) data2;
1328
1329 pRealShader = (CRGLSLShader *) crHashtableSearch(pCtx->glsl.shaders, key);
1330 CRASSERT(pRealShader);
1331
1332 pShader->hwid = pRealShader->hwid;
1333}
1334
1335static void crStateGLSLSyncShadersCB(unsigned long key, void *data1, void *data2)
1336{
1337 CRGLSLShader *pShader = (CRGLSLShader*) data1;
1338 (void) key;
1339 (void) data2;
1340
1341 if (pShader->source)
1342 {
1343 diff_api.ShaderSource(pShader->hwid, 1, (const char**)&pShader->source, NULL);
1344 if (pShader->compiled)
1345 diff_api.CompileShader(pShader->hwid);
1346 crFree(pShader->source);
1347 pShader->source = NULL;
1348 }
1349
1350 if (pShader->deleted)
1351 diff_api.DeleteShader(pShader->hwid);
1352}
1353
1354static void crStateAttachShaderCB(unsigned long key, void *data1, void *data2)
1355{
1356 CRGLSLShader *pShader = (CRGLSLShader*) data1;
1357 CRGLSLProgram *pProgram = (CRGLSLProgram *) data2;
1358 (void) key;
1359
1360 if (pShader->source)
1361 {
1362 diff_api.ShaderSource(pShader->hwid, 1, (const char**)&pShader->source, NULL);
1363 if (pShader->compiled)
1364 diff_api.CompileShader(pShader->hwid);
1365 }
1366
1367 diff_api.AttachShader(pProgram->hwid, pShader->hwid);
1368}
1369
1370static void crStateDetachShaderCB(unsigned long key, void *data1, void *data2)
1371{
1372 CRGLSLShader *pShader = (CRGLSLShader*) data1;
1373 CRGLSLProgram *pProgram = (CRGLSLProgram *) data2;
1374 (void) key;
1375
1376 diff_api.DetachShader(pProgram->hwid, pShader->hwid);
1377}
1378
1379static void crStateGLSLCreateProgramCB(unsigned long key, void *data1, void *data2)
1380{
1381 CRGLSLProgram *pProgram = (CRGLSLProgram*) data1;
1382 CRContext *ctx = (CRContext *) data2;
1383 GLuint i;
1384
1385 pProgram->hwid = diff_api.CreateProgram();
1386
1387 if (pProgram->linked)
1388 {
1389 CRASSERT(pProgram->activeState.attachedShaders);
1390
1391 crHashtableWalk(pProgram->activeState.attachedShaders, crStateFixAttachedShaderHWIDsCB, ctx);
1392 crHashtableWalk(pProgram->activeState.attachedShaders, crStateAttachShaderCB, pProgram);
1393
1394 for (i=0; i<pProgram->activeState.cAttribs; ++i)
1395 {
1396 diff_api.BindAttribLocation(pProgram->hwid, pProgram->activeState.pAttribs[i].index, pProgram->activeState.pAttribs[i].name);
1397 }
1398
1399 if (pProgram->validated)
1400 diff_api.ValidateProgram(pProgram->hwid);
1401
1402 diff_api.LinkProgram(pProgram->hwid);
1403 }
1404
1405 diff_api.UseProgram(pProgram->hwid);
1406
1407 for (i=0; i<pProgram->cUniforms; ++i)
1408 {
1409 GLint location;
1410 GLfloat *pFdata = (GLfloat*)pProgram->pUniforms[i].data;
1411 GLint *pIdata = (GLint*)pProgram->pUniforms[i].data;
1412
1413 location = diff_api.GetUniformLocation(pProgram->hwid, pProgram->pUniforms[i].name);
1414 switch (pProgram->pUniforms[i].type)
1415 {
1416 case GL_FLOAT:
1417 diff_api.Uniform1fv(location, 1, pFdata);
1418 break;
1419 case GL_FLOAT_VEC2:
1420 diff_api.Uniform2fv(location, 1, pFdata);
1421 break;
1422 case GL_FLOAT_VEC3:
1423 diff_api.Uniform3fv(location, 1, pFdata);
1424 break;
1425 case GL_FLOAT_VEC4:
1426 diff_api.Uniform4fv(location, 1, pFdata);
1427 break;
1428 case GL_INT:
1429 case GL_BOOL:
1430 diff_api.Uniform1iv(location, 1, pIdata);
1431 break;
1432 case GL_INT_VEC2:
1433 case GL_BOOL_VEC2:
1434 diff_api.Uniform2iv(location, 1, pIdata);
1435 break;
1436 case GL_INT_VEC3:
1437 case GL_BOOL_VEC3:
1438 diff_api.Uniform3iv(location, 1, pIdata);
1439 break;
1440 case GL_INT_VEC4:
1441 case GL_BOOL_VEC4:
1442 diff_api.Uniform4iv(location, 1, pIdata);
1443 break;
1444 case GL_FLOAT_MAT2:
1445 diff_api.UniformMatrix2fv(location, 1, GL_FALSE, pFdata);
1446 break;
1447 case GL_FLOAT_MAT3:
1448 diff_api.UniformMatrix3fv(location, 1, GL_FALSE, pFdata);
1449 break;
1450 case GL_FLOAT_MAT4:
1451 diff_api.UniformMatrix4fv(location, 1, GL_FALSE, pFdata);
1452 break;
1453 case GL_SAMPLER_1D:
1454 case GL_SAMPLER_2D:
1455 case GL_SAMPLER_3D:
1456 case GL_SAMPLER_CUBE:
1457 case GL_SAMPLER_1D_SHADOW:
1458 case GL_SAMPLER_2D_SHADOW:
1459 case GL_SAMPLER_2D_RECT_ARB:
1460 case GL_SAMPLER_2D_RECT_SHADOW_ARB:
1461 diff_api.Uniform1iv(location, 1, pIdata);
1462 break;
1463#ifdef CR_OPENGL_VERSION_2_1
1464 case GL_FLOAT_MAT2x3:
1465 diff_api.UniformMatrix2x3fv(location, 1, GL_FALSE, pFdata);
1466 break;
1467 case GL_FLOAT_MAT2x4:
1468 diff_api.UniformMatrix2x4fv(location, 1, GL_FALSE, pFdata);
1469 break;
1470 case GL_FLOAT_MAT3x2:
1471 diff_api.UniformMatrix3x2fv(location, 1, GL_FALSE, pFdata);
1472 break;
1473 case GL_FLOAT_MAT3x4:
1474 diff_api.UniformMatrix3x4fv(location, 1, GL_FALSE, pFdata);
1475 break;
1476 case GL_FLOAT_MAT4x2:
1477 diff_api.UniformMatrix4x2fv(location, 1, GL_FALSE, pFdata);
1478 break;
1479 case GL_FLOAT_MAT4x3:
1480 diff_api.UniformMatrix4x3fv(location, 1, GL_FALSE, pFdata);
1481 break;
1482#endif
1483 default:
1484 crWarning("crStateGLSLCreateProgramCB: unknown uniform type 0x%x", (GLint)pProgram->pUniforms[i].type);
1485 break;
1486 }
1487 crFree(pProgram->pUniforms[i].data);
1488 crFree(pProgram->pUniforms[i].name);
1489 } /*for (i=0; i<pProgram->cUniforms; ++i)*/
1490 if (pProgram->pUniforms) crFree(pProgram->pUniforms);
1491 pProgram->pUniforms = NULL;
1492 pProgram->cUniforms = 0;
1493
1494 crHashtableWalk(pProgram->activeState.attachedShaders, crStateDetachShaderCB, pProgram);
1495 crHashtableWalk(pProgram->currentState.attachedShaders, crStateAttachShaderCB, pProgram);
1496}
1497
1498DECLEXPORT(void) STATE_APIENTRY crStateGLSLSwitch(CRContext *from, CRContext *to)
1499{
1500 GLboolean fForceUseProgramSet = GL_FALSE;
1501 if (to->glsl.bResyncNeeded)
1502 {
1503 to->glsl.bResyncNeeded = GL_FALSE;
1504
1505 crHashtableWalk(to->glsl.shaders, crStateGLSLCreateShadersCB, to);
1506
1507 crHashtableWalk(to->glsl.programs, crStateGLSLCreateProgramCB, to);
1508
1509 /* crStateGLSLCreateProgramCB changes the current program, ensure we have the proper program re-sored */
1510 fForceUseProgramSet = GL_TRUE;
1511
1512 crHashtableWalk(to->glsl.shaders, crStateGLSLSyncShadersCB, NULL);
1513 }
1514
1515 if (to->glsl.activeProgram != from->glsl.activeProgram || fForceUseProgramSet)
1516 {
1517 diff_api.UseProgram(to->glsl.activeProgram ? to->glsl.activeProgram->hwid : 0);
1518 }
1519}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette