aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/modules/engines/direct3d/evas_direct3d_shader_pack.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/evas/src/modules/engines/direct3d/evas_direct3d_shader_pack.cpp')
-rw-r--r--libraries/evas/src/modules/engines/direct3d/evas_direct3d_shader_pack.cpp344
1 files changed, 344 insertions, 0 deletions
diff --git a/libraries/evas/src/modules/engines/direct3d/evas_direct3d_shader_pack.cpp b/libraries/evas/src/modules/engines/direct3d/evas_direct3d_shader_pack.cpp
new file mode 100644
index 0000000..d9c868f
--- /dev/null
+++ b/libraries/evas/src/modules/engines/direct3d/evas_direct3d_shader_pack.cpp
@@ -0,0 +1,344 @@
1
2#include <assert.h>
3
4#include <d3dx9.h>
5
6#include "evas_direct3d_shader_pack.h"
7#include "evas_direct3d_device.h"
8
9Ref<D3DShaderPack> D3DShaderPack::_this;
10
11D3DShaderPack::D3DShaderPack()
12{
13}
14
15D3DShaderPack::~D3DShaderPack()
16{
17 Uninitialize();
18}
19
20D3DShaderPack *D3DShaderPack::Current()
21{
22 if (_this.IsNull())
23 _this = new D3DShaderPack();
24 return _this;
25}
26
27void D3DShaderPack::SetCurrent(D3DShaderPack *obj)
28{
29 _this = obj;
30}
31
32
33bool D3DShaderPack::Initialize(D3DDevice *d3d)
34{
35 bool res = true;
36 if (!(res = InitVertexDeclarations(d3d) && res))
37 WRN("Failed to create vdecl set");
38 if (!(res = InitVertexShaders(d3d) && res))
39 WRN("Failed to create vs set");
40 if (!(res = InitPixelShaders(d3d) && res))
41 WRN("Failed to create ps set");
42 return res;
43}
44
45void D3DShaderPack::Uninitialize()
46{
47 for (int i = 0; i < _vdecl.Length(); i++)
48 {
49 if (_vdecl[i] != NULL)
50 {
51 _vdecl[i]->Release();
52 _vdecl[i] = NULL;
53 }
54 }
55
56 for (int i = 0; i < _vs.Length(); i++)
57 {
58 if (_vs[i] != NULL)
59 {
60 _vs[i]->Release();
61 _vs[i] = NULL;
62 }
63 }
64
65 for (int i = 0; i < _ps.Length(); i++)
66 {
67 if (_ps[i] != NULL)
68 {
69 _ps[i]->Release();
70 _ps[i] = NULL;
71 }
72 }
73}
74
75bool D3DShaderPack::InitVertexDeclarations(D3DDevice *d3d)
76{
77 _vdecl.Allocate(VDECL_NUM);
78 _vdecl.Set(NULL);
79
80 LPDIRECT3DVERTEXDECLARATION9 vdecl = NULL;
81 {
82 D3DVERTEXELEMENT9 elements[] = {
83 {0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
84 {0, 8, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
85 D3DDECL_END()
86 };
87 if (FAILED(d3d->GetDevice()->CreateVertexDeclaration(elements, &vdecl)))
88 return false;
89 if (vdecl == NULL)
90 return false;
91 }
92 _vdecl[VDECL_XYC] = vdecl;
93 vdecl = NULL;
94 {
95 D3DVERTEXELEMENT9 elements[] = {
96 {0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
97 {0, 8, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
98 D3DDECL_END()
99 };
100 if (FAILED(d3d->GetDevice()->CreateVertexDeclaration(elements, &vdecl)))
101 return false;
102 if (vdecl == NULL)
103 return false;
104 }
105 _vdecl[VDECL_XYUV] = vdecl;
106 vdecl = NULL;
107 {
108 D3DVERTEXELEMENT9 elements[] = {
109 {0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
110 {0, 8, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
111 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
112 D3DDECL_END()
113 };
114 if (FAILED(d3d->GetDevice()->CreateVertexDeclaration(elements, &vdecl)))
115 return false;
116 if (vdecl == NULL)
117 return false;
118 }
119 _vdecl[VDECL_XYUVC] = vdecl;
120 vdecl = NULL;
121 {
122 D3DVERTEXELEMENT9 elements[] = {
123 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
124 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
125 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
126 D3DDECL_END()
127 };
128 if (FAILED(d3d->GetDevice()->CreateVertexDeclaration(elements, &vdecl)))
129 return false;
130 if (vdecl == NULL)
131 return false;
132 }
133 _vdecl[VDECL_XYZUVC] = vdecl;
134
135 return true;
136}
137
138bool D3DShaderPack::InitVertexShaders(D3DDevice *d3d)
139{
140 _vs.Allocate(VS_NUM);
141 _vs.Set(NULL);
142
143 {
144 char buf[] =
145 "struct VsInput { float2 pos : POSITION; float4 col : COLOR; };\n"
146 "struct VsOutput { float4 pos : POSITION; float4 col : COLOR0; };\n"
147 "VsOutput main(VsInput vs_in) {\n"
148 "VsOutput vs_out;\n"
149 "vs_out.pos = float4(vs_in.pos, 0, 1);\n"
150 "vs_out.col = vs_in.col;\n"
151 "return vs_out;}";
152
153 _vs[VS_COPY_COLOR] = (LPDIRECT3DVERTEXSHADER9)
154 CompileShader(d3d, true, "CopyColor", buf, sizeof(buf) - 1);
155 if (_vs[VS_COPY_COLOR] == NULL)
156 return false;
157 }
158
159 {
160 char buf[] =
161 "struct VsInput { float2 pos : POSITION; float2 tex : TEXCOORD0; };\n"
162 "struct VsOutput { float4 pos : POSITION; float2 tex : TEXCOORD0; };\n"
163 "VsOutput main(VsInput vs_in) {\n"
164 "VsOutput vs_out;\n"
165 "vs_out.pos = float4(vs_in.pos, 0, 1);\n"
166 "vs_out.tex = vs_in.tex;\n"
167 "return vs_out;}";
168
169 _vs[VS_COPY_UV] = (LPDIRECT3DVERTEXSHADER9)
170 CompileShader(d3d, true, "CopyUV", buf, sizeof(buf) - 1);
171 if (_vs[VS_COPY_UV] == NULL)
172 return false;
173 }
174
175 {
176 char buf[] =
177 "struct VsInput { float2 pos : POSITION; float2 tex : TEXCOORD0; float4 col : COLOR; };\n"
178 "struct VsOutput { float4 pos : POSITION; float2 tex : TEXCOORD0; float4 col : COLOR0; };\n"
179 "VsOutput main(VsInput vs_in) {\n"
180 "VsOutput vs_out;\n"
181 "vs_out.pos = float4(vs_in.pos, 0, 1);\n"
182 "vs_out.tex = vs_in.tex;\n"
183 "vs_out.col = vs_in.col;\n"
184 "return vs_out;}";
185
186 _vs[VS_COPY_UV_COLOR] = (LPDIRECT3DVERTEXSHADER9)
187 CompileShader(d3d, true, "CopyUVColor", buf, sizeof(buf) - 1);
188 if (_vs[VS_COPY_UV_COLOR] == NULL)
189 return false;
190 }
191
192 {
193 char buf[] =
194 "struct VsInput { float3 pos : POSITION; float2 tex : TEXCOORD0; float4 col : COLOR; };\n"
195 "struct VsOutput { float4 pos : POSITION; float2 tex : TEXCOORD0; float4 col : COLOR0; };\n"
196 "VsOutput main(VsInput vs_in) {\n"
197 "VsOutput vs_out;\n"
198 "vs_out.pos = float4(vs_in.pos, 1);\n"
199 "vs_out.tex = vs_in.tex;\n"
200 "vs_out.col = vs_in.col;\n"
201 "return vs_out;}";
202
203 _vs[VS_COPY_UV_COLOR_Z] = (LPDIRECT3DVERTEXSHADER9)
204 CompileShader(d3d, true, "CopyUVColorZ", buf, sizeof(buf) - 1);
205 if (_vs[VS_COPY_UV_COLOR_Z] == NULL)
206 return false;
207 }
208
209 return true;
210}
211
212bool D3DShaderPack::InitPixelShaders(D3DDevice *d3d)
213{
214 _ps.Allocate(PS_NUM);
215 _ps.Set(NULL);
216
217 {
218 char buf[] =
219 "struct VsOutput { float4 pos : POSITION; float4 col : COLOR0; };\n"
220 "float4 main(VsOutput ps_in) : COLOR0 {\n"
221 "return ps_in.col;}";
222
223 _ps[PS_COLOR] = (LPDIRECT3DPIXELSHADER9)
224 CompileShader(d3d, false, "Color", buf, sizeof(buf) - 1);
225 if (_ps[PS_COLOR] == NULL)
226 return false;
227 }
228
229 {
230 char buf[] =
231 "sampler Texture : register(s0);\n"
232 "struct VsOutput { float4 pos : POSITION; float2 tex : TEXCOORD0; };\n"
233 "float4 main(VsOutput ps_in) : COLOR0 {\n"
234 "return tex2D(Texture, ps_in.tex);}";
235
236 _ps[PS_TEX] = (LPDIRECT3DPIXELSHADER9)
237 CompileShader(d3d, false, "Tex", buf, sizeof(buf) - 1);
238 if (_ps[PS_TEX] == NULL)
239 return false;
240 }
241
242 {
243 char buf[] =
244 "sampler Texture : register(s0);\n"
245 "struct VsOutput { float4 pos : POSITION; float2 tex : TEXCOORD0; float4 col : COLOR0; };\n"
246 "float4 main(VsOutput ps_in) : COLOR0 {\n"
247 "return tex2D(Texture, ps_in.tex) * ps_in.col;}";
248
249 _ps[PS_TEX_COLOR_FILTER] = (LPDIRECT3DPIXELSHADER9)
250 CompileShader(d3d, false, "TexColorFilter", buf, sizeof(buf) - 1);
251 if (_ps[PS_TEX_COLOR_FILTER] == NULL)
252 return false;
253 }
254
255 {
256 char buf[] =
257 "sampler Texture : register(s1);\n"
258 "struct VsOutput { float4 pos : POSITION; float2 tex : TEXCOORD0; };\n"
259 "float4 main(VsOutput ps_in) : COLOR0 {\n"
260 "return tex2D(Texture, ps_in.tex);}";
261
262 _ps[PS_TEX_2] = (LPDIRECT3DPIXELSHADER9)
263 CompileShader(d3d, false, "Tex2", buf, sizeof(buf) - 1);
264 if (_ps[PS_TEX_2] == NULL)
265 return false;
266 }
267
268 return true;
269}
270
271void *D3DShaderPack::CompileShader(D3DDevice *d3d, bool make_vs,
272 const char *name, const char *buf, int size)
273{
274 LPD3DXBUFFER compiled_res = NULL;
275 LPD3DXBUFFER error_msgs = NULL;
276
277 HRESULT res = D3DXCompileShader(buf, size, NULL, NULL,
278 "main", make_vs ? "vs_2_0" : "ps_2_0", // ?
279 0, &compiled_res, &error_msgs, NULL);
280
281 if (FAILED(res))
282 {
283 ERR("Shader %s compilation failed, code = %X", name, res);
284 if (error_msgs == NULL)
285 return NULL;
286 const char *mess = (const char *)error_msgs->GetBufferPointer();
287 ERR("Error output:\n%s", mess);
288 error_msgs->Release();
289 return NULL;
290 }
291
292 if (error_msgs != NULL)
293 error_msgs->Release();
294
295 void *res_ptr = NULL;
296 if (make_vs)
297 {
298 LPDIRECT3DVERTEXSHADER9 vs;
299 res = d3d->GetDevice()->CreateVertexShader((DWORD *)compiled_res->GetBufferPointer(), &vs);
300 res_ptr = (void *)vs;
301 }
302 else
303 {
304 LPDIRECT3DPIXELSHADER9 ps;
305 res = d3d->GetDevice()->CreatePixelShader((DWORD *)compiled_res->GetBufferPointer(), &ps);
306 res_ptr = (void *)ps;
307 }
308
309 compiled_res->Release();
310
311 if (FAILED(res))
312 {
313 WRN("Shader %s creation failed, code = %X", name, res);
314 return NULL;
315 }
316 return res_ptr;
317}
318
319bool D3DShaderPack::SetVDecl(D3DDevice *d3d, int id)
320{
321 if (id < 0 || id >= _vdecl.Length() || _vdecl[id] == NULL)
322 return false;
323 assert(d3d != NULL);
324 d3d->GetDevice()->SetVertexDeclaration(_vdecl[id]);
325 return true;
326}
327
328bool D3DShaderPack::SetVS(D3DDevice *d3d, int id)
329{
330 if (id < 0 || id >= _vs.Length() || _vs[id] == NULL)
331 return false;
332 assert(d3d != NULL);
333 d3d->GetDevice()->SetVertexShader(_vs[id]);
334 return true;
335}
336
337bool D3DShaderPack::SetPS(D3DDevice *d3d, int id)
338{
339 if (id < 0 || id >= _ps.Length() || _ps[id] == NULL)
340 return false;
341 assert(d3d != NULL);
342 d3d->GetDevice()->SetPixelShader(_ps[id]);
343 return true;
344}