ENGR00156850 gpu-viv: add gpu-viv driver source
[wandboard.git] / drivers / mxc / gpu-viv / arch / XAQ2 / hal / kernel / gc_hal_kernel_context.c
blob2f0c982dd6be66f16a288ae1e8c322ec34d3ce5f
1 /****************************************************************************
3 * Copyright (C) 2005 - 2011 by Vivante Corp.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the license, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *****************************************************************************/
26 #include "gc_hal.h"
27 #include "gc_hal_kernel.h"
28 #include "gc_hal_kernel_context.h"
29 #include "gc_hal_kernel_buffer.h"
31 /******************************************************************************\
32 ******************************** Debugging Macro *******************************
33 \******************************************************************************/
35 /* Zone used for header/footer. */
36 #define _GC_OBJ_ZONE gcvZONE_HARDWARE
39 /******************************************************************************\
40 ************************** Context State Buffer Helpers ************************
41 \******************************************************************************/
43 #define _STATE(reg) \
44 _State(\
45 Context, index, \
46 reg ## _Address >> 2, \
47 reg ## _ResetValue, \
48 reg ## _Count, \
49 gcvFALSE, gcvFALSE \
52 #define _STATE_COUNT(reg, count) \
53 _State(\
54 Context, index, \
55 reg ## _Address >> 2, \
56 reg ## _ResetValue, \
57 count, \
58 gcvFALSE, gcvFALSE \
61 #define _STATE_COUNT_OFFSET(reg, offset, count) \
62 _State(\
63 Context, index, \
64 (reg ## _Address >> 2) + offset, \
65 reg ## _ResetValue, \
66 count, \
67 gcvFALSE, gcvFALSE \
70 #define _STATE_HINT(reg) \
71 _State(\
72 Context, index, \
73 reg ## _Address >> 2, \
74 reg ## _ResetValue, \
75 reg ## _Count, \
76 gcvFALSE, gcvTRUE \
79 #define _STATE_HINT_BLOCK(reg, block, count) \
80 _State(\
81 Context, index, \
82 (reg ## _Address >> 2) + (block << reg ## _BLK), \
83 reg ## _ResetValue, \
84 count, \
85 gcvFALSE, gcvTRUE \
88 #define _STATE_X(reg) \
89 _State(\
90 Context, index, \
91 reg ## _Address >> 2, \
92 reg ## _ResetValue, \
93 reg ## _Count, \
94 gcvTRUE, gcvFALSE \
97 #define _CLOSE_RANGE() \
98 _TerminateStateBlock(Context, index)
100 #define _ENABLE(reg, field) \
101 do \
103 if (gcmVERIFYFIELDVALUE(data, reg, MASK_ ## field, ENABLED)) \
105 enable |= gcmFIELDMASK(reg, field); \
108 while (gcvFALSE)
110 #define _BLOCK_COUNT(reg) \
111 ((reg ## _Count) >> (reg ## _BLK))
114 /******************************************************************************\
115 *********************** Support Functions and Definitions **********************
116 \******************************************************************************/
118 #define gcdSTATE_MASK \
119 (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | 0xC0FFEE)
121 #if !defined(VIVANTE_NO_3D)
122 static gctSIZE_T
123 _TerminateStateBlock(
124 IN gckCONTEXT Context,
125 IN gctSIZE_T Index
128 gctUINT32_PTR buffer;
129 gctSIZE_T align;
131 /* Determine if we need alignment. */
132 align = (Index & 1) ? 1 : 0;
134 /* Address correct index. */
135 buffer = (Context->buffer == gcvNULL)
136 ? gcvNULL
137 : Context->buffer->logical;
139 /* Flush the current state block; make sure no pairing with the states
140 to follow happens. */
141 if (align && (buffer != gcvNULL))
143 buffer[Index] = 0xDEADDEAD;
146 /* Reset last address. */
147 Context->lastAddress = ~0U;
149 /* Return alignment requirement. */
150 return align;
152 #endif
155 static gctSIZE_T
156 _FlushPipe(
157 IN gckCONTEXT Context,
158 IN gctSIZE_T Index,
159 IN gcePIPE_SELECT Pipe
162 if (Context->buffer != gcvNULL)
164 gctUINT32_PTR buffer;
166 /* Address correct index. */
167 buffer = Context->buffer->logical + Index;
169 /* Flush the current pipe. */
170 *buffer++
171 = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
172 | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
173 | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
175 *buffer++
176 = (Pipe == gcvPIPE_2D)
177 ? ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)))
178 : ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
179 | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
180 | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)));
182 /* Semaphore from FE to PE. */
183 *buffer++
184 = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
185 | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
186 | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
188 *buffer++
189 = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
190 | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
192 /* Stall from FE to PE. */
193 *buffer++
194 = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
196 *buffer
197 = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
198 | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
201 /* Flushing 3D pipe takes 6 slots. */
202 return 6;
205 static gctSIZE_T
206 _SwitchPipe(
207 IN gckCONTEXT Context,
208 IN gctSIZE_T Index,
209 IN gcePIPE_SELECT Pipe
212 if (Context->buffer != gcvNULL)
214 gctUINT32_PTR buffer;
216 /* Address correct index. */
217 buffer = Context->buffer->logical + Index;
219 /* LoadState(AQPipeSelect, 1), pipe. */
220 *buffer++
221 = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
222 | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E00) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
223 | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
225 *buffer
226 = (Pipe == gcvPIPE_2D)
227 ? 0x1
228 : 0x0;
231 return 2;
234 #if !defined(VIVANTE_NO_3D)
235 static gctSIZE_T
236 _State(
237 IN gckCONTEXT Context,
238 IN gctSIZE_T Index,
239 IN gctUINT32 Address,
240 IN gctUINT32 Value,
241 IN gctSIZE_T Size,
242 IN gctBOOL FixedPoint,
243 IN gctBOOL Hinted
246 gctUINT32_PTR buffer;
247 gctSIZE_T align, i;
249 /* Determine if we need alignment. */
250 align = (Index & 1) ? 1 : 0;
252 /* Address correct index. */
253 buffer = (Context->buffer == gcvNULL)
254 ? gcvNULL
255 : Context->buffer->logical;
257 if ((buffer == gcvNULL) && (Address + Size > Context->stateCount))
259 /* Determine maximum state. */
260 Context->stateCount = Address + Size;
263 /* Do we need a new entry? */
264 if ((Address != Context->lastAddress) || (FixedPoint != Context->lastFixed))
266 if (buffer != gcvNULL)
268 if (align)
270 /* Add filler. */
271 buffer[Index++] = 0xDEADDEAD;
274 /* LoadState(Address, Count). */
275 gcmkASSERT((Index & 1) == 0);
277 if (FixedPoint)
279 buffer[Index]
280 = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
281 | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1))))))) << (0 ? 26:26))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1))))))) << (0 ? 26:26)))
282 | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (Size) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
283 | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (Address) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
285 else
287 buffer[Index]
288 = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
289 | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1))))))) << (0 ? 26:26))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1))))))) << (0 ? 26:26)))
290 | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (Size) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
291 | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (Address) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
294 /* Walk all the states. */
295 for (i = 0; i < Size; i += 1)
297 /* Set state to uninitialized value. */
298 buffer[Index + 1 + i] = Value;
300 /* Set index in state mapping table. */
301 Context->map[Address + i].index = Index + 1 + i;
303 #if gcdSECURE_USER
304 /* Save hint. */
305 if (Context->hint != gcvNULL)
307 Context->hint[Address + i] = Hinted;
309 #endif
313 /* Save information for this LoadState. */
314 Context->lastIndex = Index;
315 Context->lastAddress = Address + Size;
316 Context->lastSize = Size;
317 Context->lastFixed = FixedPoint;
319 /* Return size for load state. */
320 return align + 1 + Size;
323 /* Append this state to the previous one. */
324 if (buffer != gcvNULL)
326 /* Update last load state. */
327 buffer[Context->lastIndex] =
328 ((((gctUINT32) (buffer[Context->lastIndex])) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (Context->lastSize + Size) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
330 /* Walk all the states. */
331 for (i = 0; i < Size; i += 1)
333 /* Set state to uninitialized value. */
334 buffer[Index + i] = Value;
336 /* Set index in state mapping table. */
337 Context->map[Address + i].index = Index + i;
339 #if gcdSECURE_USER
340 /* Save hint. */
341 if (Context->hint != gcvNULL)
343 Context->hint[Address + i] = Hinted;
345 #endif
349 /* Update last address and size. */
350 Context->lastAddress += Size;
351 Context->lastSize += Size;
353 /* Return number of slots required. */
354 return Size;
356 #endif
358 static gceSTATUS
359 _InitializeContextBuffer(
360 IN gckCONTEXT Context
363 gctUINT32_PTR buffer;
364 gctSIZE_T index;
366 #if !defined(VIVANTE_NO_3D)
367 gctINT i;
368 gctUINT vertexUniforms, fragmentUniforms;
369 gctUINT fe2vsCount;
370 #endif
372 /* Reset the buffer index. */
373 index = 0;
375 /* Reset the last state address. */
376 Context->lastAddress = ~0U;
378 /* Get the buffer pointer. */
379 buffer = (Context->buffer == gcvNULL)
380 ? gcvNULL
381 : Context->buffer->logical;
384 /**************************************************************************/
385 /* Build 2D states. *******************************************************/
388 #if !defined(VIVANTE_NO_3D)
389 /**************************************************************************/
390 /* Build 3D states. *******************************************************/
392 /* Query shader support. */
393 gcmkVERIFY_OK(gckHARDWARE_QueryShaderCaps(
394 Context->hardware, &vertexUniforms, &fragmentUniforms, gcvNULL));
396 /* Store the 3D entry index. */
397 Context->entryOffset3D = index * gcmSIZEOF(gctUINT32);
399 /* Flush 2D pipe. */
400 index += _FlushPipe(Context, index, gcvPIPE_2D);
402 /* Switch to 3D pipe. */
403 index += _SwitchPipe(Context, index, gcvPIPE_3D);
405 /* Current context pointer. */
406 #if gcdDEBUG && 1
407 index += _State(Context, index, 0x03850 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
408 #endif
410 /* Global states. */
411 index += _State(Context, index, 0x03814 >> 2, 0x00000001, 1, gcvFALSE, gcvFALSE);
412 index += _State(Context, index, 0x03818 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
413 index += _State(Context, index, 0x0381C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
414 index += _State(Context, index, 0x03820 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
415 index += _State(Context, index, 0x03828 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
416 index += _State(Context, index, 0x0382C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
418 /* Front End states. */
419 fe2vsCount = 12;
420 if ((((((gctUINT32) (Context->hardware->chipMinorFeatures1)) >> (0 ? 23:23)) & ((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1)))))) ))
422 fe2vsCount = 16;
424 index += _State(Context, index, 0x00600 >> 2, 0x00000000, fe2vsCount, gcvFALSE, gcvFALSE);
425 index += _CLOSE_RANGE();
427 index += _State(Context, index, 0x00644 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
428 index += _State(Context, index, 0x00648 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
429 index += _State(Context, index, 0x0064C >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
430 index += _State(Context, index, 0x00650 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
431 index += _State(Context, index, 0x00680 >> 2, 0x00000000, 8, gcvFALSE, gcvTRUE);
432 index += _State(Context, index, 0x006A0 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE);
433 index += _State(Context, index, 0x00670 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
435 /* Vertex Shader states. */
436 index += _State(Context, index, 0x00800 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
437 index += _State(Context, index, 0x00804 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
438 index += _State(Context, index, 0x00808 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
439 index += _State(Context, index, 0x0080C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
440 index += _State(Context, index, 0x00810 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE);
441 index += _State(Context, index, 0x00820 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE);
442 index += _State(Context, index, 0x00830 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
443 index += _State(Context, index, 0x00838 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
444 index += _State(Context, index, 0x04000 >> 2, 0x00000000, 1024, gcvFALSE, gcvFALSE);
446 index += _CLOSE_RANGE();
447 index += _State(Context, index, 0x05000 >> 2, 0x00000000, vertexUniforms * 4, gcvFALSE, gcvFALSE);
449 index += _State(Context, index, 0x00850 >> 2, 0x000003E8, 1, gcvFALSE, gcvFALSE);
450 index += _State(Context, index, 0x00854 >> 2, 0x00000100, 1, gcvFALSE, gcvFALSE);
452 /* Primitive Assembly states. */
453 index += _State(Context, index, 0x00A00 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
454 index += _State(Context, index, 0x00A04 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
455 index += _State(Context, index, 0x00A08 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
456 index += _State(Context, index, 0x00A0C >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
457 index += _State(Context, index, 0x00A10 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
458 index += _State(Context, index, 0x00A14 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
459 index += _State(Context, index, 0x00A18 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
460 index += _State(Context, index, 0x00A1C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
461 index += _State(Context, index, 0x00A28 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
462 index += _State(Context, index, 0x00A2C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
463 index += _State(Context, index, 0x00A30 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
464 index += _State(Context, index, 0x00A40 >> 2, 0x00000000, 10, gcvFALSE, gcvFALSE);
465 index += _State(Context, index, 0x00A34 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
467 /* Setup states. */
468 index += _State(Context, index, 0x00C00 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
469 index += _State(Context, index, 0x00C04 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
470 index += _State(Context, index, 0x00C08 >> 2, 0x45000000, 1, gcvTRUE, gcvFALSE);
471 index += _State(Context, index, 0x00C0C >> 2, 0x45000000, 1, gcvTRUE, gcvFALSE);
472 index += _State(Context, index, 0x00C10 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
473 index += _State(Context, index, 0x00C14 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
474 index += _State(Context, index, 0x00C18 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
476 /* Raster states. */
477 index += _State(Context, index, 0x00E00 >> 2, 0x00000001, 1, gcvFALSE, gcvFALSE);
478 index += _State(Context, index, 0x00E10 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE);
479 index += _State(Context, index, 0x00E04 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
480 index += _State(Context, index, 0x00E40 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
481 index += _State(Context, index, 0x00E08 >> 2, 0x00000031, 1, gcvFALSE, gcvFALSE);
483 /* Pixel Shader states. */
484 index += _State(Context, index, 0x01000 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
485 index += _State(Context, index, 0x01004 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
486 index += _State(Context, index, 0x01008 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
487 index += _State(Context, index, 0x0100C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
488 index += _State(Context, index, 0x01010 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
489 index += _State(Context, index, 0x01018 >> 2, 0x01000000, 1, gcvFALSE, gcvFALSE);
490 index += _State(Context, index, 0x06000 >> 2, 0x00000000, 1024, gcvFALSE, gcvFALSE);
492 index += _CLOSE_RANGE();
493 index += _State(Context, index, 0x07000 >> 2, 0x00000000, fragmentUniforms * 4, gcvFALSE, gcvFALSE);
495 /* Texture states. */
496 index += _State(Context, index, 0x02000 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
497 index += _State(Context, index, 0x02040 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
498 index += _State(Context, index, 0x02080 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
499 index += _State(Context, index, 0x020C0 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
500 index += _State(Context, index, 0x02100 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
501 index += _State(Context, index, 0x02140 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
502 index += _State(Context, index, 0x02400 >> 2, 0x00000000, 12, gcvFALSE, gcvTRUE);
503 index += _State(Context, index, 0x02440 >> 2, 0x00000000, 12, gcvFALSE, gcvTRUE);
504 index += _State(Context, index, 0x02480 >> 2, 0x00000000, 12, gcvFALSE, gcvTRUE);
505 index += _State(Context, index, 0x024C0 >> 2, 0x00000000, 12, gcvFALSE, gcvTRUE);
506 index += _State(Context, index, 0x02500 >> 2, 0x00000000, 12, gcvFALSE, gcvTRUE);
507 index += _State(Context, index, 0x02540 >> 2, 0x00000000, 12, gcvFALSE, gcvTRUE);
508 index += _State(Context, index, 0x02580 >> 2, 0x00000000, 12, gcvFALSE, gcvTRUE);
509 index += _State(Context, index, 0x025C0 >> 2, 0x00000000, 12, gcvFALSE, gcvTRUE);
510 index += _State(Context, index, 0x02600 >> 2, 0x00000000, 12, gcvFALSE, gcvTRUE);
511 index += _State(Context, index, 0x02640 >> 2, 0x00000000, 12, gcvFALSE, gcvTRUE);
512 index += _State(Context, index, 0x02680 >> 2, 0x00000000, 12, gcvFALSE, gcvTRUE);
513 index += _State(Context, index, 0x026C0 >> 2, 0x00000000, 12, gcvFALSE, gcvTRUE);
514 index += _State(Context, index, 0x02700 >> 2, 0x00000000, 12, gcvFALSE, gcvTRUE);
515 index += _State(Context, index, 0x02740 >> 2, 0x00000000, 12, gcvFALSE, gcvTRUE);
516 index += _CLOSE_RANGE();
518 if ((((((gctUINT32) (Context->hardware->chipMinorFeatures2)) >> (0 ? 11:11)) & ((gctUINT32) ((((1 ? 11:11) - (0 ? 11:11) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:11) - (0 ? 11:11) + 1)))))) ))
520 /* New texture block. */
521 index += _State(Context, index, 0x10000 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
522 index += _State(Context, index, 0x10080 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
523 index += _State(Context, index, 0x10100 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
524 index += _State(Context, index, 0x10180 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
525 index += _State(Context, index, 0x10200 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
526 index += _State(Context, index, 0x10280 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
527 index += _State(Context, index, 0x10300 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
528 index += _State(Context, index, 0x10380 >> 2, 0x00321000, 32, gcvFALSE, gcvFALSE);
529 index += _State(Context, index, 0x10400 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
530 index += _State(Context, index, 0x10480 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
531 index += _State(Context, index, 0x12000 >> 2, 0x00000000, 256, gcvFALSE, gcvFALSE);
532 index += _State(Context, index, 0x12400 >> 2, 0x00000000, 256, gcvFALSE, gcvFALSE);
534 for (i = 0; i < (512 >> (4)); i += 1)
536 index += _State(Context, index, ((0x10800 >> 2) + (i << 4)), 0x00000000, 14, gcvFALSE, gcvTRUE);
540 /* YUV. */
541 index += _State(Context, index, 0x01678 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
542 index += _State(Context, index, 0x0167C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
543 index += _State(Context, index, 0x01680 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
544 index += _State(Context, index, 0x01684 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
545 index += _State(Context, index, 0x01688 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
546 index += _State(Context, index, 0x0168C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
547 index += _State(Context, index, 0x01690 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
548 index += _State(Context, index, 0x01694 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
549 index += _State(Context, index, 0x01698 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
550 index += _State(Context, index, 0x0169C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
551 index += _CLOSE_RANGE();
553 index += _State(Context, index, 0x016A4 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
554 index += _State(Context, index, 0x016A8 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
555 index += _CLOSE_RANGE();
557 /* Thread walker states. */
558 index += _State(Context, index, 0x00900 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
559 index += _State(Context, index, 0x00904 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
560 index += _State(Context, index, 0x00908 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
561 index += _State(Context, index, 0x0090C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
562 index += _State(Context, index, 0x00910 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
563 index += _State(Context, index, 0x00914 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
564 index += _State(Context, index, 0x00918 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
565 index += _State(Context, index, 0x0091C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
566 index += _CLOSE_RANGE();
568 if (Context->hardware->instructionCount >= 2048)
570 /* New Shader instruction memory. */
571 index += _State(Context, index, 0x0085C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
572 index += _State(Context, index, 0x0101C >> 2, 0x00000100, 1, gcvFALSE, gcvFALSE);
573 index += _State(Context, index, 0x00860 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
574 index += _CLOSE_RANGE();
576 for (i = 0; i < 8192; i += 1024)
578 index += _State(Context, index, (0x20000 >> 2) + i, 0x00000000, 1024, gcvFALSE, gcvFALSE);
579 index += _CLOSE_RANGE();
582 else if (Context->hardware->instructionCount >= 1024)
584 /* VX instruction memory. */
585 for (i = 0; i < 4096; i += 1024)
587 index += _State(Context, index, (0x0C000 >> 2) + i, 0x00000000, 1024, gcvFALSE, gcvFALSE);
588 index += _CLOSE_RANGE();
591 for (i = 0; i < 4096; i += 1024)
593 index += _State(Context, index, (0x08000 >> 2) + i, 0x00000000, 1024, gcvFALSE, gcvFALSE);
594 index += _CLOSE_RANGE();
598 /* Store the index of the "XD" entry. */
599 Context->entryOffsetXDFrom3D = index * gcmSIZEOF(gctUINT32);
601 index += _FlushPipe(Context, index, gcvPIPE_3D);
603 /* Pixel Engine states. */
604 index += _State(Context, index, 0x01400 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
605 index += _State(Context, index, 0x01404 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
606 index += _State(Context, index, 0x01408 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
607 index += _State(Context, index, 0x0140C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
609 index += _State(Context, index, 0x01414 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
610 index += _State(Context, index, 0x01418 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
611 index += _State(Context, index, 0x0141C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
612 index += _State(Context, index, 0x01420 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
613 index += _State(Context, index, 0x01424 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
614 index += _State(Context, index, 0x01428 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
615 index += _State(Context, index, 0x0142C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
617 /* Composition states. */
618 index += _State(Context, index, 0x03008 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
620 if (Context->hardware->pixelPipes == 1)
622 index += _State(Context, index, 0x01430 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
623 index += _State(Context, index, 0x01410 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
625 else
627 index += _State(Context, index, ((0x01460 >> 2) + (0 << 3)), 0x00000000, Context->hardware->pixelPipes , gcvFALSE, gcvTRUE);
629 index += _State(Context, index, ((0x01480 >> 2) + (0 << 3)), 0x00000000, Context->hardware->pixelPipes , gcvFALSE, gcvTRUE);
632 index += _State(Context, index, 0x01434 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
633 index += _State(Context, index, 0x01454 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
634 index += _State(Context, index, 0x01458 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
635 index += _State(Context, index, 0x0145C >> 2, 0x00000010, 1, gcvFALSE, gcvFALSE);
636 index += _State(Context, index, 0x014A8 >> 2, 0xFFFFFFFF, 1, gcvFALSE, gcvFALSE);
637 index += _State(Context, index, 0x014AC >> 2, 0xFFFFFFFF, 1, gcvFALSE, gcvFALSE);
639 /* Resolve states. */
640 index += _State(Context, index, 0x01604 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
641 index += _State(Context, index, 0x01608 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
642 index += _State(Context, index, 0x0160C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
643 index += _State(Context, index, 0x01610 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
644 index += _State(Context, index, 0x01614 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
645 index += _State(Context, index, 0x01620 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
646 index += _State(Context, index, 0x01630 >> 2, 0x00000000, 2, gcvFALSE, gcvFALSE);
647 index += _State(Context, index, 0x01640 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE);
648 index += _State(Context, index, 0x0163C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
649 index += _State(Context, index, 0x016A0 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
650 index += _CLOSE_RANGE();
652 /* Tile status. */
653 index += _State(Context, index, 0x01654 >> 2, 0x00200000, 1, gcvFALSE, gcvFALSE);
655 index += _CLOSE_RANGE();
656 index += _State(Context, index, 0x01658 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
658 index += _CLOSE_RANGE();
659 index += _State(Context, index, 0x0165C >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
660 index += _State(Context, index, 0x01660 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
662 index += _CLOSE_RANGE();
663 index += _State(Context, index, 0x01664 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
665 index += _CLOSE_RANGE();
666 index += _State(Context, index, 0x01668 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
667 index += _State(Context, index, 0x0166C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
668 index += _CLOSE_RANGE();
669 #endif
671 /**************************************************************************/
672 /* Link to another address. ***********************************************/
674 Context->linkIndex3D = index;
676 if (buffer != gcvNULL)
678 buffer[index + 0]
679 = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
680 | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
682 buffer[index + 1]
683 = 0;
686 index += 2;
688 /* Store the end of the context buffer. */
689 Context->bufferSize = index * gcmSIZEOF(gctUINT32);
692 /**************************************************************************/
693 /* Pipe switch for the case where neither 2D nor 3D are used. *************/
695 /* Store the 3D entry index. */
696 Context->entryOffsetXDFrom2D = index * gcmSIZEOF(gctUINT32);
698 /* Flush 2D pipe. */
699 index += _FlushPipe(Context, index, gcvPIPE_2D);
701 /* Switch to 3D pipe. */
702 index += _SwitchPipe(Context, index, gcvPIPE_3D);
704 /* Store the location of the link. */
705 Context->linkIndexXD = index;
707 if (buffer != gcvNULL)
709 buffer[index + 0]
710 = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
711 | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
713 buffer[index + 1]
714 = 0;
717 index += 2;
720 /**************************************************************************/
721 /* Save size for buffer. **************************************************/
723 Context->totalSize = index * gcmSIZEOF(gctUINT32);
726 /* Success. */
727 return gcvSTATUS_OK;
730 static gceSTATUS
731 _DestroyContext(
732 IN gckCONTEXT Context
735 gceSTATUS status = gcvSTATUS_OK;
737 if (Context != gcvNULL)
739 gcsCONTEXT_PTR bufferHead;
741 /* Free context buffers. */
742 for (bufferHead = Context->buffer; Context->buffer != gcvNULL;)
744 /* Get a shortcut to the current buffer. */
745 gcsCONTEXT_PTR buffer = Context->buffer;
747 /* Get the next buffer. */
748 gcsCONTEXT_PTR next = buffer->next;
750 /* Last item? */
751 if (next == bufferHead)
753 next = gcvNULL;
756 /* Destroy the signal. */
757 if (buffer->signal != gcvNULL)
759 gcmkONERROR(gckOS_DestroySignal(
760 Context->os, buffer->signal
763 buffer->signal = gcvNULL;
766 /* Free state delta map. */
767 if (buffer->logical != gcvNULL)
769 gcmkONERROR(gckOS_FreeContiguous(
770 Context->os,
771 buffer->physical,
772 buffer->logical,
773 Context->totalSize
776 buffer->logical = gcvNULL;
779 /* Free context buffer. */
780 gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, buffer));
782 /* Remove from the list. */
783 Context->buffer = next;
786 #if gcdSECURE_USER
787 /* Free the hint array. */
788 if (Context->hint != gcvNULL)
790 gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, Context->hint));
792 #endif
793 /* Free record array copy. */
794 if (Context->recordArray != gcvNULL)
796 gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, Context->recordArray));
799 /* Free the state mapping. */
800 if (Context->map != gcvNULL)
802 gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, Context->map));
805 /* Mark the gckCONTEXT object as unknown. */
806 Context->object.type = gcvOBJ_UNKNOWN;
808 /* Free the gckCONTEXT object. */
809 gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, Context));
812 OnError:
813 return status;
817 /******************************************************************************\
818 **************************** Context Management API ****************************
819 \******************************************************************************/
821 /******************************************************************************\
823 ** gckCONTEXT_Construct
825 ** Construct a new gckCONTEXT object.
827 ** INPUT:
829 ** gckOS Os
830 ** Pointer to gckOS object.
832 ** gctUINT32 ProcessID
833 ** Current process ID.
835 ** gckHARDWARE Hardware
836 ** Pointer to gckHARDWARE object.
838 ** OUTPUT:
840 ** gckCONTEXT * Context
841 ** Pointer to a variable thet will receive the gckCONTEXT object
842 ** pointer.
844 gceSTATUS
845 gckCONTEXT_Construct(
846 IN gckOS Os,
847 IN gckHARDWARE Hardware,
848 IN gctUINT32 ProcessID,
849 OUT gckCONTEXT * Context
852 gceSTATUS status;
853 gckCONTEXT context = gcvNULL;
854 gctSIZE_T allocationSize;
855 gctUINT i;
856 gctPOINTER pointer = gcvNULL;
858 gcmkHEADER_ARG("Os=0x%08X Hardware=0x%08X", Os, Hardware);
860 /* Verify the arguments. */
861 gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
862 gcmkVERIFY_ARGUMENT(Context != gcvNULL);
865 /**************************************************************************/
866 /* Allocate and initialize basic fields of gckCONTEXT. ********************/
868 /* The context object size. */
869 allocationSize = gcmSIZEOF(struct _gckCONTEXT);
871 /* Allocate the object. */
872 gcmkONERROR(gckOS_Allocate(
873 Os, allocationSize, &pointer
876 context = pointer;
878 /* Reset the entire object. */
879 gcmkONERROR(gckOS_ZeroMemory(context, allocationSize));
881 /* Initialize the gckCONTEXT object. */
882 context->object.type = gcvOBJ_CONTEXT;
883 context->os = Os;
884 context->hardware = Hardware;
887 #if defined(VIVANTE_NO_3D)
888 context->entryPipe = gcvPIPE_2D;
889 context->exitPipe = gcvPIPE_2D;
890 #elif gcdCMD_NO_2D_CONTEXT
891 context->entryPipe = gcvPIPE_3D;
892 context->exitPipe = gcvPIPE_3D;
893 #else
894 context->entryPipe
895 = (((((gctUINT32) (context->hardware->chipFeatures)) >> (0 ? 9:9)) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1)))))) )
896 ? gcvPIPE_2D
897 : gcvPIPE_3D;
898 context->exitPipe = gcvPIPE_3D;
899 #endif
901 /* Get the command buffer requirements. */
902 gcmkONERROR(gckHARDWARE_QueryCommandBuffer(
903 Hardware,
904 &context->alignment,
905 &context->reservedHead,
906 &context->reservedTail
909 /* Mark the context as dirty to force loading of the entire state table
910 the first time. */
911 context->dirty = gcvTRUE;
914 /**************************************************************************/
915 /* Get the size of the context buffer. ************************************/
917 gcmkONERROR(_InitializeContextBuffer(context));
920 /**************************************************************************/
921 /* Compute the size of the record array. **********************************/
923 context->recordArraySize
924 = gcmSIZEOF(gcsSTATE_DELTA_RECORD) * context->stateCount;
927 if (context->stateCount > 0)
929 /**************************************************************************/
930 /* Allocate and reset the state mapping table. ****************************/
932 /* Allocate the state mapping table. */
933 gcmkONERROR(gckOS_Allocate(
935 gcmSIZEOF(gcsSTATE_MAP) * context->stateCount,
936 &pointer
939 context->map = pointer;
941 /* Zero the state mapping table. */
942 gcmkONERROR(gckOS_ZeroMemory(
943 context->map, gcmSIZEOF(gcsSTATE_MAP) * context->stateCount
947 /**************************************************************************/
948 /* Allocate the hint array. ***********************************************/
950 #if gcdSECURE_USER
951 /* Allocate hints. */
952 gcmkONERROR(gckOS_Allocate(
954 gcmSIZEOF(gctBOOL) * context->stateCount,
955 &pointer
958 context->hint = pointer;
959 #endif
962 /**************************************************************************/
963 /* Allocate the context and state delta buffers. **************************/
965 for (i = 0; i < gcdCONTEXT_BUFFER_COUNT; i += 1)
967 /* Allocate a context buffer. */
968 gcsCONTEXT_PTR buffer;
970 /* Allocate the context buffer structure. */
971 gcmkONERROR(gckOS_Allocate(
973 gcmSIZEOF(gcsCONTEXT),
974 &pointer
977 buffer = pointer;
979 /* Reset the context buffer structure. */
980 gcmkVERIFY_OK(gckOS_ZeroMemory(
981 buffer, gcmSIZEOF(gcsCONTEXT)
984 /* Append to the list. */
985 if (context->buffer == gcvNULL)
987 buffer->next = buffer;
988 context->buffer = buffer;
990 else
992 buffer->next = context->buffer->next;
993 context->buffer->next = buffer;
996 /* Set the number of delta in the order of creation. */
997 #if gcmIS_DEBUG(gcdDEBUG_CODE)
998 buffer->num = i;
999 #endif
1001 /* Create the busy signal. */
1002 gcmkONERROR(gckOS_CreateSignal(
1003 Os, gcvFALSE, &buffer->signal
1006 /* Set the signal, buffer is currently not busy. */
1007 gcmkONERROR(gckOS_Signal(
1008 Os, buffer->signal, gcvTRUE
1011 /* Create a new physical context buffer. */
1012 gcmkONERROR(gckOS_AllocateContiguous(
1014 gcvFALSE,
1015 &context->totalSize,
1016 &buffer->physical,
1017 &pointer
1020 buffer->logical = pointer;
1022 /* Set gckEVENT object pointer. */
1023 buffer->eventObj = Hardware->kernel->eventObj;
1025 /* Set the pointers to the LINK commands. */
1026 if (context->linkIndex2D != 0)
1028 buffer->link2D = &buffer->logical[context->linkIndex2D];
1031 if (context->linkIndex3D != 0)
1033 buffer->link3D = &buffer->logical[context->linkIndex3D];
1036 if (context->linkIndexXD != 0)
1038 gctPOINTER xdLink;
1039 gctUINT8_PTR xdEntryLogical;
1040 gctSIZE_T xdEntrySize;
1041 gctSIZE_T linkBytes;
1043 /* Determine LINK parameters. */
1044 xdLink
1045 = &buffer->logical[context->linkIndexXD];
1047 xdEntryLogical
1048 = (gctUINT8_PTR) buffer->logical
1049 + context->entryOffsetXDFrom3D;
1051 xdEntrySize
1052 = context->bufferSize
1053 - context->entryOffsetXDFrom3D;
1055 /* Query LINK size. */
1056 gcmkONERROR(gckHARDWARE_Link(
1057 Hardware, gcvNULL, gcvNULL, 0, &linkBytes
1060 /* Generate a LINK. */
1061 gcmkONERROR(gckHARDWARE_Link(
1062 Hardware,
1063 xdLink,
1064 xdEntryLogical,
1065 xdEntrySize,
1066 &linkBytes
1072 /**************************************************************************/
1073 /* Initialize the context buffers. ****************************************/
1075 /* Initialize the current context buffer. */
1076 gcmkONERROR(_InitializeContextBuffer(context));
1078 /* Make all created contexts equal. */
1080 gcsCONTEXT_PTR currContext, tempContext;
1082 /* Set the current context buffer. */
1083 currContext = context->buffer;
1085 /* Get the next context buffer. */
1086 tempContext = currContext->next;
1088 /* Loop through all buffers. */
1089 while (tempContext != currContext)
1091 if (tempContext == gcvNULL)
1093 gcmkONERROR(gcvSTATUS_NOT_FOUND);
1096 /* Copy the current context. */
1097 gcmkONERROR(gckOS_MemCopy(
1098 tempContext->logical,
1099 currContext->logical,
1100 context->totalSize
1103 /* Get the next context buffer. */
1104 tempContext = tempContext->next;
1108 /* Return pointer to the gckCONTEXT object. */
1109 *Context = context;
1111 /* Success. */
1112 gcmkFOOTER_ARG("*Context=0x%08X", *Context);
1113 return gcvSTATUS_OK;
1115 OnError:
1116 /* Roll back on error. */
1117 gcmkVERIFY_OK(_DestroyContext(context));
1119 /* Return the status. */
1120 gcmkFOOTER();
1121 return status;
1124 /******************************************************************************\
1126 ** gckCONTEXT_Destroy
1128 ** Destroy a gckCONTEXT object.
1130 ** INPUT:
1132 ** gckCONTEXT Context
1133 ** Pointer to an gckCONTEXT object.
1135 ** OUTPUT:
1137 ** Nothing.
1139 gceSTATUS
1140 gckCONTEXT_Destroy(
1141 IN gckCONTEXT Context
1144 gceSTATUS status;
1146 gcmkHEADER_ARG("Context=0x%08X", Context);
1148 /* Verify the arguments. */
1149 gcmkVERIFY_OBJECT(Context, gcvOBJ_CONTEXT);
1151 /* Destroy the context and all related objects. */
1152 status = _DestroyContext(Context);
1154 /* Success. */
1155 gcmkFOOTER_NO();
1156 return status;
1159 /******************************************************************************\
1161 ** gckCONTEXT_Update
1163 ** Merge all pending state delta buffers into the current context buffer.
1165 ** INPUT:
1167 ** gckCONTEXT Context
1168 ** Pointer to an gckCONTEXT object.
1170 ** gctUINT32 ProcessID
1171 ** Current process ID.
1173 ** gcsSTATE_DELTA_PTR StateDelta
1174 ** Pointer to the state delta.
1176 ** OUTPUT:
1178 ** Nothing.
1180 gceSTATUS
1181 gckCONTEXT_Update(
1182 IN gckCONTEXT Context,
1183 IN gctUINT32 ProcessID,
1184 IN gcsSTATE_DELTA_PTR StateDelta
1187 #ifndef VIVANTE_NO_3D
1188 gceSTATUS status = gcvSTATUS_OK;
1189 static gcsSTATE_DELTA _stateDelta;
1190 gckKERNEL kernel;
1191 gcsCONTEXT_PTR buffer;
1192 gcsSTATE_MAP_PTR map;
1193 gctBOOL needCopy = gcvFALSE;
1194 gcsSTATE_DELTA_PTR nDelta;
1195 gcsSTATE_DELTA_PTR uDelta = gcvNULL;
1196 gcsSTATE_DELTA_PTR kDelta = gcvNULL;
1197 gcsSTATE_DELTA_RECORD_PTR record;
1198 gcsSTATE_DELTA_RECORD_PTR recordArray = gcvNULL;
1199 gctUINT elementCount;
1200 gctUINT address;
1201 gctUINT32 mask;
1202 gctUINT32 data;
1203 gctUINT index;
1204 gctUINT i, j;
1206 #if gcdSECURE_USER
1207 gcskSECURE_CACHE_PTR cache;
1208 #endif
1210 gcmkHEADER_ARG(
1211 "Context=0x%08X ProcessID=%d StateDelta=0x%08X",
1212 Context, ProcessID, StateDelta
1215 /* Verify the arguments. */
1216 gcmkVERIFY_OBJECT(Context, gcvOBJ_CONTEXT);
1218 /* Get a shortcut to the kernel object. */
1219 kernel = Context->hardware->kernel;
1221 /* Check wehther we need to copy the structures or not. */
1222 gcmkONERROR(gckOS_QueryNeedCopy(Context->os, ProcessID, &needCopy));
1224 /* Allocate the copy buffer for the user record array. */
1225 if (needCopy && (Context->recordArray == gcvNULL))
1227 /* Allocate the buffer. */
1228 gcmkONERROR(gckOS_Allocate(
1229 Context->os,
1230 Context->recordArraySize,
1231 (gctPOINTER *) &Context->recordArray
1235 /* Get the current context buffer. */
1236 buffer = Context->buffer;
1238 /* Wait until the context buffer becomes available; this will
1239 also reset the signal and mark the buffer as busy. */
1240 gcmkONERROR(gckOS_WaitSignal(
1241 Context->os, buffer->signal, gcvINFINITE
1244 #if gcdSECURE_USER
1245 /* Get the cache form the database. */
1246 gcmkONERROR(gckKERNEL_GetProcessDBCache(kernel, ProcessID, &cache));
1247 #endif
1249 #if gcmIS_DEBUG(gcdDEBUG_CODE) && 1 && !defined(VIVANTE_NO_3D)
1250 /* Update current context token. */
1251 buffer->logical[Context->map[0x0E14].index]
1252 = gcmPTR2INT(Context);
1253 #endif
1255 /* Are there any pending deltas? */
1256 if (buffer->deltaCount != 0)
1258 /* Get the state map. */
1259 map = Context->map;
1261 /* Get the first delta item. */
1262 uDelta = buffer->delta;
1264 /* Reset the vertex stream count. */
1265 elementCount = 0;
1267 /* Merge all pending deltas. */
1268 for (i = 0; i < buffer->deltaCount; i += 1)
1270 /* Get access to the state delta. */
1271 gcmkONERROR(gckKERNEL_OpenUserData(
1272 kernel, needCopy,
1273 &_stateDelta,
1274 uDelta, gcmSIZEOF(gcsSTATE_DELTA),
1275 (gctPOINTER *) &kDelta
1278 /* Get access to the state records. */
1279 gcmkONERROR(gckKERNEL_OpenUserData(
1280 kernel, needCopy,
1281 Context->recordArray,
1282 kDelta->recordArray, Context->recordArraySize,
1283 (gctPOINTER *) &recordArray
1286 /* Merge all pending states. */
1287 for (j = 0; j < kDelta->recordCount; j += 1)
1289 /* Get the current state record. */
1290 record = &recordArray[j];
1292 /* Get the state address. */
1293 address = record->address;
1295 /* Make sure the state is a part of the mapping table. */
1296 if (address >= Context->stateCount)
1298 gcmkTRACE(
1299 gcvLEVEL_ERROR,
1300 "%s(%d): State 0x%04X is not mapped.\n",
1301 __FUNCTION__, __LINE__,
1302 address
1305 continue;
1308 /* Get the state index. */
1309 index = map[address].index;
1311 /* Skip the state if not mapped. */
1312 if (index == 0)
1314 continue;
1317 /* Get the data mask. */
1318 mask = record->mask;
1320 /* Masked states that are being completly reset or regular states. */
1321 if ((mask == 0) || (mask == ~0U))
1323 /* Get the new data value. */
1324 data = record->data;
1326 /* Process special states. */
1327 if (address == 0x0595)
1329 /* Force auto-disable to be disabled. */
1330 data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)));
1331 data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
1332 data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 13:13) - (0 ? 13:13) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 13:13) - (0 ? 13:13) + 1))))))) << (0 ? 13:13))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 13:13) - (0 ? 13:13) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 13:13) - (0 ? 13:13) + 1))))))) << (0 ? 13:13)));
1335 #if gcdSECURE_USER
1336 /* Do we need to convert the logical address? */
1337 if (Context->hint[address])
1339 /* Map handle into physical address. */
1340 gcmkONERROR(gckKERNEL_MapLogicalToPhysical(
1341 kernel, cache, (gctPOINTER) &data
1344 #endif
1346 /* Set new data. */
1347 buffer->logical[index] = data;
1350 /* Masked states that are being set partially. */
1351 else
1353 buffer->logical[index]
1354 = (~mask & buffer->logical[index])
1355 | (mask & record->data);
1359 /* Get the element count. */
1360 if (kDelta->elementCount != 0)
1362 elementCount = kDelta->elementCount;
1365 /* Dereference delta. */
1366 kDelta->refCount -= 1;
1367 gcmkASSERT(kDelta->refCount >= 0);
1369 /* Get the next state delta. */
1370 nDelta = kDelta->next;
1372 /* Get access to the state records. */
1373 gcmkONERROR(gckKERNEL_CloseUserData(
1374 kernel, needCopy,
1375 gcvFALSE,
1376 kDelta->recordArray, Context->recordArraySize,
1377 (gctPOINTER *) &recordArray
1380 /* Close access to the current state delta. */
1381 gcmkONERROR(gckKERNEL_CloseUserData(
1382 kernel, needCopy,
1383 gcvTRUE,
1384 uDelta, gcmSIZEOF(gcsSTATE_DELTA),
1385 (gctPOINTER *) &kDelta
1388 /* Update the user delta pointer. */
1389 uDelta = nDelta;
1392 /* Hardware disables all input streams when the stream 0 is programmed,
1393 it then reenables those streams that were explicitely programmed by
1394 the software. Because of this we cannot program the entire array of
1395 values, otherwise we'll get all streams reenabled, but rather program
1396 only those that are actully needed by the software. */
1397 if (elementCount != 0)
1399 gctUINT base;
1400 gctUINT nopCount;
1401 gctUINT32_PTR nop;
1402 gctUINT fe2vsCount = 12;
1404 if ((((((gctUINT32) (Context->hardware->chipMinorFeatures1)) >> (0 ? 23:23)) & ((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1)))))) ))
1406 fe2vsCount = 16;
1409 /* Determine the base index of the vertex stream array. */
1410 base = map[0x0180].index;
1412 /* Set the proper state count. */
1413 buffer->logical[base - 1]
1414 = ((((gctUINT32) (buffer->logical[base - 1])) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (elementCount ) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
1416 /* Determine the number of NOP commands. */
1417 nopCount
1418 = (fe2vsCount / 2)
1419 - (elementCount / 2);
1421 /* Determine the location of the first NOP. */
1422 nop = &buffer->logical[base + (elementCount | 1)];
1424 /* Fill the unused space with NOPs. */
1425 for (i = 0; i < nopCount; i += 1)
1427 /* Generate a NOP command. */
1428 *nop = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
1430 /* Advance. */
1431 nop += 2;
1435 /* Reset pending deltas. */
1436 buffer->deltaCount = 0;
1437 buffer->delta = gcvNULL;
1440 /* Set state delta user pointer. */
1441 uDelta = StateDelta;
1443 /* Get access to the state delta. */
1444 gcmkONERROR(gckKERNEL_OpenUserData(
1445 kernel, needCopy,
1446 &_stateDelta,
1447 uDelta, gcmSIZEOF(gcsSTATE_DELTA),
1448 (gctPOINTER *) &kDelta
1451 /* State delta cannot be attached to anything yet. */
1452 if (kDelta->refCount != 0)
1454 gcmkTRACE(
1455 gcvLEVEL_ERROR,
1456 "%s(%d): kDelta->refCount = %d (has to be 0).\n",
1457 __FUNCTION__, __LINE__,
1458 kDelta->refCount
1462 /* Attach to all contexts. */
1463 buffer = Context->buffer;
1467 /* Attach to the context if nothing is attached yet. If a delta
1468 is allready attached, all we need to do is to increment
1469 the number of deltas in the context. */
1470 if (buffer->delta == gcvNULL)
1472 buffer->delta = uDelta;
1475 /* Update reference count. */
1476 kDelta->refCount += 1;
1478 /* Update counters. */
1479 buffer->deltaCount += 1;
1481 /* Get the next context buffer. */
1482 buffer = buffer->next;
1484 if (buffer == gcvNULL)
1486 gcmkONERROR(gcvSTATUS_NOT_FOUND);
1489 while (Context->buffer != buffer);
1491 /* Close access to the current state delta. */
1492 gcmkONERROR(gckKERNEL_CloseUserData(
1493 kernel, needCopy,
1494 gcvTRUE,
1495 uDelta, gcmSIZEOF(gcsSTATE_DELTA),
1496 (gctPOINTER *) &kDelta
1499 /* Schedule an event to mark the context buffer as available. */
1500 gcmkONERROR(gckEVENT_Signal(
1501 buffer->eventObj, buffer->signal, gcvKERNEL_PIXEL
1504 /* Advance to the next context buffer. */
1505 Context->buffer = buffer->next;
1507 /* Return the status. */
1508 gcmkFOOTER();
1509 return gcvSTATUS_OK;
1511 OnError:
1512 /* Get access to the state records. */
1513 if (kDelta != gcvNULL)
1515 gcmkVERIFY_OK(gckKERNEL_CloseUserData(
1516 kernel, needCopy,
1517 gcvFALSE,
1518 kDelta->recordArray, Context->recordArraySize,
1519 (gctPOINTER *) &recordArray
1523 /* Close access to the current state delta. */
1524 gcmkVERIFY_OK(gckKERNEL_CloseUserData(
1525 kernel, needCopy,
1526 gcvTRUE,
1527 uDelta, gcmSIZEOF(gcsSTATE_DELTA),
1528 (gctPOINTER *) &kDelta
1531 /* Return the status. */
1532 gcmkFOOTER();
1533 return status;
1534 #else
1535 return gcvSTATUS_OK;
1536 #endif