2017-02-09 04:30:25 +01:00
|
|
|
#include "internal.h"
|
2014-12-20 21:34:19 +01:00
|
|
|
#include <c3d/uniforms.h>
|
|
|
|
|
2015-03-05 23:05:14 +01:00
|
|
|
C3D_FVec C3D_FVUnif[2][C3D_FVUNIF_COUNT];
|
|
|
|
C3D_IVec C3D_IVUnif[2][C3D_IVUNIF_COUNT];
|
|
|
|
u16 C3D_BoolUnifs[2];
|
2014-12-20 21:34:19 +01:00
|
|
|
|
2015-03-05 23:05:14 +01:00
|
|
|
bool C3D_FVUnifDirty[2][C3D_FVUNIF_COUNT];
|
|
|
|
bool C3D_IVUnifDirty[2][C3D_IVUNIF_COUNT];
|
|
|
|
bool C3D_BoolUnifsDirty[2];
|
2014-12-20 21:34:19 +01:00
|
|
|
|
2015-11-21 01:02:25 +01:00
|
|
|
static struct
|
|
|
|
{
|
|
|
|
bool dirty;
|
|
|
|
int count;
|
|
|
|
float24Uniform_s* data;
|
|
|
|
} C3Di_ShaderFVecData[2];
|
|
|
|
|
|
|
|
static bool C3Di_FVUnifEverDirty[2][C3D_FVUNIF_COUNT];
|
|
|
|
static bool C3Di_IVUnifEverDirty[2][C3D_IVUNIF_COUNT];
|
|
|
|
|
2015-03-05 23:05:14 +01:00
|
|
|
void C3D_UpdateUniforms(GPU_SHADER_TYPE type)
|
2014-12-20 21:34:19 +01:00
|
|
|
{
|
2015-03-05 23:05:14 +01:00
|
|
|
int offset = type == GPU_GEOMETRY_SHADER ? (GPUREG_GSH_BOOLUNIFORM-GPUREG_VSH_BOOLUNIFORM) : 0;
|
2015-11-21 01:02:25 +01:00
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
// Update FVec uniforms that come from shader constants
|
|
|
|
if (C3Di_ShaderFVecData[type].dirty)
|
|
|
|
{
|
|
|
|
while (i < C3Di_ShaderFVecData[type].count)
|
|
|
|
{
|
|
|
|
float24Uniform_s* u = &C3Di_ShaderFVecData[type].data[i++];
|
|
|
|
GPUCMD_AddIncrementalWrites(GPUREG_VSH_FLOATUNIFORM_CONFIG+offset, (u32*)u, 4);
|
|
|
|
C3D_FVUnifDirty[type][u->id] = false;
|
|
|
|
}
|
|
|
|
C3Di_ShaderFVecData[type].dirty = false;
|
|
|
|
i = 0;
|
|
|
|
}
|
2015-03-05 23:05:14 +01:00
|
|
|
|
2014-12-20 21:34:19 +01:00
|
|
|
// Update FVec uniforms
|
|
|
|
while (i < C3D_FVUNIF_COUNT)
|
|
|
|
{
|
2015-03-05 23:05:14 +01:00
|
|
|
if (!C3D_FVUnifDirty[type][i])
|
2014-12-20 21:34:19 +01:00
|
|
|
{
|
|
|
|
i ++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Find the number of consecutive dirty uniforms
|
|
|
|
int j;
|
2015-03-05 23:05:14 +01:00
|
|
|
for (j = i; j < C3D_FVUNIF_COUNT && C3D_FVUnifDirty[type][j]; j ++);
|
2014-12-20 21:34:19 +01:00
|
|
|
|
|
|
|
// Upload the uniforms
|
2015-09-06 22:08:28 +02:00
|
|
|
GPUCMD_AddWrite(GPUREG_VSH_FLOATUNIFORM_CONFIG+offset, 0x80000000|i);
|
2015-11-22 13:48:11 +01:00
|
|
|
GPUCMD_AddWrites(GPUREG_VSH_FLOATUNIFORM_DATA+offset, (u32*)&C3D_FVUnif[type][i], (j-i)*4);
|
2014-12-20 21:34:19 +01:00
|
|
|
|
|
|
|
// Clear the dirty flag
|
|
|
|
int k;
|
|
|
|
for (k = i; k < j; k ++)
|
2015-11-21 01:02:25 +01:00
|
|
|
{
|
2015-03-05 23:05:14 +01:00
|
|
|
C3D_FVUnifDirty[type][k] = false;
|
2015-11-21 01:02:25 +01:00
|
|
|
C3Di_FVUnifEverDirty[type][k] = true;
|
|
|
|
}
|
2014-12-20 21:34:19 +01:00
|
|
|
|
|
|
|
// Advance
|
2017-03-04 18:16:20 +01:00
|
|
|
i = j;
|
2014-12-20 21:34:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Update IVec uniforms
|
|
|
|
for (i = 0; i < C3D_IVUNIF_COUNT; i ++)
|
|
|
|
{
|
2015-03-05 23:05:14 +01:00
|
|
|
if (!C3D_IVUnifDirty[type][i]) continue;
|
2014-12-20 21:34:19 +01:00
|
|
|
|
2015-03-05 23:05:14 +01:00
|
|
|
GPUCMD_AddWrite(GPUREG_VSH_INTUNIFORM_I0+offset+i, C3D_IVUnif[type][i]);
|
|
|
|
C3D_IVUnifDirty[type][i] = false;
|
2015-11-21 01:02:25 +01:00
|
|
|
C3Di_IVUnifEverDirty[type][i] = false;
|
2014-12-20 21:34:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Update bool uniforms
|
2015-03-05 23:05:14 +01:00
|
|
|
if (C3D_BoolUnifsDirty[type])
|
2014-12-20 21:34:19 +01:00
|
|
|
{
|
2016-01-24 01:45:39 +01:00
|
|
|
GPUCMD_AddWrite(GPUREG_VSH_BOOLUNIFORM+offset, 0x7FFF0000 | C3D_BoolUnifs[type]);
|
2015-03-05 23:05:14 +01:00
|
|
|
C3D_BoolUnifsDirty[type] = false;
|
2014-12-20 21:34:19 +01:00
|
|
|
}
|
|
|
|
}
|
2015-11-21 01:02:25 +01:00
|
|
|
|
|
|
|
void C3Di_DirtyUniforms(GPU_SHADER_TYPE type)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
C3D_BoolUnifsDirty[type] = true;
|
|
|
|
if (C3Di_ShaderFVecData[type].count)
|
|
|
|
C3Di_ShaderFVecData[type].dirty = true;
|
|
|
|
for (i = 0; i < C3D_FVUNIF_COUNT; i ++)
|
|
|
|
C3D_FVUnifDirty[type][i] = C3D_FVUnifDirty[type][i] || C3Di_FVUnifEverDirty[type][i];
|
|
|
|
for (i = 0; i < C3D_IVUNIF_COUNT; i ++)
|
|
|
|
C3D_IVUnifDirty[type][i] = C3D_IVUnifDirty[type][i] || C3Di_IVUnifEverDirty[type][i];
|
|
|
|
}
|
|
|
|
|
|
|
|
void C3Di_LoadShaderUniforms(shaderInstance_s* si)
|
|
|
|
{
|
|
|
|
GPU_SHADER_TYPE type = si->dvle->type;
|
|
|
|
if (si->boolUniformMask)
|
|
|
|
{
|
|
|
|
C3D_BoolUnifs[type] &= ~si->boolUniformMask;
|
|
|
|
C3D_BoolUnifs[type] |= si->boolUniforms;
|
|
|
|
}
|
2016-07-20 17:38:05 +02:00
|
|
|
|
2016-07-21 12:06:09 +02:00
|
|
|
if (type == GPU_GEOMETRY_SHADER)
|
|
|
|
C3D_BoolUnifs[type] &= ~BIT(15);
|
2016-07-20 17:38:05 +02:00
|
|
|
C3D_BoolUnifsDirty[type] = true;
|
|
|
|
|
2015-11-21 01:02:25 +01:00
|
|
|
if (si->intUniformMask)
|
|
|
|
{
|
2016-07-20 17:38:05 +02:00
|
|
|
int i;
|
2015-11-21 01:02:25 +01:00
|
|
|
for (i = 0; i < 4; i ++)
|
|
|
|
{
|
|
|
|
if (si->intUniformMask & BIT(i))
|
|
|
|
{
|
|
|
|
C3D_IVUnif[type][i] = si->intUniforms[i];
|
|
|
|
C3D_IVUnifDirty[type][i] = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
C3Di_ShaderFVecData[type].dirty = true;
|
|
|
|
C3Di_ShaderFVecData[type].count = si->numFloat24Uniforms;
|
|
|
|
C3Di_ShaderFVecData[type].data = si->float24Uniforms;
|
|
|
|
}
|
|
|
|
|
|
|
|
void C3Di_ClearShaderUniforms(GPU_SHADER_TYPE type)
|
|
|
|
{
|
|
|
|
C3Di_ShaderFVecData[type].dirty = false;
|
|
|
|
C3Di_ShaderFVecData[type].count = 0;
|
|
|
|
C3Di_ShaderFVecData[type].data = NULL;
|
|
|
|
}
|