Citro3d
Loading...
Searching...
No Matches
uniforms.c
Go to the documentation of this file.
1#include "internal.h"
2#include <c3d/uniforms.h>
3
4C3D_FVec C3D_FVUnif[2][C3D_FVUNIF_COUNT];
5C3D_IVec C3D_IVUnif[2][C3D_IVUNIF_COUNT];
7
8bool C3D_FVUnifDirty[2][C3D_FVUNIF_COUNT];
9bool C3D_IVUnifDirty[2][C3D_IVUNIF_COUNT];
11
12static struct
13{
14 bool dirty;
15 int count;
16 float24Uniform_s* data;
17} C3Di_ShaderFVecData[2];
18
19static bool C3Di_FVUnifEverDirty[2][C3D_FVUNIF_COUNT];
20static bool C3Di_IVUnifEverDirty[2][C3D_IVUNIF_COUNT];
21
22void C3D_UpdateUniforms(GPU_SHADER_TYPE type)
23{
24 int offset = type == GPU_GEOMETRY_SHADER ? (GPUREG_GSH_BOOLUNIFORM-GPUREG_VSH_BOOLUNIFORM) : 0;
25 int i = 0;
26
27 // Update FVec uniforms that come from shader constants
28 if (C3Di_ShaderFVecData[type].dirty)
29 {
30 while (i < C3Di_ShaderFVecData[type].count)
31 {
32 float24Uniform_s* u = &C3Di_ShaderFVecData[type].data[i++];
33 GPUCMD_AddIncrementalWrites(GPUREG_VSH_FLOATUNIFORM_CONFIG+offset, (u32*)u, 4);
34 C3D_FVUnifDirty[type][u->id] = false;
35 }
36 C3Di_ShaderFVecData[type].dirty = false;
37 i = 0;
38 }
39
40 // Update FVec uniforms
41 while (i < C3D_FVUNIF_COUNT)
42 {
43 if (!C3D_FVUnifDirty[type][i])
44 {
45 i ++;
46 continue;
47 }
48
49 // Find the number of consecutive dirty uniforms
50 int j;
51 for (j = i; j < C3D_FVUNIF_COUNT && C3D_FVUnifDirty[type][j]; j ++);
52
53 // Upload the uniforms
54 GPUCMD_AddWrite(GPUREG_VSH_FLOATUNIFORM_CONFIG+offset, 0x80000000|i);
55 GPUCMD_AddWrites(GPUREG_VSH_FLOATUNIFORM_DATA+offset, (u32*)&C3D_FVUnif[type][i], (j-i)*4);
56
57 // Clear the dirty flag
58 int k;
59 for (k = i; k < j; k ++)
60 {
61 C3D_FVUnifDirty[type][k] = false;
62 C3Di_FVUnifEverDirty[type][k] = true;
63 }
64
65 // Advance
66 i = j;
67 }
68
69 // Update IVec uniforms
70 for (i = 0; i < C3D_IVUNIF_COUNT; i ++)
71 {
72 if (!C3D_IVUnifDirty[type][i]) continue;
73
74 GPUCMD_AddWrite(GPUREG_VSH_INTUNIFORM_I0+offset+i, C3D_IVUnif[type][i]);
75 C3D_IVUnifDirty[type][i] = false;
76 C3Di_IVUnifEverDirty[type][i] = false;
77 }
78
79 // Update bool uniforms
80 if (C3D_BoolUnifsDirty[type])
81 {
82 GPUCMD_AddWrite(GPUREG_VSH_BOOLUNIFORM+offset, 0x7FFF0000 | C3D_BoolUnifs[type]);
83 C3D_BoolUnifsDirty[type] = false;
84 }
85}
86
87void C3Di_DirtyUniforms(GPU_SHADER_TYPE type)
88{
89 int i;
90 C3D_BoolUnifsDirty[type] = true;
91 if (C3Di_ShaderFVecData[type].count)
92 C3Di_ShaderFVecData[type].dirty = true;
93 for (i = 0; i < C3D_FVUNIF_COUNT; i ++)
94 C3D_FVUnifDirty[type][i] = C3D_FVUnifDirty[type][i] || C3Di_FVUnifEverDirty[type][i];
95 for (i = 0; i < C3D_IVUNIF_COUNT; i ++)
96 C3D_IVUnifDirty[type][i] = C3D_IVUnifDirty[type][i] || C3Di_IVUnifEverDirty[type][i];
97}
98
99void C3Di_LoadShaderUniforms(shaderInstance_s* si)
100{
101 GPU_SHADER_TYPE type = si->dvle->type;
102 if (si->boolUniformMask)
103 {
104 C3D_BoolUnifs[type] &= ~si->boolUniformMask;
105 C3D_BoolUnifs[type] |= si->boolUniforms;
106 }
107
108 if (type == GPU_GEOMETRY_SHADER)
109 C3D_BoolUnifs[type] &= ~BIT(15);
110 C3D_BoolUnifsDirty[type] = true;
111
112 if (si->intUniformMask)
113 {
114 int i;
115 for (i = 0; i < 4; i ++)
116 {
117 if (si->intUniformMask & BIT(i))
118 {
119 C3D_IVUnif[type][i] = si->intUniforms[i];
120 C3D_IVUnifDirty[type][i] = true;
121 }
122 }
123 }
124 C3Di_ShaderFVecData[type].dirty = true;
125 C3Di_ShaderFVecData[type].count = si->numFloat24Uniforms;
126 C3Di_ShaderFVecData[type].data = si->float24Uniforms;
127}
128
129void C3Di_ClearShaderUniforms(GPU_SHADER_TYPE type)
130{
131 C3Di_ShaderFVecData[type].dirty = false;
132 C3Di_ShaderFVecData[type].count = 0;
133 C3Di_ShaderFVecData[type].data = NULL;
134}
bool C3D_FVUnifDirty[2][C3D_FVUNIF_COUNT]
Definition: uniforms.c:8
u16 C3D_BoolUnifs[2]
Definition: uniforms.c:6
void C3Di_DirtyUniforms(GPU_SHADER_TYPE type)
Definition: uniforms.c:87
C3D_FVec C3D_FVUnif[2][C3D_FVUNIF_COUNT]
Definition: uniforms.c:4
void C3Di_LoadShaderUniforms(shaderInstance_s *si)
Definition: uniforms.c:99
bool C3D_IVUnifDirty[2][C3D_IVUNIF_COUNT]
Definition: uniforms.c:9
bool C3D_BoolUnifsDirty[2]
Definition: uniforms.c:10
float24Uniform_s * data
Definition: uniforms.c:16
C3D_IVec C3D_IVUnif[2][C3D_IVUNIF_COUNT]
Definition: uniforms.c:5
bool dirty
Definition: uniforms.c:14
void C3D_UpdateUniforms(GPU_SHADER_TYPE type)
Definition: uniforms.c:22
int count
Definition: uniforms.c:15
void C3Di_ClearShaderUniforms(GPU_SHADER_TYPE type)
Definition: uniforms.c:129