Merge branch 'lp-offset-twoside'
[mesa.git] / src / mesa / drivers / dri / r600 / r700_shader.c
1 /*
2 * Copyright (C) 2008-2009 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 */
21
22 /*
23 * Authors:
24 * Richard Li <RichardZ.Li@amd.com>, <richardradeon@gmail.com>
25 */
26
27 #include <stdio.h>
28 #include <stdarg.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <math.h>
32
33 #include "main/imports.h"
34
35 #include "main/glheader.h"
36
37 #include "r600_context.h"
38
39 #include "r700_shader.h"
40
41 void r700ShaderInit(struct gl_context * ctx)
42 {
43 }
44
45 void AddInstToList(TypedShaderList * plstCFInstructions, R700ShaderInstruction * pInst)
46 {
47 if(NULL == plstCFInstructions->pTail)
48 { //first
49 plstCFInstructions->pHead = pInst;
50 plstCFInstructions->pTail = pInst;
51 }
52 else
53 {
54 plstCFInstructions->pTail->pNextInst = pInst;
55 plstCFInstructions->pTail = pInst;
56 }
57 pInst->pNextInst = NULL;
58
59 plstCFInstructions->uNumOfNode++;
60 }
61
62 void TakeInstOutFromList(TypedShaderList * plstCFInstructions, R700ShaderInstruction * pInst)
63 {
64 GLuint ulIndex = 0;
65 GLboolean bFound = GL_FALSE;
66 R700ShaderInstruction * pPrevInst = NULL;
67 R700ShaderInstruction * pCurInst = plstCFInstructions->pHead;
68
69 /* Need go thro list to make sure pInst is there. */
70 while(NULL != pCurInst)
71 {
72 if(pCurInst == pInst)
73 {
74 bFound = GL_TRUE;
75 break;
76 }
77
78 pPrevInst = pCurInst;
79 pCurInst = pCurInst->pNextInst;
80 }
81 if(GL_TRUE == bFound)
82 {
83 plstCFInstructions->uNumOfNode--;
84
85 pCurInst = pInst->pNextInst;
86 ulIndex = pInst->m_uIndex;
87 while(NULL != pCurInst)
88 {
89 pCurInst->m_uIndex = ulIndex;
90 ulIndex++;
91 pCurInst = pCurInst->pNextInst;
92 }
93
94 if(plstCFInstructions->pHead == pInst)
95 {
96 plstCFInstructions->pHead = pInst->pNextInst;
97 }
98 if(plstCFInstructions->pTail == pInst)
99 {
100 plstCFInstructions->pTail = pPrevInst;
101 }
102 if(NULL != pPrevInst)
103 {
104 pPrevInst->pNextInst = pInst->pNextInst;
105 }
106
107 FREE(pInst);
108 }
109 }
110
111 void Init_R700_Shader(R700_Shader * pShader)
112 {
113 pShader->Type = R700_SHADER_INVALID;
114 pShader->pProgram = NULL;
115 pShader->bBinaryShader = GL_FALSE;
116 pShader->bFetchShaderRequired = GL_FALSE;
117 pShader->bNeedsAssembly = GL_FALSE;
118 pShader->bLinksDirty = GL_TRUE;
119 pShader->uShaderBinaryDWORDSize = 0;
120 pShader->nRegs = 0;
121 pShader->nParamExports = 0;
122 pShader->nMemExports = 0;
123 pShader->resource = 0;
124
125 pShader->exportMode = 0;
126 pShader->depthIsImported = GL_FALSE;
127
128 pShader->positionVectorIsExported = GL_FALSE;
129 pShader->miscVectorIsExported = GL_FALSE;
130 pShader->renderTargetArrayIndexIsExported = GL_FALSE;
131 pShader->ccDist0VectorIsExported = GL_FALSE;
132 pShader->ccDist1VectorIsExported = GL_FALSE;
133
134
135 pShader->depthIsExported = GL_FALSE;
136 pShader->stencilRefIsExported = GL_FALSE;
137 pShader->coverageToMaskIsExported = GL_FALSE;
138 pShader->maskIsExported = GL_FALSE;
139 pShader->killIsUsed = GL_FALSE;
140
141 pShader->uCFOffset = 0;
142 pShader->uStackSize = 0;
143 pShader->uMaxCallDepth = 0;
144
145 pShader->bSurfAllocated = GL_FALSE;
146
147 pShader->lstCFInstructions.pHead=NULL;
148 pShader->lstCFInstructions.pTail=NULL;
149 pShader->lstCFInstructions.uNumOfNode=0;
150 pShader->lstALUInstructions.pHead=NULL;
151 pShader->lstALUInstructions.pTail=NULL;
152 pShader->lstALUInstructions.uNumOfNode=0;
153 pShader->lstTEXInstructions.pHead=NULL;
154 pShader->lstTEXInstructions.pTail=NULL;
155 pShader->lstTEXInstructions.uNumOfNode=0;
156 pShader->lstVTXInstructions.pHead=NULL;
157 pShader->lstVTXInstructions.pTail=NULL;
158 pShader->lstVTXInstructions.uNumOfNode=0;
159 }
160
161 void SetActiveCFlist(R700_Shader *pShader, TypedShaderList * plstCF)
162 {
163 pShader->plstCFInstructions_active = plstCF;
164 }
165
166 void AddCFInstruction(R700_Shader *pShader, R700ControlFlowInstruction *pCFInst)
167 {
168 R700ControlFlowSXClause* pSXClause;
169 R700ControlFlowSMXClause* pSMXClause;
170
171 pCFInst->m_uIndex = pShader->plstCFInstructions_active->uNumOfNode;
172 AddInstToList(pShader->plstCFInstructions_active,
173 (R700ShaderInstruction*)pCFInst);
174 pShader->uShaderBinaryDWORDSize += GetInstructionSize(pCFInst->m_ShaderInstType);
175
176 pSXClause = NULL;
177 pSMXClause = NULL;
178 switch (pCFInst->m_ShaderInstType)
179 {
180 case SIT_CF_ALL_EXP_SX:
181 pSXClause = (R700ControlFlowSXClause*)pCFInst;
182 break;
183 case SIT_CF_ALL_EXP_SMX:
184 pSMXClause = (R700ControlFlowSMXClause*)pCFInst;
185 break;
186 default:
187 break;
188 };
189
190 if((pSXClause != NULL) && (pSXClause->m_Word0.f.type == SQ_EXPORT_PARAM))
191 {
192 pShader->nParamExports += pSXClause->m_Word1.f.burst_count + 1;
193 }
194 else if ((pSMXClause != NULL) && (pSMXClause->m_Word1.f.cf_inst == SQ_CF_INST_MEM_RING) &&
195 (pSMXClause->m_Word0.f.type == SQ_EXPORT_WRITE || pSMXClause->m_Word0.f.type == SQ_EXPORT_WRITE_IND))
196 {
197 pShader->nMemExports += pSMXClause->m_Word1.f.burst_count + 1;
198 }
199
200 pShader->bLinksDirty = GL_TRUE;
201 pShader->bNeedsAssembly = GL_TRUE;
202
203 pCFInst->useCount++;
204 }
205
206 void AddVTXInstruction(R700_Shader *pShader, R700VertexInstruction *pVTXInst)
207 {
208 pVTXInst->m_uIndex = pShader->lstVTXInstructions.uNumOfNode;
209 AddInstToList(&(pShader->lstVTXInstructions),
210 (R700ShaderInstruction*)pVTXInst);
211 pShader->uShaderBinaryDWORDSize += GetInstructionSize(pVTXInst->m_ShaderInstType);
212
213 if(pVTXInst->m_ShaderInstType == SIT_VTX_GENERIC)
214 {
215 R700VertexGenericFetch* pVTXGenericClause = (R700VertexGenericFetch*)pVTXInst;
216 pShader->nRegs = (pShader->nRegs < pVTXGenericClause->m_Word1_GPR.f.dst_gpr) ? pVTXGenericClause->m_Word1_GPR.f.dst_gpr : pShader->nRegs;
217 }
218
219 pShader->bLinksDirty = GL_TRUE;
220 pShader->bNeedsAssembly = GL_TRUE;
221
222 pVTXInst->useCount++;
223 }
224
225 void AddTEXInstruction(R700_Shader *pShader, R700TextureInstruction *pTEXInst)
226 {
227 pTEXInst->m_uIndex = pShader->lstTEXInstructions.uNumOfNode;
228 AddInstToList(&(pShader->lstTEXInstructions),
229 (R700ShaderInstruction*)pTEXInst);
230 pShader->uShaderBinaryDWORDSize += GetInstructionSize(pTEXInst->m_ShaderInstType);
231
232 pShader->nRegs = (pShader->nRegs < pTEXInst->m_Word1.f.dst_gpr) ? pTEXInst->m_Word1.f.dst_gpr : pShader->nRegs;
233
234 pShader->bLinksDirty = GL_TRUE;
235 pShader->bNeedsAssembly = GL_TRUE;
236
237 pTEXInst->useCount++;
238 }
239
240 void AddALUInstruction(R700_Shader *pShader, R700ALUInstruction *pALUInst)
241 {
242 pALUInst->m_uIndex = pShader->lstALUInstructions.uNumOfNode;
243 AddInstToList(&(pShader->lstALUInstructions),
244 (R700ShaderInstruction*)pALUInst);
245 pShader->uShaderBinaryDWORDSize += GetInstructionSize(pALUInst->m_ShaderInstType);
246
247 pShader->nRegs = (pShader->nRegs < pALUInst->m_Word1.f.dst_gpr) ? pALUInst->m_Word1.f.dst_gpr : pShader->nRegs;
248
249 pShader->bLinksDirty = GL_TRUE;
250 pShader->bNeedsAssembly = GL_TRUE;
251
252 pALUInst->useCount++;
253 }
254
255 void ResolveLinks(R700_Shader *pShader)
256 {
257 GLuint uiSize;
258 R700ShaderInstruction *pInst;
259 R700ALUInstruction *pALUinst;
260 R700TextureInstruction *pTEXinst;
261 R700VertexInstruction *pVTXinst;
262
263 GLuint vtxOffset;
264
265 GLuint cfOffset = 0x0;
266
267 GLuint aluOffset = cfOffset + pShader->lstCFInstructions.uNumOfNode * GetInstructionSize(SIT_CF);
268
269 GLuint texOffset = aluOffset; // + m_lstALUInstructions.size() * R700ALUInstruction::SIZE,
270
271 pInst = pShader->lstALUInstructions.pHead;
272 while(NULL != pInst)
273 {
274 texOffset += GetInstructionSize(pInst->m_ShaderInstType);
275
276 pInst = pInst->pNextInst;
277 };
278
279 vtxOffset = texOffset + pShader->lstTEXInstructions.uNumOfNode * GetInstructionSize(SIT_TEX);
280
281 if ( ((pShader->lstTEXInstructions.uNumOfNode > 0) && (texOffset % 4 != 0)) ||
282 ((pShader->lstVTXInstructions.uNumOfNode > 0) && (vtxOffset % 4 != 0)) )
283 {
284 pALUinst = (R700ALUInstruction*) CALLOC_STRUCT(R700ALUInstruction);
285 Init_R700ALUInstruction(pALUinst);
286 AddALUInstruction(pShader, pALUinst);
287 texOffset += GetInstructionSize(SIT_ALU);
288 vtxOffset += GetInstructionSize(SIT_ALU);
289 }
290
291 pInst = pShader->lstALUInstructions.pHead;
292 uiSize = 0;
293 while(NULL != pInst)
294 {
295 pALUinst = (R700ALUInstruction*)pInst;
296
297 if(pALUinst->m_pLinkedALUClause != NULL)
298 {
299 // This address is quad-word aligned
300 pALUinst->m_pLinkedALUClause->m_Word0.f.addr = (aluOffset + uiSize) >> 1;
301 }
302
303 uiSize += GetInstructionSize(pALUinst->m_ShaderInstType);
304
305 pInst = pInst->pNextInst;
306 };
307
308 pInst = pShader->lstTEXInstructions.pHead;
309 uiSize = 0;
310 while(NULL != pInst)
311 {
312 pTEXinst = (R700TextureInstruction*)pInst;
313
314 if (pTEXinst->m_pLinkedGenericClause != NULL)
315 {
316 pTEXinst->m_pLinkedGenericClause->m_Word0.f.addr = (texOffset + uiSize) >> 1;
317 }
318
319 uiSize += GetInstructionSize(pTEXinst->m_ShaderInstType);
320
321 pInst = pInst->pNextInst;
322 };
323
324 pInst = pShader->lstVTXInstructions.pHead;
325 uiSize = 0;
326 while(NULL != pInst)
327 {
328 pVTXinst = (R700VertexInstruction*)pInst;
329
330 if (pVTXinst->m_pLinkedGenericClause != NULL)
331 {
332 pVTXinst->m_pLinkedGenericClause->m_Word0.f.addr = (vtxOffset + uiSize) >> 1;
333 }
334
335 uiSize += GetInstructionSize(pVTXinst->m_ShaderInstType);
336
337 pInst = pInst->pNextInst;
338 };
339
340 pShader->bLinksDirty = GL_FALSE;
341 }
342
343 void Assemble(R700_Shader *pShader)
344 {
345 GLuint i;
346 GLuint *pShaderBinary;
347 GLuint size_of_program;
348 GLuint *pCurrPos;
349
350 GLuint end_of_cf_instructions;
351 GLuint number_of_alu_dwords;
352
353 R700ShaderInstruction *pInst;
354
355 if(GL_TRUE == pShader->bBinaryShader)
356 {
357 return;
358 }
359
360 if(pShader->bLinksDirty == GL_TRUE)
361 {
362 ResolveLinks(pShader);
363 }
364
365 size_of_program = pShader->uShaderBinaryDWORDSize;
366
367 pShaderBinary = (GLuint*) MALLOC(sizeof(GLuint)*size_of_program);
368
369 pCurrPos = pShaderBinary;
370
371 for (i = 0; i < size_of_program; i++)
372 {
373 pShaderBinary[i] = 0;
374 }
375
376 pInst = pShader->lstCFInstructions.pHead;
377 while(NULL != pInst)
378 {
379 switch (pInst->m_ShaderInstType)
380 {
381 case SIT_CF_GENERIC:
382 {
383 R700ControlFlowGenericClause* pCFgeneric = (R700ControlFlowGenericClause*)pInst;
384 *pCurrPos++ = pCFgeneric->m_Word0.val;
385 *pCurrPos++ = pCFgeneric->m_Word1.val;
386 }
387 break;
388 case SIT_CF_ALU:
389 {
390 R700ControlFlowALUClause* pCFalu = (R700ControlFlowALUClause*)pInst;
391 *pCurrPos++ = pCFalu->m_Word0.val;
392 *pCurrPos++ = pCFalu->m_Word1.val;
393 }
394 break;
395 case SIT_CF_ALL_EXP_SX:
396 {
397 R700ControlFlowSXClause* pCFsx = (R700ControlFlowSXClause*)pInst;
398 *pCurrPos++ = pCFsx->m_Word0.val;
399 *pCurrPos++ = (pCFsx->m_Word1.val | pCFsx->m_Word1_SWIZ.val);
400 }
401 break;
402 case SIT_CF_ALL_EXP_SMX:
403 {
404 R700ControlFlowSMXClause* pCFsmx = (R700ControlFlowSMXClause*)pInst;
405 *pCurrPos++ = pCFsmx->m_Word0.val;
406 *pCurrPos++ = (pCFsmx->m_Word1.val | pCFsmx->m_Word1_BUF.val);
407 }
408 break;
409 default:
410 break;
411 }
412
413 pInst = pInst->pNextInst;
414 };
415
416 number_of_alu_dwords = 0;
417 pInst = pShader->lstALUInstructions.pHead;
418 while(NULL != pInst)
419 {
420 switch (pInst->m_ShaderInstType)
421 {
422 case SIT_ALU:
423 {
424 R700ALUInstruction* pALU = (R700ALUInstruction*)pInst;
425
426 *pCurrPos++ = pALU->m_Word0.val;
427 *pCurrPos++ = (pALU->m_Word1.val | pALU->m_Word1_OP2.val | pALU->m_Word1_OP3.val);
428
429 number_of_alu_dwords += 2;
430 }
431 break;
432 case SIT_ALU_HALF_LIT:
433 {
434 R700ALUInstructionHalfLiteral* pALUhalf = (R700ALUInstructionHalfLiteral*)pInst;
435
436 *pCurrPos++ = pALUhalf->m_Word0.val;
437 *pCurrPos++ = (pALUhalf->m_Word1.val | pALUhalf->m_Word1_OP2.val | pALUhalf->m_Word1_OP3.val);
438 *pCurrPos++ = *((GLuint*)&(pALUhalf->m_fLiteralX));
439 *pCurrPos++ = *((GLuint*)&(pALUhalf->m_fLiteralY));
440
441 number_of_alu_dwords += 4;
442 }
443 break;
444 case SIT_ALU_FALL_LIT:
445 {
446 R700ALUInstructionFullLiteral* pALUfull = (R700ALUInstructionFullLiteral*)pInst;
447
448 *pCurrPos++ = pALUfull->m_Word0.val;
449 *pCurrPos++ = (pALUfull->m_Word1.val | pALUfull->m_Word1_OP2.val | pALUfull->m_Word1_OP3.val);
450
451 *pCurrPos++ = *((GLuint*)&(pALUfull->m_fLiteralX));
452 *pCurrPos++ = *((GLuint*)&(pALUfull->m_fLiteralY));
453 *pCurrPos++ = *((GLuint*)&(pALUfull->m_fLiteralZ));
454 *pCurrPos++ = *((GLuint*)&(pALUfull->m_fLiteralW));
455
456 number_of_alu_dwords += 6;
457 }
458 break;
459 default:
460 break;
461 }
462
463 pInst = pInst->pNextInst;
464 };
465
466 pInst = pShader->lstTEXInstructions.pHead;
467 while(NULL != pInst)
468 {
469 R700TextureInstruction* pTEX = (R700TextureInstruction*)pInst;
470
471 *pCurrPos++ = pTEX->m_Word0.val;
472 *pCurrPos++ = pTEX->m_Word1.val;
473 *pCurrPos++ = pTEX->m_Word2.val;
474 *pCurrPos++ = 0x0beadeaf;
475
476 pInst = pInst->pNextInst;
477 };
478
479 pInst = pShader->lstVTXInstructions.pHead;
480 while(NULL != pInst)
481 {
482 switch (pInst->m_ShaderInstType)
483 {
484 case SIT_VTX_SEM: //
485 {
486 R700VertexSemanticFetch* pVTXsem = (R700VertexSemanticFetch*)pInst;
487
488 *pCurrPos++ = pVTXsem->m_Word0.val;
489 *pCurrPos++ = (pVTXsem->m_Word1.val | pVTXsem->m_Word1_SEM.val);
490 *pCurrPos++ = pVTXsem->m_Word2.val;
491 *pCurrPos++ = 0x0beadeaf;
492 }
493 break;
494 case SIT_VTX_GENERIC: //
495 {
496 R700VertexGenericFetch* pVTXgeneric = (R700VertexGenericFetch*)pInst;
497
498 *pCurrPos++ = pVTXgeneric->m_Word0.val;
499 *pCurrPos++ = (pVTXgeneric->m_Word1.val | pVTXgeneric->m_Word1_GPR.val);
500 *pCurrPos++ = pVTXgeneric->m_Word2.val;
501 *pCurrPos++ = 0x0beadeaf;
502 }
503 break;
504 default:
505 break;
506 }
507
508 pInst = pInst->pNextInst;
509 };
510
511 if(NULL != pShader->pProgram)
512 {
513 FREE(pShader->pProgram);
514 }
515 pShader->pProgram = (GLubyte*)pShaderBinary;
516
517 end_of_cf_instructions = pShader->uCFOffset + pShader->lstCFInstructions.uNumOfNode * GetInstructionSize(SIT_CF);
518
519 pShader->uEndOfCF = end_of_cf_instructions >> 1;
520
521 pShader->uEndOfALU = (end_of_cf_instructions + number_of_alu_dwords) >> 1;
522
523 pShader->uEndOfFetch = (pShader->uCFOffset + pShader->uShaderBinaryDWORDSize) >> 1;
524
525 pShader->bNeedsAssembly = GL_FALSE;
526 }
527
528 void LoadProgram(R700_Shader *pShader) //context
529 {
530 }
531
532 void UpdateShaderRegisters(R700_Shader *pShader) //context
533 {
534 }
535
536 void DeleteInstructions(R700_Shader *pShader)
537 {
538 }
539
540 void DebugPrint(void)
541 {
542 }
543
544 void cleanup_vfetch_shaderinst(R700_Shader *pShader)
545 {
546 R700ShaderInstruction *pInst;
547 R700ShaderInstruction *pInstToFree;
548 R700VertexInstruction *pVTXInst;
549 R700ControlFlowInstruction *pCFInst;
550
551 pInst = pShader->lstVTXInstructions.pHead;
552 while(NULL != pInst)
553 {
554 pVTXInst = (R700VertexInstruction *)pInst;
555 pShader->uShaderBinaryDWORDSize -= GetInstructionSize(pVTXInst->m_ShaderInstType);
556
557 if(NULL != pVTXInst->m_pLinkedGenericClause)
558 {
559 pCFInst = (R700ControlFlowInstruction*)(pVTXInst->m_pLinkedGenericClause);
560
561 TakeInstOutFromList(&(pShader->lstCFInstructions),
562 (R700ShaderInstruction*)pCFInst);
563
564 pShader->uShaderBinaryDWORDSize -= GetInstructionSize(pCFInst->m_ShaderInstType);
565 }
566
567 pInst = pInst->pNextInst;
568 };
569
570 //destroy each item in pShader->lstVTXInstructions;
571 pInst = pShader->lstVTXInstructions.pHead;
572 while(NULL != pInst)
573 {
574 pInstToFree = pInst;
575 pInst = pInst->pNextInst;
576 FREE(pInstToFree);
577 };
578
579 //set NULL pShader->lstVTXInstructions
580 pShader->lstVTXInstructions.pHead=NULL;
581 pShader->lstVTXInstructions.pTail=NULL;
582 pShader->lstVTXInstructions.uNumOfNode=0;
583 }
584
585 void Clean_Up_Shader(R700_Shader *pShader)
586 {
587 if(NULL != pShader->pProgram)
588 {
589 FREE(pShader->pProgram);
590 pShader->pProgram = NULL;
591 }
592
593 R700ShaderInstruction *pInst;
594 R700ShaderInstruction *pInstToFree;
595
596 pInst = pShader->lstCFInstructions.pHead;
597 while(NULL != pInst)
598 {
599 pInstToFree = pInst;
600 pInst = pInst->pNextInst;
601 FREE(pInstToFree);
602 };
603 pShader->lstCFInstructions.pHead = NULL;
604
605 pInst = pShader->lstALUInstructions.pHead;
606 while(NULL != pInst)
607 {
608 pInstToFree = pInst;
609 pInst = pInst->pNextInst;
610 FREE(pInstToFree);
611 };
612 pShader->lstALUInstructions.pHead = NULL;
613
614 pInst = pShader->lstTEXInstructions.pHead;
615 while(NULL != pInst)
616 {
617 pInstToFree = pInst;
618 pInst = pInst->pNextInst;
619 FREE(pInstToFree);
620 };
621 pShader->lstTEXInstructions.pHead = NULL;
622
623 pInst = pShader->lstVTXInstructions.pHead;
624 while(NULL != pInst)
625 {
626 pInstToFree = pInst;
627 pInst = pInst->pNextInst;
628 FREE(pInstToFree);
629 };
630 pShader->lstVTXInstructions.pHead = NULL;
631 }
632