My Project
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules
shdr.c
Go to the documentation of this file.
1 /*
2  shdr.c _ Shader loader.
3 */
4 
5 #include <stdlib.h>
6 #include <string.h>
7 #include <3ds.h>
8 
9 
10 //please don't feed this an invalid SHBIN
11 DVLB_s* SHDR_ParseSHBIN(u32* shbinData, u32 shbinSize)
12 {
13  if(!shbinData)return NULL;
14  DVLB_s* ret=malloc(sizeof(DVLB_s));
15  if(!ret)goto exit;
16 
17  //parse DVLB
18  ret->numDVLE=shbinData[1];
19  ret->DVLE=malloc(sizeof(DVLE_s)*ret->numDVLE);
20  if(!ret->DVLE)goto clean1;
21 
22  //parse DVLP
23  u32* dvlpData=&shbinData[2+ret->numDVLE];
24  ret->DVLP.codeSize=dvlpData[3];
25  ret->DVLP.codeData=&dvlpData[dvlpData[2]/4];
26  ret->DVLP.opdescSize=dvlpData[5];
27  ret->DVLP.opcdescData=&dvlpData[dvlpData[4]/4];
28 
29  //parse DVLE
30  int i;
31  for(i=0;i<ret->numDVLE;i++)
32  {
33  DVLE_s* dvle=&ret->DVLE[i];
34  u32* dvleData=&shbinData[shbinData[2+i]/4];
35 
36  dvle->type=(dvleData[1]>>16)&0xFF;
37  dvle->mainOffset=dvleData[2];
38  dvle->endmainOffset=dvleData[3];
39 
40  dvle->constTableSize=dvleData[7];
41  dvle->constTableData=(DVLE_constEntry_s*)&dvleData[dvleData[6]/4];
42 
43  dvle->outTableSize=dvleData[11];
44  dvle->outTableData=(DVLE_outEntry_s*)&dvleData[dvleData[10]/4];
45 
46  dvle->uniformTableSize=dvleData[13];
47  dvle->uniformTableData=(DVLE_uniformEntry_s*)&dvleData[dvleData[12]/4];
48 
49  dvle->symbolTableData=(char*)&dvleData[dvleData[14]/4];
50  }
51 
52  goto exit;
53  clean1:
54  free(ret);
55  exit:
56  return ret;
57 }
58 
59 s8 SHDR_GetUniformRegister(DVLB_s* dvlb, const char* name, u8 programID)
60 {
61  if(!dvlb || !name)return -1;
62 
63  DVLE_s* dvle=&dvlb->DVLE[programID];
64 
65  int i; DVLE_uniformEntry_s* u=dvle->uniformTableData;
66  for(i=0;i<dvle->uniformTableSize;i++)
67  {
68  if(!strcmp(&dvle->symbolTableData[u->symbolOffset],name))return (s8)u->startReg;
69  u++;
70  }
71  return -1;
72 }
73 
74 //hm
75 static inline u8 minu8(u8 a, u8 b)
76 {
77  if(a<b)return a;
78  return b;
79 }
80 static inline u8 maxu8(u8 a, u8 b)
81 {
82  if(a<b)return b;
83  return a;
84 }
85 
86 void DVLP_SendCode(DVLP_s* dvlp)
87 {
88  if(!dvlp)return;
89 
90  GPUCMD_AddSingleParam(0x000F02CB, 0x00000000);
91 
92  int i;
93  // for(i=0;i<dvlp->codeSize;i+=0x80)GPUCMD_Add(0x000F02CC, &dvlp->codeData[i], ((dvlp->codeSize-i)<0x80)?(dvlp->codeSize-i):0x80);
94  for(i=0;i<dvlp->codeSize;i+=0x80)GPUCMD_Add(0x000F02CC, &dvlp->codeData[i], maxu8(minu8(dvlp->codeSize-i,0x80),0x37)); //not sure why, but anything smaller than 0x37 seems to break stuff atm...
95 
96  GPUCMD_AddSingleParam(0x000F02BF, 0x00000001);
97 }
98 
100 {
101  if(!dvlp)return;
102 
103  GPUCMD_AddSingleParam(0x000F02D5, 0x00000000);
104 
105  u32 param[0x20];
106 
107  int i;
108  //TODO : should probably preprocess this
109  for(i=0;i<dvlp->opdescSize;i++)param[i]=dvlp->opcdescData[i*2];
110 
111  GPUCMD_Add(0x000F02D6, param, dvlp->opdescSize);
112 }
113 
115 {
116  if(!dvle)return;
117 
118  u32 param[0x7]={0x1F1F1F1F,0x1F1F1F1F,0x1F1F1F1F,0x1F1F1F1F,
119  0x1F1F1F1F,0x1F1F1F1F,0x1F1F1F1F};
120 
121  int i;
122  u8 numAttr=0;
123  u8 maxAttr=0;
124  u8 attrMask=0;
125  //TODO : should probably preprocess this
126  for(i=0;i<dvle->outTableSize;i++)
127  {
128  u32* out=&param[dvle->outTableData[i].regID];
129 
130  if(*out==0x1F1F1F1F)numAttr++;
131 
132  //desc could include masking/swizzling info not currently taken into account
133  //also TODO : map out other output register values
134  switch(dvle->outTableData[i].type)
135  {
136  case RESULT_POSITION: *out=0x03020100; break;
137  case RESULT_COLOR: *out=0x0B0A0908; break;
138  case RESULT_TEXCOORD0: *out=0x1F1F0D0C; break;
139  case RESULT_TEXCOORD1: *out=0x1F1F0F0E; break;
140  case RESULT_TEXCOORD2: *out=0x1F1F1716; break;
141  }
142 
143  attrMask|=1<<dvle->outTableData[i].regID;
144  if(dvle->outTableData[i].regID+1>maxAttr)maxAttr=dvle->outTableData[i].regID+1;
145  }
146 
147  GPUCMD_AddSingleParam(0x000F0251, numAttr-1); //?
148  GPUCMD_AddSingleParam(0x000F024A, numAttr-1); //?
149  GPUCMD_AddSingleParam(0x000F02BD, attrMask); //?
150  GPUCMD_AddSingleParam(0x0001025E, numAttr-1); //?
151  GPUCMD_AddSingleParam(0x000F004F, numAttr); //?
152  GPUCMD_Add(0x800F0050, param, 0x00000007);
153 }
154 
156 {
157  if(!dvle)return;
158 
159  u32 param[4];
160  u32 rev[3];
161  u8* rev8=(u8*)rev;
162 
163  int i;
164  DVLE_constEntry_s* cnst=dvle->constTableData;
165  for(i=0;i<dvle->constTableSize;i++,cnst++)
166  {
167  memcpy(&rev8[0], &cnst->data[0], 3);
168  memcpy(&rev8[3], &cnst->data[1], 3);
169  memcpy(&rev8[6], &cnst->data[2], 3);
170  memcpy(&rev8[9], &cnst->data[3], 3);
171 
172  param[0x0]=(cnst->header>>16)&0xFF;
173  param[0x1]=rev[2];
174  param[0x2]=rev[1];
175  param[0x3]=rev[0];
176 
177  GPUCMD_Add(0x800F02C0, param, 0x00000004);
178  }
179 }
180 
181 void SHDR_UseProgram(DVLB_s* dvlb, u8 id)
182 {
183  if(!dvlb || id>dvlb->numDVLE)return;
184  DVLE_s* dvle=&dvlb->DVLE[id];
185 
186  //?
187  GPUCMD_AddSingleParam(0x00010229, 0x00000000);
188  GPUCMD_AddSingleParam(0x00010244, 0x00000000);
189 
190  DVLP_SendCode(&dvlb->DVLP);
191  DVLP_SendOpDesc(&dvlb->DVLP);
192  DVLE_SendConstants(dvle);
193 
194  GPUCMD_AddSingleParam(0x00080229, 0x00000000);
195  GPUCMD_AddSingleParam(0x000F02BA, 0x7FFF0000|(dvle->mainOffset&0xFFFF)); //set entrypoint
196 
197  GPUCMD_AddSingleParam(0x000F0252, 0x00000000); // should all be part of DVLE_SendOutmap ?
198 
199  DVLE_SendOutmap(dvle);
200 
201  //?
202  GPUCMD_AddSingleParam(0x000F0064, 0x00000001);
203  GPUCMD_AddSingleParam(0x000F006F, 0x00000703);
204 }
205 
206 //TODO
208 {
209  if(!dvlb)return;
210 
211 }
u32 constTableSize
Definition: shdr.h:43
int8_t s8
Definition: types.h:26
u32 * codeData
Definition: shdr.h:18
DVLP_s DVLP
Definition: shdr.h:54
u32 header
Definition: shdr.h:24
DVLE_s * DVLE
Definition: shdr.h:55
void DVLE_SendConstants(DVLE_s *dvle)
Definition: shdr.c:155
u32 uniformTableSize
Definition: shdr.h:47
Definition: shdr.h:52
void DVLP_SendCode(DVLP_s *dvlp)
Definition: shdr.c:86
void SHDR_FreeDVLB(DVLB_s *dvlb)
Definition: shdr.c:207
u32 * opcdescData
Definition: shdr.h:20
void DVLE_SendOutmap(DVLE_s *dvle)
Definition: shdr.c:114
uint8_t u8
Definition: types.h:21
void SHDR_UseProgram(DVLB_s *dvlb, u8 id)
Definition: shdr.c:181
u32 opdescSize
Definition: shdr.h:19
uint32_t u32
Definition: types.h:23
Definition: shdr.h:34
u32 data[4]
Definition: shdr.h:25
u32 mainOffset
Definition: shdr.h:42
Definition: shdr.h:16
SHDR_type type
Definition: shdr.h:41
u32 numDVLE
Definition: shdr.h:53
void GPUCMD_AddSingleParam(u32 cmd, u32 param)
Definition: gpu.c:88
DVLB_s * SHDR_ParseSHBIN(u32 *shbinData, u32 shbinSize)
Definition: shdr.c:11
u32 endmainOffset
Definition: shdr.h:42
u32 symbolOffset
Definition: shdr.h:35
u32 outTableSize
Definition: shdr.h:45
u16 regID
Definition: shdr.h:30
char * symbolTableData
Definition: shdr.h:49
Definition: shdr.h:23
DVLE_constEntry_s * constTableData
Definition: shdr.h:44
Definition: shdr.h:40
void GPUCMD_Add(u32 cmd, u32 *param, u32 paramlength)
Definition: gpu.c:63
DVLE_outEntry_s * outTableData
Definition: shdr.h:46
Definition: shdr.h:28
s8 SHDR_GetUniformRegister(DVLB_s *dvlb, const char *name, u8 programID)
Definition: shdr.c:59
u32 codeSize
Definition: shdr.h:17
u16 type
Definition: shdr.h:29
DVLE_uniformEntry_s * uniformTableData
Definition: shdr.h:48
u16 startReg
Definition: shdr.h:36
void DVLP_SendOpDesc(DVLP_s *dvlp)
Definition: shdr.c:99