diff --git a/libctru/include/3ds/gpu/gpu.h b/libctru/include/3ds/gpu/gpu.h index 5fd3071..e25c7de 100644 --- a/libctru/include/3ds/gpu/gpu.h +++ b/libctru/include/3ds/gpu/gpu.h @@ -190,6 +190,8 @@ typedef enum{ }GPU_Primitive_t; void GPU_SetUniform(u32 startreg, u32* data, u32 numreg); +void GPU_SetIntUniform(u32 startreg, u32 value); +void GPU_SetBoolUniforms(u32 values); void GPU_SetViewport(u32* depthBuffer, u32* colorBuffer, u32 x, u32 y, u32 w, u32 h); diff --git a/libctru/include/3ds/gpu/shdr.h b/libctru/include/3ds/gpu/shdr.h index 02b5128..64846a9 100644 --- a/libctru/include/3ds/gpu/shdr.h +++ b/libctru/include/3ds/gpu/shdr.h @@ -28,7 +28,8 @@ typedef struct{ typedef struct{ u16 type; u16 regID; - u32 header; + u8 compMask; + u8 pad[3]; }DVLE_outEntry_s; typedef struct{ diff --git a/libctru/source/gpu/gpu.c b/libctru/source/gpu/gpu.c index ccde474..fab80ed 100644 --- a/libctru/source/gpu/gpu.c +++ b/libctru/source/gpu/gpu.c @@ -234,6 +234,16 @@ void GPU_SetUniform(u32 startreg, u32* data, u32 numreg) GPUCMD_Add(0x000F02C1, data, numreg*4); } +void GPU_SetIntUniform(u32 reg, u32 value) +{ + GPUCMD_AddSingleParam(0x000F02B1 + reg, value); +} + +void GPU_SetBoolUniforms(u32 values) +{ + GPUCMD_AddSingleParam(0x000F02B0, values); +} + //TODO : fix u32 f32tof24(float f) { diff --git a/libctru/source/gpu/shdr.c b/libctru/source/gpu/shdr.c index 47ac389..15e1bbf 100644 --- a/libctru/source/gpu/shdr.c +++ b/libctru/source/gpu/shdr.c @@ -57,7 +57,7 @@ DVLB_s* SHDR_ParseSHBIN(u32* shbinData, u32 shbinSize) return ret; } -s8 SHDR_GetUniformRegister(DVLB_s* dvlb, const char* name, u8 programID) +static s32 SHDR_GetUniformRegisterInternal(DVLB_s* dvlb, const char* name, u8 programID) { if(!dvlb || !name)return -1; @@ -66,12 +66,35 @@ s8 SHDR_GetUniformRegister(DVLB_s* dvlb, const char* name, u8 programID) int i; DVLE_uniformEntry_s* u=dvle->uniformTableData; for(i=0;iuniformTableSize;i++) { - if(!strcmp(&dvle->symbolTableData[u->symbolOffset],name))return (s8)u->startReg-0x10; + if(!strcmp(&dvle->symbolTableData[u->symbolOffset],name)) + return u->startReg; + u++; } return -1; } +s8 SHDR_GetUniformRegister(DVLB_s* dvlb, const char* name, u8 programID) +{ + s32 value = SHDR_GetUniformRegisterInternal(dvlb, name, programID); + if (value < 0x10 || value > 0x6f) return -1; + else return value - 0x10; +} + +s8 SHDR_GetIntUniformRegster(DVLB_s* dvlb, const char* name, u8 programID) +{ + s32 value = SHDR_GetUniformRegisterInternal(dvlb, name, programID); + if (value < 0x70 || value > 0x73) return -1; + else return value - 0x70; +} + +s8 SHDR_GetBoolUniformRegster(DVLB_s* dvlb, const char* name, u8 programID) +{ + s32 value = SHDR_GetUniformRegisterInternal(dvlb, name, programID); + if (value < 0x78 || value > 0x87) return -1; + else return value - 0x78; +} + void DVLP_SendCode(DVLP_s* dvlp) { if(!dvlp)return; @@ -101,7 +124,7 @@ void DVLP_SendOpDesc(DVLP_s* dvlp) void DVLE_SendOutmap(DVLE_s* dvle) { - if(!dvle)return; + if(!dvle) return; u32 param[0x7]={0x1F1F1F1F,0x1F1F1F1F,0x1F1F1F1F,0x1F1F1F1F, 0x1F1F1F1F,0x1F1F1F1F,0x1F1F1F1F}; @@ -109,32 +132,38 @@ void DVLE_SendOutmap(DVLE_s* dvle) int i; u8 numAttr=0; u8 maxAttr=0; - u8 attrMask=0; + u8 activeOutputs=0; //TODO : should probably preprocess this for(i=0;ioutTableSize;i++) { u32* out=¶m[dvle->outTableData[i].regID]; - - if(*out==0x1F1F1F1F)numAttr++; + + if(*out==0x1F1F1F1F) numAttr++; //desc could include masking/swizzling info not currently taken into account //also TODO : map out other output register values + u32 mask = ((dvle->outTableData[i].compMask & 1) ? 0x000000FF : 0u) | + ((dvle->outTableData[i].compMask & 2) ? 0x0000FF00 : 0u) | + ((dvle->outTableData[i].compMask & 4) ? 0x00FF0000 : 0u) | + ((dvle->outTableData[i].compMask & 8) ? 0xFF000000 : 0u); + + *out &= ~mask; switch(dvle->outTableData[i].type) { - case RESULT_POSITION: *out=0x03020100; break; - case RESULT_COLOR: *out=0x0B0A0908; break; - case RESULT_TEXCOORD0: *out=0x1F1F0D0C; break; - case RESULT_TEXCOORD1: *out=0x1F1F0F0E; break; - case RESULT_TEXCOORD2: *out=0x1F1F1716; break; + case RESULT_POSITION: *out |= 0x03020100 & mask; break; + case RESULT_COLOR: *out |= 0x0B0A0908 & mask; break; + case RESULT_TEXCOORD0: *out |= 0x1F1F0D0C & mask; break; + case RESULT_TEXCOORD1: *out |= 0x1F1F0F0E & mask; break; + case RESULT_TEXCOORD2: *out |= 0x1F1F1716 & mask; break; } - attrMask|=1<outTableData[i].regID; + activeOutputs |= 1 << dvle->outTableData[i].regID; if(dvle->outTableData[i].regID+1>maxAttr)maxAttr=dvle->outTableData[i].regID+1; } GPUCMD_AddSingleParam(0x000F0251, numAttr-1); //? GPUCMD_AddSingleParam(0x000F024A, numAttr-1); //? - GPUCMD_AddSingleParam(0x000F02BD, attrMask); //? + GPUCMD_AddSingleParam(0x000F02BD, activeOutputs); //? GPUCMD_AddSingleParam(0x0001025E, numAttr-1); //? GPUCMD_AddSingleParam(0x000F004F, numAttr); //? GPUCMD_Add(0x800F0050, param, 0x00000007);