summaryrefslogtreecommitdiff
path: root/Runtime/GfxDevice/GpuProgramParamsApply.h
blob: 4ac5ad0b8962875dd00afce81e4bec930675d4b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#pragma once


template<typename SetValuesFunctor>
void ApplyMaterialPropertyBlockValues(
	MaterialPropertyBlock& propblock,
	GpuProgram* activeGpuProgram[kShaderTypeCount],
	const GpuProgramParameters* activeGpuProgramParams[kShaderTypeCount],
	SetValuesFunctor& functor)
{
	const MaterialPropertyBlock::Property* curProp = propblock.GetPropertiesBegin();
	const MaterialPropertyBlock::Property* propEnd = propblock.GetPropertiesEnd();
	const float* propBuffer = propblock.GetBufferBegin();
	while (curProp != propEnd)
	{
		FastPropertyName name;
		name.index = curProp->nameIndex;
		for (int shaderType = kShaderVertex; shaderType < kShaderTypeCount; ++shaderType)
		{
			GpuProgram* GpuProgram = activeGpuProgram[shaderType];
			if (!GpuProgram)
				continue;
			const GpuProgramParameters* params = activeGpuProgramParams[shaderType];

			if (curProp->texDim != kTexDimNone)
			{
				// texture parameter
				const GpuProgramParameters::TextureParameter* param = params->FindTextureParam(name, (TextureDimension)curProp->texDim);
				if (!param)
					continue;
				const float* val = &propBuffer[curProp->offset];
				functor.SetTextureVal ((ShaderType)shaderType, param->m_Index, param->m_SamplerIndex, param->m_Dim, TextureID(*(unsigned int*)val));
			}
			else
			{
				// value parameter
				int cbIndex;
				const GpuProgramParameters::ValueParameter* param = params->FindParam(name, &cbIndex);
				if (!param)
					continue;
				if (curProp->rows == 1)
				{
					const float* src = &propBuffer[curProp->offset];
					Vector4f val;
					if (curProp->cols == 4)
						val = Vector4f(src);
					else
					{
						DebugAssert(curProp->cols == 1);
						val = Vector4f(*src, 0, 0, 0);
					}
					functor.SetVectorVal ((ShaderType)shaderType, param->m_Type, param->m_Index, val.GetPtr(), curProp->cols, *params, cbIndex);
				}
				else if (curProp->rows == 4)
				{
					DebugAssert(curProp->cols == 4);
					const Matrix4x4f* src = (const Matrix4x4f*)&propBuffer[curProp->offset];
					functor.SetMatrixVal ((ShaderType)shaderType, param->m_Index, src, param->m_RowCount, *params, cbIndex);
				}
				else
				{
					AssertString("Unknown property dimensions");
				}
			}
		}
		++curProp;
	}

	propblock.Clear();
}


// GL ES is different from everyone else, in that shader variables are always for the whole
// "program" (all shader stages at once).
template<typename SetValuesFunctor>
void ApplyMaterialPropertyBlockValuesES(
	MaterialPropertyBlock& propblock,
	const GpuProgram* activeProgram,
	const GpuProgramParameters* activeProgramParams,
	SetValuesFunctor& functor)
{
	if (activeProgram)
	{
		const MaterialPropertyBlock::Property* curProp = propblock.GetPropertiesBegin();
		const MaterialPropertyBlock::Property* propEnd = propblock.GetPropertiesEnd();
		const float* propBuffer = propblock.GetBufferBegin();
		while (curProp != propEnd)
		{
			FastPropertyName name;
			name.index = curProp->nameIndex;

			if (curProp->texDim != kTexDimNone)
			{
				// texture parameter
				const GpuProgramParameters::TextureParameter* param = activeProgramParams->FindTextureParam(name, (TextureDimension)curProp->texDim);
				if (param)
				{
					const float* val = &propBuffer[curProp->offset];
					functor.SetTextureVal (kShaderFragment, param->m_Index, param->m_SamplerIndex, param->m_Dim, TextureID(*(unsigned int*)val));
				}
			}
			else
			{
				// value parameter
				const GpuProgramParameters::ValueParameter* param = activeProgramParams->FindParam(name);
				if (param && curProp->rows == param->m_RowCount)
				{
					if (curProp->rows == 1)
					{
						const float* src = &propBuffer[curProp->offset];
						functor.SetVectorVal (param->m_Type, param->m_Index, src, param->m_ColCount);
					}
					else if (curProp->rows == 4)
					{
						DebugAssert(curProp->cols == 4);
						const Matrix4x4f* src = (const Matrix4x4f*)&propBuffer[curProp->offset];
						functor.SetMatrixVal (param->m_Index, src, param->m_RowCount);
					}
					else
					{
						AssertString("Unknown property dimensions");
					}
				}
			}
			++curProp;
		}
	}

	propblock.Clear();
}