Tizen 2.0 Release
[profile/ivi/osmesa.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