VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/gallium/test/d3d9render.cpp

Last change on this file was 98909, checked in by vboxsync, 14 months ago

WDDM: testcase update

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 49.2 KB
Line 
1/* $Id: d3d9render.cpp 98909 2023-03-10 16:49:13Z vboxsync $ */
2/** @file
3 * Gallium D3D testcase. Simple D3D9 tests.
4 */
5
6/*
7 * Copyright (C) 2017-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#include "d3d9render.h"
29
30#include <intrin.h>
31
32static HRESULT d3dCopyToVertexBuffer(IDirect3DVertexBuffer9 *pVB, const void *pvSrc, int cbSrc)
33{
34 HRESULT hr = D3D_OK;
35 void *pvDst = 0;
36 HTEST(pVB->Lock(0, 0, &pvDst, 0));
37 if (SUCCEEDED(hr))
38 {
39 memcpy(pvDst, pvSrc, cbSrc);
40 HTEST(pVB->Unlock());
41 }
42 return hr;
43}
44
45static HRESULT d3dCopyToIndexBuffer(IDirect3DIndexBuffer9 *pIB, const void *pvSrc, int cbSrc)
46{
47 HRESULT hr = D3D_OK;
48 void *pvDst = 0;
49 HTEST(pIB->Lock(0, 0, &pvDst, 0));
50 if (SUCCEEDED(hr))
51 {
52 memcpy(pvDst, pvSrc, cbSrc);
53 HTEST(pIB->Unlock());
54 }
55 return hr;
56}
57
58static void drawTexture(IDirect3DDevice9 *pDevice, IDirect3DTexture9 *pTexture, int x, int y, int w, int h)
59{
60 HRESULT hr = S_OK;
61
62 HTEST(pDevice->Clear(0, 0, D3DCLEAR_TARGET, 0xffafaf00, 0.0f, 0));
63
64 HTEST(pDevice->BeginScene());
65
66 IDirect3DSurface9 *pSurface;
67 HTEST(pTexture->GetSurfaceLevel(0, &pSurface));
68
69 /* Copy the texture to the backbuffer. */
70 IDirect3DSurface9 *pBackBuffer;
71 HTEST(pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer));
72
73 RECT rDst;
74 rDst.left = x;
75 rDst.top = y;
76 rDst.right = x + w;
77 rDst.bottom = y + h;
78
79 HTEST(pDevice->StretchRect(pSurface, NULL, pBackBuffer, &rDst, D3DTEXF_POINT));
80
81 HTEST(pDevice->EndScene());
82
83 D3D_RELEASE(pBackBuffer);
84 D3D_RELEASE(pSurface);
85}
86
87
88/*
89 * Clear the backbuffer and display it.
90 */
91
92class D3D9RenderClear: public D3D9Render
93{
94public:
95 D3D9RenderClear() {}
96 virtual ~D3D9RenderClear() {}
97 virtual HRESULT InitRender(D3D9DeviceProvider *pDP);
98 virtual HRESULT DoRender(D3D9DeviceProvider *pDP);
99};
100
101HRESULT D3D9RenderClear::InitRender(D3D9DeviceProvider *pDP)
102{
103 (void)pDP;
104 return S_OK;
105}
106
107HRESULT D3D9RenderClear::DoRender(D3D9DeviceProvider *pDP)
108{
109 IDirect3DDevice9 *pDevice = pDP->Device(0);
110
111 pDevice->Clear(0, 0, D3DCLEAR_TARGET /* | D3DCLEAR_ZBUFFER */, 0xff0000ff, 1.0f, 0);
112
113 /* Separately test depth. This triggered a unimplemented code path in SVGA driver. */
114 D3DRECT r;
115 r.x1 = 20;
116 r.y1 = 20;
117 r.x2 = 120;
118 r.y2 = 120;
119 pDevice->Clear(1, &r, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
120
121 pDevice->Present(0, 0, 0, 0);
122 return S_OK;
123}
124
125
126/*
127 * Minimal code to draw a black triangle.
128 */
129
130class D3D9RenderTriangle: public D3D9Render
131{
132public:
133 D3D9RenderTriangle();
134 virtual ~D3D9RenderTriangle();
135 virtual HRESULT InitRender(D3D9DeviceProvider *pDP);
136 virtual HRESULT DoRender(D3D9DeviceProvider *pDP);
137private:
138 IDirect3DVertexDeclaration9 *mpVertexDecl;
139 IDirect3DVertexBuffer9 *mpVB;
140
141 struct Vertex
142 {
143 D3DVECTOR position;
144 };
145
146 static D3DVERTEXELEMENT9 maVertexElements[];
147};
148
149D3DVERTEXELEMENT9 D3D9RenderTriangle::maVertexElements[] =
150{
151 { 0, GA_W_OFFSET_OF(Vertex, position), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
152 D3DDECL_END()
153};
154
155D3D9RenderTriangle::D3D9RenderTriangle()
156 :
157 mpVertexDecl(0),
158 mpVB(0)
159{
160}
161
162D3D9RenderTriangle::~D3D9RenderTriangle()
163{
164 D3D_RELEASE(mpVertexDecl);
165 D3D_RELEASE(mpVB);
166}
167
168HRESULT D3D9RenderTriangle::InitRender(D3D9DeviceProvider *pDP)
169{
170 IDirect3DDevice9 *pDevice = pDP->Device(0);
171
172 HRESULT hr = pDevice->CreateVertexDeclaration(maVertexElements, &mpVertexDecl);
173 if (FAILED(hr))
174 {
175 return hr;
176 }
177
178 /* Coords are choosen to avoid setting the view and projection matrices. */
179 static Vertex aVertices[] =
180 {
181 { {-0.5f, -0.5f, 0.9f } },
182 { { 0.0f, 0.5f, 0.9f } },
183 { { 0.5f, -0.5f, 0.9f } },
184 };
185
186 hr = pDevice->CreateVertexBuffer(sizeof(aVertices), 0, 0, D3DPOOL_DEFAULT, &mpVB, 0);
187 if (FAILED(hr))
188 {
189 return hr;
190 }
191
192 hr = d3dCopyToVertexBuffer(mpVB, aVertices, sizeof(aVertices));
193
194 return hr;
195}
196
197HRESULT D3D9RenderTriangle::DoRender(D3D9DeviceProvider *pDP)
198{
199 IDirect3DDevice9 *pDevice = pDP->Device(0);
200
201 HRESULT hr = S_OK;
202
203 HTEST(pDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0));
204
205 HTEST(pDevice->BeginScene());
206
207 HTEST(pDevice->SetStreamSource(0, mpVB, 0, sizeof(Vertex)));
208 HTEST(pDevice->SetVertexDeclaration(mpVertexDecl));
209
210 HTEST(pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1));
211
212 HTEST(pDevice->EndScene());
213
214 HTEST(pDevice->Present(0, 0, 0, 0));
215 return S_OK;
216}
217
218
219/*
220 * Colorful triangle using FVF.
221 */
222
223class D3D9RenderTriangleFVF: public D3D9Render
224{
225public:
226 D3D9RenderTriangleFVF();
227 virtual ~D3D9RenderTriangleFVF();
228 virtual HRESULT InitRender(D3D9DeviceProvider *pDP);
229 virtual HRESULT DoRender(D3D9DeviceProvider *pDP);
230private:
231 IDirect3DVertexBuffer9 *mpVB;
232
233 struct Vertex_XYZRHW_DIFFUSE
234 {
235 FLOAT x, y, z, rhw;
236 DWORD color;
237 };
238};
239
240#define FVF_XYZRHW_DIFFUSE (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)
241
242D3D9RenderTriangleFVF::D3D9RenderTriangleFVF()
243 :
244 mpVB(0)
245{
246}
247
248D3D9RenderTriangleFVF::~D3D9RenderTriangleFVF()
249{
250 D3D_RELEASE(mpVB);
251}
252
253HRESULT D3D9RenderTriangleFVF::InitRender(D3D9DeviceProvider *pDP)
254{
255 IDirect3DDevice9 *pDevice = pDP->Device(0);
256
257 static Vertex_XYZRHW_DIFFUSE aVertices[] =
258 {
259 { 50.0f, 50.0f, 0.5f, 1.0f, D3DCOLOR_XRGB( 0, 0, 255), },
260 { 150.0f, 50.0f, 0.5f, 1.0f, D3DCOLOR_XRGB( 0, 255, 0), },
261 { 100.0f, 150.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(255, 0, 0), },
262 };
263
264 HRESULT hr = S_OK;
265
266 HTEST(pDevice->CreateVertexBuffer(sizeof(aVertices),
267 0,
268 FVF_XYZRHW_DIFFUSE,
269 D3DPOOL_DEFAULT,
270 &mpVB,
271 0));
272 if (FAILED(hr))
273 {
274 return hr;
275 }
276
277 HTEST(d3dCopyToVertexBuffer(mpVB, aVertices, sizeof(aVertices)));
278
279 return hr;
280}
281
282HRESULT D3D9RenderTriangleFVF::DoRender(D3D9DeviceProvider *pDP)
283{
284 IDirect3DDevice9 *pDevice = pDP->Device(0);
285
286 HRESULT hr = S_OK;
287
288 HTEST(pDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffafafaf, 1.0f, 0));
289
290 HTEST(pDevice->BeginScene());
291
292 HTEST(pDevice->SetStreamSource(0, mpVB, 0, sizeof(Vertex_XYZRHW_DIFFUSE)));
293 HTEST(pDevice->SetFVF(FVF_XYZRHW_DIFFUSE));
294
295 HTEST(pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1));
296
297 HTEST(pDevice->EndScene());
298
299 HTEST(pDevice->Present(0, 0, 0, 0));
300 return S_OK;
301}
302
303
304/*
305 * Colorful triangle using shaders.
306 */
307
308class D3D9RenderTriangleShader: public D3D9Render
309{
310public:
311 D3D9RenderTriangleShader();
312 virtual ~D3D9RenderTriangleShader();
313 virtual HRESULT InitRender(D3D9DeviceProvider *pDP);
314 virtual HRESULT DoRender(D3D9DeviceProvider *pDP);
315private:
316 IDirect3DVertexBuffer9 *mpVB;
317 IDirect3DVertexDeclaration9 *mpVertexDecl;
318 IDirect3DVertexShader9 *mpVS;
319 IDirect3DPixelShader9 *mpPS;
320
321 struct Vertex
322 {
323 D3DVECTOR position;
324 D3DCOLOR color;
325 };
326 static D3DVERTEXELEMENT9 VertexElements[];
327};
328
329D3DVERTEXELEMENT9 D3D9RenderTriangleShader::VertexElements[] =
330{
331 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
332 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
333 D3DDECL_END()
334};
335
336
337D3D9RenderTriangleShader::D3D9RenderTriangleShader()
338 :
339 mpVB(0),
340 mpVertexDecl(0),
341 mpVS(0),
342 mpPS(0)
343{
344}
345
346D3D9RenderTriangleShader::~D3D9RenderTriangleShader()
347{
348 D3D_RELEASE(mpVS);
349 D3D_RELEASE(mpPS);
350 D3D_RELEASE(mpVB);
351 D3D_RELEASE(mpVertexDecl);
352}
353
354HRESULT D3D9RenderTriangleShader::InitRender(D3D9DeviceProvider *pDP)
355{
356 IDirect3DDevice9 *pDevice = pDP->Device(0);
357
358 static DWORD aVSCode[] =
359 {
360 0xFFFE0200, // vs_2_0
361 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, // def c0, 1, 0, 0, 0
362 0x0200001f, 0x80000000, 0x900f0000, // dcl_position v0
363 0x0200001f, 0x8000000a, 0x900f0001, // dcl_color v1
364 0x02000001, 0xc0070000, 0x90e40000, // mov oPos.xyz, v0
365 0x02000001, 0xc0080000, 0xa0000000, // mov oPos.w, c0.x
366 0x02000001, 0xd00f0000, 0x90e40001, // mov oD0, v1
367 0x0000FFFF
368 };
369
370 static DWORD aPSCode[] =
371 {
372 0xFFFF0200, // ps_2_0
373 0x0200001f, 0x80000000, 0x900f0000, // dcl v0
374 0x02000001, 0x800f0800, 0x90e40000, // mov oC0, v0
375 0x0000FFFF
376 };
377
378 static DWORD aPSCode1[] =
379 {
380 0xFFFF0200, // ps_2_0
381 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, // def c0, 1, 0, 0, 0
382 0x02000001, 0x800f0000, 0xa0000000, // mov r0, c0.x
383 0x02000001, 0x800f0800, 0x80e40000, // mov oC0, r0
384 0x0000FFFF
385 };
386
387 static DWORD aPSCodeParallax[] =
388 {
389 0xFFFF0300,
390 0x0200001F, 0x80010005, 0x900F0000,
391 0x0200001F, 0x80020005, 0x900F0001,
392 0x0200001F, 0x80030005, 0x900F0002,
393 0x0200001F, 0x80040005, 0x900F0003,
394 0x0200001F, 0x80050005, 0x900F0004,
395 0x0200001F, 0x80060005, 0x900F0005,
396 0x05000051, 0xA00F00F1, 0x3F6147AE, 0x3F451EB8, 0xBF6147AE, 0xBF451EB8,
397 0x0000FFFF
398 };
399
400 static Vertex aVertices[] =
401 {
402 { { -0.5f, -0.5f, 0.5f }, D3DCOLOR_XRGB( 0, 0, 255), },
403 { { 0.5f, -0.5f, 0.5f }, D3DCOLOR_XRGB( 0, 255, 0), },
404 { { 0.0f, 0.5f, 0.5f }, D3DCOLOR_XRGB(255, 0, 0), },
405 };
406
407 HRESULT hr = S_OK;
408
409 HTEST(pDevice->CreateVertexDeclaration(VertexElements, &mpVertexDecl));
410 HTEST(pDevice->CreateVertexBuffer(sizeof(aVertices),
411 0, /* D3DUSAGE_* */
412 0, /* FVF */
413 D3DPOOL_DEFAULT,
414 &mpVB,
415 0));
416 HTEST(pDevice->CreateVertexShader(aVSCode, &mpVS));
417 HTEST(pDevice->CreatePixelShader(aPSCode, &mpPS));
418
419 HTEST(d3dCopyToVertexBuffer(mpVB, aVertices, sizeof(aVertices)));
420
421 return hr;
422}
423
424HRESULT D3D9RenderTriangleShader::DoRender(D3D9DeviceProvider *pDP)
425{
426 IDirect3DDevice9 *pDevice = pDP->Device(0);
427
428 HRESULT hr = S_OK;
429
430 HTEST(pDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffafafaf, 1.0f, 0));
431
432 HTEST(pDevice->BeginScene());
433
434 HTEST(pDevice->SetStreamSource(0, mpVB, 0, sizeof(Vertex)));
435 HTEST(pDevice->SetVertexDeclaration(mpVertexDecl));
436 HTEST(pDevice->SetVertexShader(mpVS));
437 HTEST(pDevice->SetPixelShader(mpPS));
438 HTEST(pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE));
439
440 HTEST(pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1));
441
442 HTEST(pDevice->EndScene());
443
444 HTEST(pDevice->Present(0, 0, 0, 0));
445 return S_OK;
446}
447
448
449/*
450 * Cubemap texture.
451 */
452
453class D3D9RenderCubeMap: public D3D9Render
454{
455 public:
456 D3D9RenderCubeMap();
457 virtual ~D3D9RenderCubeMap();
458 virtual HRESULT InitRender(D3D9DeviceProvider *pDP);
459 virtual HRESULT DoRender(D3D9DeviceProvider *pDP);
460 virtual void TimeAdvance(float dt);
461
462 private:
463 IDirect3DVertexDeclaration9 *mpVertexDecl;
464 IDirect3DVertexBuffer9 *mpVertexBuffer;
465 IDirect3DCubeTexture9 *mpCubeTexture;
466 IDirect3DVertexShader9 *mpVS;
467 IDirect3DPixelShader9 *mpPS;
468
469 D3DCamera mCamera;
470
471 static D3DVERTEXELEMENT9 maVertexElements[];
472};
473
474D3DVERTEXELEMENT9 D3D9RenderCubeMap::maVertexElements[] =
475{
476 { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
477 D3DDECL_END()
478};
479
480D3D9RenderCubeMap::D3D9RenderCubeMap()
481 :
482 mpVertexDecl(0),
483 mpVertexBuffer(0),
484 mpCubeTexture(0),
485 mpVS(0),
486 mpPS(0)
487{
488}
489
490D3D9RenderCubeMap::~D3D9RenderCubeMap()
491{
492 D3D_RELEASE(mpVS);
493 D3D_RELEASE(mpPS);
494 D3D_RELEASE(mpVertexBuffer);
495 D3D_RELEASE(mpVertexDecl);
496 D3D_RELEASE(mpCubeTexture);
497}
498
499HRESULT D3D9RenderCubeMap::InitRender(D3D9DeviceProvider *pDP)
500{
501 IDirect3DDevice9 *pDevice = pDP->Device(0);
502
503 static const DWORD aVSCubeMap[] =
504 {
505 0xfffe0200, // vs_2_0
506 0x05000051, 0xa00f0004, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, // def c4, 1, 0, 0, 0
507 0x0200001f, 0x80000000, 0x900f0000, // dcl_position v0
508 0x04000004, 0x800f0000, 0x90240000, 0xa0400004, 0xa0150004, // mad r0, v0.xyzx, c4.xxxy, c4.yyyx
509 0x03000009, 0x80010001, 0x80e40000, 0xa0e40000, // dp4 r1.x, r0, c0
510 0x03000009, 0x80020001, 0x80e40000, 0xa0e40001, // dp4 r1.y, r0, c1
511 0x03000009, 0x80040001, 0x80e40000, 0xa0e40003, // dp4 r1.z, r0, c3
512 0x02000001, 0xc00f0000, 0x80a40001, // mov oPos, r1.xyzz
513 0x02000001, 0xe0070000, 0x90e40000, // mov oT0.xyz, v0
514 0x0000ffff
515 };
516
517 static const DWORD aPSCubeMap[] =
518 {
519 0xffff0200, // ps_2_0
520 0x0200001f, 0x80000000, 0xb0070000, // dcl t0.xyz
521 0x0200001f, 0x98000000, 0xa00f0800, // dcl_cube s0
522 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, // texld r0, t0, s0
523 0x02000001, 0x800f0800, 0x80e40000, // mov oC0, r0
524 0x0000ffff
525 };
526
527 HRESULT hr = S_OK;
528
529 HTEST(pDevice->CreateVertexDeclaration(maVertexElements, &mpVertexDecl));
530 HTEST(d3dCreateCubeVertexBuffer(pDevice, 1.0f, &mpVertexBuffer));
531 HTEST(d3dCreateCubeTexture(pDevice, &mpCubeTexture));
532 HTEST(pDevice->CreateVertexShader(aVSCubeMap, &mpVS));
533 HTEST(pDevice->CreatePixelShader(aPSCubeMap, &mpPS));
534
535 float w = 800;
536 float h = 600;
537 mCamera.SetProjection(3.14f * 0.5f, w/h, 1.0f, 100.0f);
538
539 return S_OK;
540}
541
542HRESULT D3D9RenderCubeMap::DoRender(D3D9DeviceProvider *pDP)
543{
544 IDirect3DDevice9 *pDevice = pDP->Device(0);
545
546 HRESULT hr = S_OK;
547
548 // HTEST(pDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0));
549
550 HTEST(pDevice->BeginScene());
551
552 /* World matrix is identity matrix, i.e. need only View and Projection. */
553 D3DMATRIX WVP = *mCamera.ViewProjection();
554 d3dMatrixTranspose(&WVP); /* Because shader will multiply vector row by matrix column, i.e. columns must be in the shader constants. */
555
556 HTEST(pDevice->SetVertexShader(mpVS));
557 HTEST(pDevice->SetPixelShader(mpPS));
558
559 HTEST(pDevice->SetVertexShaderConstantF(0, &WVP.m[0][0], 4));
560 HTEST(pDevice->SetTexture(0, mpCubeTexture));
561
562 HTEST(pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE));
563 HTEST(pDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS));
564
565 HTEST(pDevice->SetVertexDeclaration(mpVertexDecl));
566 HTEST(pDevice->SetStreamSource(0, mpVertexBuffer, 0, 3 * sizeof(float)));
567
568 HTEST(pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 6 * 2));
569
570 HTEST(pDevice->EndScene());
571
572 HTEST(pDevice->Present(0, 0, 0, 0));
573
574 return S_OK;
575}
576
577void D3D9RenderCubeMap::TimeAdvance(float dt)
578{
579 mCamera.TimeAdvance(dt);
580}
581
582
583/*
584 * Solid triangles using shaders and instancing.
585 */
586
587class D3D9RenderInstance: public D3D9Render
588{
589public:
590 D3D9RenderInstance();
591 virtual ~D3D9RenderInstance();
592 virtual HRESULT InitRender(D3D9DeviceProvider *pDP);
593 virtual HRESULT DoRender(D3D9DeviceProvider *pDP);
594private:
595 IDirect3DVertexBuffer9 *mpVBGeometry;
596 IDirect3DVertexBuffer9 *mpVBInstance;
597 IDirect3DIndexBuffer9 *mpIB;
598 IDirect3DVertexDeclaration9 *mpVertexDecl;
599 IDirect3DVertexShader9 *mpVS;
600 IDirect3DPixelShader9 *mpPS;
601
602 struct VertexGeometry
603 {
604 D3DVECTOR position;
605 };
606
607 struct VertexInstance
608 {
609 D3DCOLOR color;
610 float dy;
611 };
612 static D3DVERTEXELEMENT9 VertexElements[];
613};
614
615D3DVERTEXELEMENT9 D3D9RenderInstance::VertexElements[] =
616{
617 {0, GA_W_OFFSET_OF(VertexGeometry, position), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
618 {1, GA_W_OFFSET_OF(VertexInstance, color), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
619 {1, GA_W_OFFSET_OF(VertexInstance, dy), D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
620 D3DDECL_END()
621};
622
623
624D3D9RenderInstance::D3D9RenderInstance()
625 :
626 mpVBGeometry(0),
627 mpVBInstance(0),
628 mpIB(0),
629 mpVertexDecl(0),
630 mpVS(0),
631 mpPS(0)
632{
633}
634
635D3D9RenderInstance::~D3D9RenderInstance()
636{
637 D3D_RELEASE(mpVBGeometry);
638 D3D_RELEASE(mpVBInstance);
639 D3D_RELEASE(mpIB);
640 D3D_RELEASE(mpVertexDecl);
641 D3D_RELEASE(mpVS);
642 D3D_RELEASE(mpPS);
643}
644
645HRESULT D3D9RenderInstance::InitRender(D3D9DeviceProvider *pDP)
646{
647 IDirect3DDevice9 *pDevice = pDP->Device(0);
648
649 static DWORD aVSCode[] =
650 {
651 0xfffe0200, // vs_2_0
652 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, // def c0, 1, 0, 0, 0
653 0x0200001f, 0x80000000, 0x900f0000, // dcl_position v0
654 0x0200001f, 0x8000000a, 0x900f0001, // dcl_color v1
655 0x0200001f, 0x80000005, 0x900f0002, // dcl_texcoord v2
656 0x02000001, 0x80020000, 0x90550000, // mov r0.y, v0.y
657 0x03000002, 0xc0020000, 0x80550000, 0x90000002, // add oPos.y, r0.y, v2.x
658 0x02000001, 0xc0050000, 0x90e40000, // mov oPos.xz, v0
659 0x02000001, 0xc0080000, 0xa0000000, // mov oPos.w, c0.x
660 0x02000001, 0xd00f0000, 0x90e40001, // mov oD0, v1
661 0x0000ffff
662 };
663
664 static DWORD aPSCode[] =
665 {
666 0xFFFF0200, // ps_2_0
667 0x0200001f, 0x80000000, 0x900f0000, // dcl v0
668 0x02000001, 0x800f0800, 0x90e40000, // mov oC0, v0
669 0x0000FFFF
670 };
671
672 static VertexGeometry aVerticesGeometry[] =
673 {
674 { { -0.5f, -0.5f, 0.5f } },
675 { { 0.5f, -0.5f, 0.5f } },
676 { { 0.0f, 0.5f, 0.5f } },
677 };
678
679 static VertexInstance aVerticesInstance[] =
680 {
681 { D3DCOLOR_XRGB( 0, 0, 255), -0.5f },
682 { D3DCOLOR_XRGB( 0, 255, 0), 0.0f },
683 { D3DCOLOR_XRGB(255, 0, 0), 0.5f },
684 };
685
686 static USHORT aIndices[] =
687 {
688 0, 1, 2
689 };
690
691 HRESULT hr = S_OK;
692
693 HTEST(pDevice->CreateVertexDeclaration(VertexElements, &mpVertexDecl));
694
695 HTEST(pDevice->CreateVertexBuffer(sizeof(aVerticesGeometry),
696 0, /* D3DUSAGE_* */
697 0, /* FVF */
698 D3DPOOL_DEFAULT,
699 &mpVBGeometry,
700 0));
701 HTEST(pDevice->CreateVertexBuffer(sizeof(aVerticesInstance),
702 0, /* D3DUSAGE_* */
703 0, /* FVF */
704 D3DPOOL_DEFAULT,
705 &mpVBInstance,
706 0));
707
708 HTEST(pDevice->CreateIndexBuffer(sizeof(aIndices),
709 0, /* D3DUSAGE_* */
710 D3DFMT_INDEX16,
711 D3DPOOL_DEFAULT,
712 &mpIB,
713 0));
714
715 HTEST(pDevice->CreateVertexShader(aVSCode, &mpVS));
716 HTEST(pDevice->CreatePixelShader(aPSCode, &mpPS));
717
718 HTEST(d3dCopyToVertexBuffer(mpVBGeometry, aVerticesGeometry, sizeof(aVerticesGeometry)));
719 HTEST(d3dCopyToVertexBuffer(mpVBInstance, aVerticesInstance, sizeof(aVerticesInstance)));
720 HTEST(d3dCopyToIndexBuffer(mpIB, aIndices, sizeof(aIndices)));
721
722 return hr;
723}
724
725HRESULT D3D9RenderInstance::DoRender(D3D9DeviceProvider *pDP)
726{
727 IDirect3DDevice9 *pDevice = pDP->Device(0);
728
729 HRESULT hr = S_OK;
730
731 HTEST(pDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffafafaf, 1.0f, 0));
732
733 HTEST(pDevice->BeginScene());
734
735 HTEST(pDevice->SetStreamSource(0, mpVBGeometry, 0, sizeof(VertexGeometry)));
736 /* Draw 2 instances, which should produce a solid blue triangle and a green one. */
737 HTEST(pDevice->SetStreamSourceFreq(0, D3DSTREAMSOURCE_INDEXEDDATA | 2U));
738
739 HTEST(pDevice->SetStreamSource(1, mpVBInstance, 0, sizeof(VertexInstance)));
740 HTEST(pDevice->SetStreamSourceFreq(1, D3DSTREAMSOURCE_INSTANCEDATA | 1U));
741
742 HTEST(pDevice->SetVertexDeclaration(mpVertexDecl));
743 HTEST(pDevice->SetVertexShader(mpVS));
744 HTEST(pDevice->SetPixelShader(mpPS));
745 HTEST(pDevice->SetIndices(mpIB));
746 HTEST(pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE));
747
748 HTEST(pDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
749 0, /* BaseVertexIndex */
750 0, /* MinIndex */
751 3, /* NumVertices */
752 0, /* StartIndex */
753 1)); /* PrimitiveCount */
754
755 HTEST(pDevice->SetStreamSourceFreq(0, 1));
756 HTEST(pDevice->SetStreamSourceFreq(1, 1));
757
758 HTEST(pDevice->EndScene());
759
760 HTEST(pDevice->Present(0, 0, 0, 0));
761 return S_OK;
762}
763
764
765/*
766 * Solid triangles with different Z positions.
767 */
768
769class D3D9RenderDepth: public D3D9Render
770{
771public:
772 D3D9RenderDepth();
773 virtual ~D3D9RenderDepth();
774 virtual HRESULT InitRender(D3D9DeviceProvider *pDP);
775 virtual HRESULT DoRender(D3D9DeviceProvider *pDP);
776private:
777 IDirect3DVertexBuffer9 *mpVB;
778 IDirect3DVertexDeclaration9 *mpVertexDecl;
779 IDirect3DVertexShader9 *mpVS;
780 IDirect3DPixelShader9 *mpPS;
781
782 D3DCamera mCamera;
783
784 struct Vertex
785 {
786 D3DVECTOR position;
787 };
788 static D3DVERTEXELEMENT9 VertexElements[];
789};
790
791D3DVERTEXELEMENT9 D3D9RenderDepth::VertexElements[] =
792{
793 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
794 D3DDECL_END()
795};
796
797
798D3D9RenderDepth::D3D9RenderDepth()
799 :
800 mpVB(0),
801 mpVertexDecl(0),
802 mpVS(0),
803 mpPS(0)
804{
805}
806
807D3D9RenderDepth::~D3D9RenderDepth()
808{
809 D3D_RELEASE(mpVS);
810 D3D_RELEASE(mpPS);
811 D3D_RELEASE(mpVB);
812 D3D_RELEASE(mpVertexDecl);
813}
814
815HRESULT D3D9RenderDepth::InitRender(D3D9DeviceProvider *pDP)
816{
817 IDirect3DDevice9 *pDevice = pDP->Device(0);
818
819 static DWORD aVSCode[] =
820 {
821 0xfffe0200, // vs_2_0
822 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, // def c5, 1, 0, 0, 0
823 0x0200001f, 0x80000000, 0x900f0000, // dcl_position v0
824 0x04000004, 0x800f0000, 0x90240000, 0xa0400005, 0xa0150005, // mad r0, v0.xyzx, c5.xxxy, c5.yyyx
825 0x03000009, 0xc0010000, 0x80e40000, 0xa0e40000, // dp4 oPos.x, r0, c0
826 0x03000009, 0xc0020000, 0x80e40000, 0xa0e40001, // dp4 oPos.y, r0, c1
827 0x03000009, 0xc0040000, 0x80e40000, 0xa0e40002, // dp4 oPos.z, r0, c2
828 0x03000009, 0xc0080000, 0x80e40000, 0xa0e40003, // dp4 oPos.w, r0, c3
829 0x02000001, 0xd00f0000, 0xa0e40004, // mov oD0, c4
830 0x0000ffff
831 };
832
833 static DWORD aPSCode[] =
834 {
835 0xFFFF0200, // ps_2_0
836 0x0200001f, 0x80000000, 0x900f0000, // dcl v0
837 0x02000001, 0x800f0800, 0x90e40000, // mov oC0, v0
838 0x0000FFFF
839 };
840
841 static Vertex aVertices[] =
842 {
843 { { -1.0f, -1.0f, 0.0f } },
844 { { 1.0f, -1.0f, 0.0f } },
845 { { 0.0f, 1.0f, 0.0f } },
846 };
847
848 HRESULT hr = S_OK;
849
850 HTEST(pDevice->CreateVertexDeclaration(VertexElements, &mpVertexDecl));
851 HTEST(pDevice->CreateVertexBuffer(sizeof(aVertices),
852 0, /* D3DUSAGE_* */
853 0, /* FVF */
854 D3DPOOL_DEFAULT,
855 &mpVB,
856 0));
857 HTEST(pDevice->CreateVertexShader(aVSCode, &mpVS));
858 HTEST(pDevice->CreatePixelShader(aPSCode, &mpPS));
859
860 HTEST(d3dCopyToVertexBuffer(mpVB, aVertices, sizeof(aVertices)));
861
862 const D3DVECTOR cameraPosition = { 0.0f, 0.0f, -10.0f };
863 const D3DVECTOR cameraAt = { 0.0f, 0.0f, 1.0f };
864 const D3DVECTOR cameraUp = { 0.0f, 1.0f, 0.0f };
865 mCamera.SetupAt(&cameraPosition, &cameraAt, &cameraUp);
866
867 float w = 800;
868 float h = 600;
869 mCamera.SetProjection(3.14f * 0.5f, w/h, 1.0f, 100.0f);
870
871 return hr;
872}
873
874static void d3d9RenderDepthDrawTriangle(IDirect3DDevice9 *pDevice, D3DCamera *pCamera,
875 float s, float x, float y, float z, D3DCOLOR color)
876{
877 HRESULT hr; /* Used by HTEST. */
878
879 /* Calc world matrix. */
880 D3DMATRIX mtxST;
881 d3dMatrixScaleTranslation(&mtxST, s, x, y, z);
882
883 D3DMATRIX WVP;
884 d3dMatrixMultiply(&WVP, &mtxST, pCamera->ViewProjection());
885
886 /* Transpose, because shader will multiply vector row by matrix column,
887 * i.e. columns must be in the shader constants.
888 */
889 d3dMatrixTranspose(&WVP);
890
891 HTEST(pDevice->SetVertexShaderConstantF(0, &WVP.m[0][0], 4));
892
893 /* Set color of the triangle. */
894 float aColor[4];
895 aColor[0] = 1.0f * (float)((color >> 16) & 0xff) / 255.0f;
896 aColor[1] = 1.0f * (float)((color >> 8) & 0xff) / 255.0f;
897 aColor[2] = 1.0f * (float)((color ) & 0xff) / 255.0f;
898 aColor[3] = 1.0f;
899 HTEST(pDevice->SetVertexShaderConstantF(4, &aColor[0], 1));
900
901 HTEST(pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1));
902}
903
904HRESULT D3D9RenderDepth::DoRender(D3D9DeviceProvider *pDP)
905{
906 IDirect3DDevice9 *pDevice = pDP->Device(0);
907
908 HRESULT hr;
909
910 HTEST(pDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff7f7f7f, 1.0f, 0));
911
912 D3DVIEWPORT9 viewport;
913 HTEST(pDevice->GetViewport(&viewport));
914
915 HTEST(pDevice->SetVertexShader(mpVS));
916 HTEST(pDevice->SetPixelShader(mpPS));
917
918 HTEST(pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE));
919 HTEST(pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE));
920
921 HTEST(pDevice->SetVertexDeclaration(mpVertexDecl));
922 HTEST(pDevice->SetStreamSource(0, mpVB, 0, 3 * sizeof(float)));
923
924 HTEST(pDevice->BeginScene());
925
926 viewport.MinZ = 0.2f;
927 viewport.MaxZ = 0.3f;
928 HTEST(pDevice->SetViewport(&viewport));
929
930 d3d9RenderDepthDrawTriangle(pDevice, &mCamera, 20.0f, -50.0f, -20.0f, 50.0f, D3DCOLOR_XRGB(0, 128, 0));
931 d3d9RenderDepthDrawTriangle(pDevice, &mCamera, 20.0f, -40.0f, -10.0f, 55.0f, D3DCOLOR_XRGB(0, 0, 128));
932
933 viewport.MinZ = 0.9f;
934 viewport.MaxZ = 1.0f;
935 HTEST(pDevice->SetViewport(&viewport));
936
937 d3d9RenderDepthDrawTriangle(pDevice, &mCamera, 20.0f, -50.0f, 0.0f, 40.0f, D3DCOLOR_XRGB(0, 255, 0));
938 d3d9RenderDepthDrawTriangle(pDevice, &mCamera, 20.0f, -45.0f, 0.0f, 45.0f, D3DCOLOR_XRGB(0, 0, 255));
939
940 HTEST(pDevice->EndScene());
941
942 HTEST(pDevice->Present(0, 0, 0, 0));
943
944 return S_OK;
945}
946
947
948/*
949 * Shared resource and render to texture.
950 */
951
952class D3D9RenderShared: public D3D9Render
953{
954public:
955 D3D9RenderShared();
956 virtual ~D3D9RenderShared();
957 virtual int RequiredDeviceCount() { return 2; }
958 virtual HRESULT InitRender(D3D9DeviceProvider *pDP);
959 virtual HRESULT DoRender(D3D9DeviceProvider *pDP);
960private:
961 IDirect3DVertexBuffer9 *mpVB;
962 IDirect3DVertexDeclaration9 *mpVertexDecl;
963 IDirect3DVertexShader9 *mpVS;
964 IDirect3DPixelShader9 *mpPS;
965 IDirect3DTexture9 *mpRT;
966 IDirect3DTexture9 *mpTexShared;
967
968 HANDLE mhRtShared;
969 DWORD mdwRtWidth;
970 DWORD mdwRtHeight;
971
972 struct Vertex
973 {
974 D3DVECTOR position;
975 D3DCOLOR color;
976 };
977 static D3DVERTEXELEMENT9 VertexElements[];
978
979 void renderToTexture(IDirect3DDevice9 *pDevice, IDirect3DTexture9 *pTexture);
980};
981
982D3DVERTEXELEMENT9 D3D9RenderShared::VertexElements[] =
983{
984 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
985 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
986 D3DDECL_END()
987};
988
989
990D3D9RenderShared::D3D9RenderShared()
991 :
992 mpVB(0),
993 mpVertexDecl(0),
994 mpVS(0),
995 mpPS(0),
996 mpRT(0),
997 mpTexShared(0)
998{
999 mdwRtWidth = 640;
1000 mdwRtHeight = 480;
1001}
1002
1003D3D9RenderShared::~D3D9RenderShared()
1004{
1005 D3D_RELEASE(mpVS);
1006 D3D_RELEASE(mpPS);
1007 D3D_RELEASE(mpVB);
1008 D3D_RELEASE(mpVertexDecl);
1009 D3D_RELEASE(mpTexShared);
1010 D3D_RELEASE(mpRT);
1011}
1012
1013HRESULT D3D9RenderShared::InitRender(D3D9DeviceProvider *pDP)
1014{
1015 IDirect3DDevice9 *pDevice = pDP->Device(0);
1016
1017 static DWORD aVSCode[] =
1018 {
1019 0xFFFE0200, // vs_2_0
1020 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, // def c0, 1, 0, 0, 0
1021 0x0200001f, 0x80000000, 0x900f0000, // dcl_position v0
1022 0x0200001f, 0x8000000a, 0x900f0001, // dcl_color v1
1023 0x02000001, 0xc0070000, 0x90e40000, // mov oPos.xyz, v0
1024 0x02000001, 0xc0080000, 0xa0000000, // mov oPos.w, c0.x
1025 0x02000001, 0xd00f0000, 0x90e40001, // mov oD0, v1
1026 0x0000FFFF
1027 };
1028
1029 static DWORD aPSCode[] =
1030 {
1031 0xFFFF0200, // ps_2_0
1032 0x0200001f, 0x80000000, 0x900f0000, // dcl v0
1033 0x02000001, 0x800f0800, 0x90e40000, // mov oC0, v0
1034 0x0000FFFF
1035 };
1036
1037 static Vertex aVertices[] =
1038 {
1039 { { -0.5f, -0.5f, 0.5f }, D3DCOLOR_XRGB( 0, 0, 255), },
1040 { { 0.5f, -0.5f, 0.5f }, D3DCOLOR_XRGB( 0, 255, 0), },
1041 { { 0.0f, 0.5f, 0.5f }, D3DCOLOR_XRGB(255, 0, 0), },
1042 };
1043
1044 HRESULT hr = S_OK;
1045
1046 HTEST(pDevice->CreateVertexDeclaration(VertexElements, &mpVertexDecl));
1047 HTEST(pDevice->CreateVertexBuffer(sizeof(aVertices),
1048 0, /* D3DUSAGE_* */
1049 0, /* FVF */
1050 D3DPOOL_DEFAULT,
1051 &mpVB,
1052 0));
1053 HTEST(pDevice->CreateVertexShader(aVSCode, &mpVS));
1054 HTEST(pDevice->CreatePixelShader(aPSCode, &mpPS));
1055
1056 HTEST(d3dCopyToVertexBuffer(mpVB, aVertices, sizeof(aVertices)));
1057
1058 mhRtShared = 0;
1059 HTEST(pDevice->CreateTexture(mdwRtWidth,
1060 mdwRtHeight,
1061 1,
1062 D3DUSAGE_RENDERTARGET,
1063 D3DFMT_X8R8G8B8,
1064 D3DPOOL_DEFAULT,
1065 &mpRT,
1066 &mhRtShared));
1067
1068 return hr;
1069}
1070
1071void D3D9RenderShared::renderToTexture(IDirect3DDevice9 *pDevice, IDirect3DTexture9 *pTexture)
1072{
1073 HRESULT hr = S_OK;
1074
1075 /*
1076 * Render to texture.
1077 */
1078 IDirect3DSurface9 *pSavedRT = NULL;
1079 HTEST(pDevice->GetRenderTarget(0, &pSavedRT));
1080
1081 IDirect3DSurface9 *pSurface = NULL;
1082 HTEST(pTexture->GetSurfaceLevel(0, &pSurface));
1083 HTEST(pDevice->SetRenderTarget(0, pSurface));
1084
1085 HTEST(pDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffafafaf, 1.0f, 0));
1086
1087 HTEST(pDevice->BeginScene());
1088
1089 HTEST(pDevice->SetStreamSource(0, mpVB, 0, sizeof(Vertex)));
1090 HTEST(pDevice->SetVertexDeclaration(mpVertexDecl));
1091 HTEST(pDevice->SetVertexShader(mpVS));
1092 HTEST(pDevice->SetPixelShader(mpPS));
1093 HTEST(pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE));
1094
1095 HTEST(pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1));
1096
1097 HTEST(pDevice->EndScene());
1098
1099 HTEST(pDevice->SetRenderTarget(0, pSavedRT));
1100
1101 D3D_RELEASE(pSurface);
1102}
1103
1104static void issueQuery(IDirect3DDevice9 *pDevice)
1105{
1106 HRESULT hr;
1107
1108 IDirect3DQuery9 *pQuery;
1109 hr = pDevice->CreateQuery(D3DQUERYTYPE_EVENT, &pQuery);
1110 if (hr == D3D_OK)
1111 {
1112 hr = pQuery->Issue(D3DISSUE_END);
1113 if (hr == D3D_OK)
1114 {
1115 do
1116 {
1117 hr = pQuery->GetData(NULL, 0, D3DGETDATA_FLUSH);
1118 } while (hr == S_FALSE);
1119 }
1120
1121 D3D_RELEASE(pQuery);
1122 }
1123}
1124
1125HRESULT D3D9RenderShared::DoRender(D3D9DeviceProvider *pDP)
1126{
1127 HRESULT hr = S_OK;
1128
1129 IDirect3DDevice9 *pDevice = pDP->Device(0);
1130
1131 renderToTexture(pDevice, mpRT);
1132
1133 issueQuery(pDevice);
1134
1135 IDirect3DDevice9 *pDevice2 = pDP->Device(1);
1136 if (pDevice2)
1137 {
1138 HTEST(pDevice2->CreateTexture(mdwRtWidth,
1139 mdwRtHeight,
1140 1,
1141 D3DUSAGE_RENDERTARGET,
1142 D3DFMT_X8R8G8B8,
1143 D3DPOOL_DEFAULT,
1144 &mpTexShared,
1145 &mhRtShared));
1146
1147 drawTexture(pDevice2, mpTexShared, 50, 50, 200, 200);
1148 HTEST(pDevice2->Present(0, 0, 0, 0));
1149 }
1150 else
1151 {
1152 drawTexture(pDevice, mpRT, 50, 50, 200, 200);
1153 HTEST(pDevice->Present(0, 0, 0, 0));
1154 }
1155
1156 return S_OK;
1157}
1158
1159
1160/*
1161 * Use ColorFill to clear a part of the backbuffer.
1162 */
1163
1164class D3D9RenderColorFill: public D3D9Render
1165{
1166public:
1167 D3D9RenderColorFill() {}
1168 virtual ~D3D9RenderColorFill() {}
1169 virtual HRESULT InitRender(D3D9DeviceProvider *pDP);
1170 virtual HRESULT DoRender(D3D9DeviceProvider *pDP);
1171};
1172
1173HRESULT D3D9RenderColorFill::InitRender(D3D9DeviceProvider *pDP)
1174{
1175 (void)pDP;
1176 return S_OK;
1177}
1178
1179HRESULT D3D9RenderColorFill::DoRender(D3D9DeviceProvider *pDP)
1180{
1181 HRESULT hr = S_OK;
1182
1183 IDirect3DDevice9 *pDevice = pDP->Device(0);
1184
1185 pDevice->Clear(0, 0, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
1186
1187 IDirect3DSurface9 *pBackBuffer = NULL;
1188 HTEST(pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer));
1189
1190 RECT rDst;
1191 rDst.left = 50;
1192 rDst.top = 10;
1193 rDst.right = 250;
1194 rDst.bottom = 250;
1195
1196 HTEST(pDevice->ColorFill(pBackBuffer, &rDst, D3DCOLOR_XRGB(0, 255, 0)));
1197
1198 D3D_RELEASE(pBackBuffer);
1199
1200 HTEST(pDevice->Present(0, 0, 0, 0));
1201 return S_OK;
1202}
1203
1204
1205/*
1206 * Render a texture to texture.
1207 */
1208
1209class D3D9RenderTexture: public D3D9Render
1210{
1211public:
1212 D3D9RenderTexture();
1213 virtual ~D3D9RenderTexture();
1214 virtual HRESULT InitRender(D3D9DeviceProvider *pDP);
1215 virtual HRESULT DoRender(D3D9DeviceProvider *pDP);
1216private:
1217 IDirect3DVertexBuffer9 *mpVB;
1218 IDirect3DVertexDeclaration9 *mpVertexDecl;
1219 IDirect3DVertexShader9 *mpVS;
1220 IDirect3DPixelShader9 *mpPS;
1221 IDirect3DTexture9 *mpTexDst;
1222 IDirect3DTexture9 *mpTexSrc;
1223
1224 static const int cxTexture = 8;
1225 static const int cyTexture = 8;
1226
1227 struct Vertex
1228 {
1229 D3DVECTOR position;
1230 float x, y;
1231 };
1232 static D3DVERTEXELEMENT9 VertexElements[];
1233
1234 void renderToTexture(IDirect3DDevice9 *pDevice, IDirect3DTexture9 *pTexture, IDirect3DTexture9 *pTexSrc);
1235};
1236
1237D3DVERTEXELEMENT9 D3D9RenderTexture::VertexElements[] =
1238{
1239 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1240 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1241 D3DDECL_END()
1242};
1243
1244
1245D3D9RenderTexture::D3D9RenderTexture()
1246 :
1247 mpVB(0),
1248 mpVertexDecl(0),
1249 mpVS(0),
1250 mpPS(0),
1251 mpTexDst(0),
1252 mpTexSrc(0)
1253{
1254}
1255
1256D3D9RenderTexture::~D3D9RenderTexture()
1257{
1258 D3D_RELEASE(mpVS);
1259 D3D_RELEASE(mpPS);
1260 D3D_RELEASE(mpVB);
1261 D3D_RELEASE(mpVertexDecl);
1262 D3D_RELEASE(mpTexSrc);
1263 D3D_RELEASE(mpTexDst);
1264}
1265
1266HRESULT D3D9RenderTexture::InitRender(D3D9DeviceProvider *pDP)
1267{
1268 IDirect3DDevice9 *pDevice = pDP->Device(0);
1269
1270 static DWORD aVSCode[] =
1271 {
1272 0xFFFE0200, // vs_2_0
1273 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, // def c0, 1, 0, 0, 0
1274 0x0200001f, 0x80000000, 0x900f0000, // dcl_position v0
1275 0x0200001f, 0x80000005, 0x900f0001, // dcl_texcoord v1
1276 0x02000001, 0xc0070000, 0x90e40000, // mov oPos.xyz, v0
1277 0x02000001, 0xc0080000, 0xa0000000, // mov oPos.w, c0.x
1278 0x02000001, 0xe0030000, 0x90e40001, // mov oT0.xy, v1
1279 0x0000FFFF
1280 };
1281
1282 static DWORD aVSCodeMad[] =
1283 {
1284 0xFFFE0200, // vs_2_0
1285 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, // def c0, 1, 0, 0, 0
1286 0x0200001f, 0x80000000, 0x900f0000, // dcl_position v0
1287 0x0200001f, 0x80000005, 0x900f0001, // dcl_texcoord v1
1288 0x04000004, 0xc00f0000, 0x90240000, 0xa0400000, 0xa0150000, // mad oPos, v0.xyzx, c0.xxxy, c0.yyyx
1289 0x02000001, 0xe0030000, 0x90e40001, // mov oT0.xy, v1
1290 0x0000FFFF
1291 };
1292
1293 static DWORD aPSCodeSwap[] =
1294 {
1295 0xffff0200, // ps_2_0
1296 0x0200001f, 0x80000000, 0xb0030000, // dcl t0.xy
1297 0x0200001f, 0x90000000, 0xa00f0800, // dcl_2d s0
1298 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, // texld r0, t0, s0
1299 0x02000001, 0x80090001, 0x80d20000, // mov r1.xw, r0.zxyw
1300 0x02000001, 0x80040001, 0x80000000, // mov r1.z, r0.x
1301 0x02000001, 0x80020001, 0x80550000, // mov r1.y, r0.y
1302 0x02000001, 0x800f0800, 0x80e40001, // mov oC0, r1
1303 0x0000ffff
1304 };
1305
1306 static DWORD aPSCodePass[] =
1307 {
1308 0xffff0200, // ps_2_0
1309 0x0200001f, 0x80000000, 0xb0030000, // dcl t0.xy
1310 0x0200001f, 0x90000000, 0xa00f0800, // dcl_2d s0
1311 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, // texld r0, t0, s0
1312 0x02000001, 0x800f0800, 0x80e40000, // mov oC0, r0
1313 0x0000ffff
1314 };
1315
1316 static DWORD aPSCodeCoord[] =
1317 {
1318 0xffff0200, // ps_2_0
1319 0x0200001f, 0x80000000, 0xb0010000, // dcl t0.x
1320 0x02000001, 0x800f0000, 0xb0000000, // mov r0, t0.x
1321 0x02000001, 0x800f0800, 0x80e40000, // mov oC0, r0
1322 0x0000ffff
1323 };
1324
1325 static Vertex aVertices[] =
1326 {
1327 { { -1.0f, -1.0f, 0.0f }, 0.0f, 1.0f},
1328 { { 1.0f, -1.0f, 0.0f }, 1.0f, 1.0f},
1329 { { -1.0f, 1.0f, 0.0f }, 0.0f, 0.0f},
1330
1331 { { -1.0f, 1.0f, 0.0f }, 0.0f, 0.0f},
1332 { { 1.0f, -1.0f, 0.0f }, 1.0f, 1.0f},
1333 { { 1.0f, 1.0f, 0.0f }, 1.0f, 0.0f},
1334 };
1335
1336 HRESULT hr = S_OK;
1337
1338 HTEST(pDevice->CreateVertexDeclaration(VertexElements, &mpVertexDecl));
1339 HTEST(pDevice->CreateVertexBuffer(sizeof(aVertices),
1340 0, /* D3DUSAGE_* */
1341 0, /* FVF */
1342 D3DPOOL_DEFAULT,
1343 &mpVB,
1344 0));
1345 HTEST(pDevice->CreateVertexShader(aVSCodeMad, &mpVS));
1346 HTEST(pDevice->CreatePixelShader(aPSCodeSwap, &mpPS));
1347
1348 HTEST(d3dCopyToVertexBuffer(mpVB, aVertices, sizeof(aVertices)));
1349
1350 HTEST(pDevice->CreateTexture(cxTexture,
1351 cyTexture,
1352 1,
1353 D3DUSAGE_RENDERTARGET,
1354 D3DFMT_A8R8G8B8,
1355 D3DPOOL_DEFAULT,
1356 &mpTexDst,
1357 NULL));
1358
1359 HTEST(pDevice->CreateTexture(cxTexture,
1360 cyTexture,
1361 1,
1362 D3DUSAGE_DYNAMIC,
1363 D3DFMT_A8R8G8B8,
1364 D3DPOOL_DEFAULT,
1365 &mpTexSrc,
1366 NULL));
1367
1368 D3DLOCKED_RECT LockedRect;
1369 HTEST(mpTexSrc->LockRect(0, &LockedRect, NULL /* entire texture */, 0));
1370
1371 unsigned char *pScanline = (unsigned char *)LockedRect.pBits;
1372 for (UINT y = 0; y < cxTexture; ++y)
1373 {
1374 for (UINT x = 0; x < cxTexture; ++x)
1375 {
1376 if (x < y)
1377 {
1378 pScanline[x * 4 + 0] = 0xff;
1379 pScanline[x * 4 + 1] = 0x00;
1380 pScanline[x * 4 + 2] = 0x00;
1381 pScanline[x * 4 + 3] = 0x00;
1382 }
1383 else
1384 {
1385 pScanline[x * 4 + 0] = 0x00;
1386 pScanline[x * 4 + 1] = 0x00;
1387 pScanline[x * 4 + 2] = 0xff;
1388 pScanline[x * 4 + 3] = 0x00;
1389 }
1390 }
1391
1392 pScanline += LockedRect.Pitch;
1393 }
1394
1395 HTEST(mpTexSrc->UnlockRect(0));
1396
1397 return hr;
1398}
1399
1400void D3D9RenderTexture::renderToTexture(IDirect3DDevice9 *pDevice, IDirect3DTexture9 *pTexture, IDirect3DTexture9 *pTexSrc)
1401{
1402 HRESULT hr = S_OK;
1403
1404 /*
1405 * Render to texture.
1406 */
1407 IDirect3DSurface9 *pSavedRT = NULL;
1408 HTEST(pDevice->GetRenderTarget(0, &pSavedRT));
1409
1410 IDirect3DSurface9 *pSurface = NULL;
1411 HTEST(pTexture->GetSurfaceLevel(0, &pSurface));
1412 HTEST(pDevice->SetRenderTarget(0, pSurface));
1413
1414 HTEST(pDevice->BeginScene());
1415
1416 HTEST(pDevice->SetStreamSource(0, mpVB, 0, sizeof(Vertex)));
1417 HTEST(pDevice->SetVertexDeclaration(mpVertexDecl));
1418 HTEST(pDevice->SetVertexShader(mpVS));
1419 HTEST(pDevice->SetPixelShader(mpPS));
1420 HTEST(pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE));
1421 HTEST(pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE));
1422
1423 HTEST(pDevice->SetTexture(0, pTexSrc));
1424
1425 HTEST(pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2));
1426
1427 HTEST(pDevice->EndScene());
1428
1429 HTEST(pDevice->SetRenderTarget(0, pSavedRT));
1430
1431 D3D_RELEASE(pSurface);
1432}
1433
1434HRESULT D3D9RenderTexture::DoRender(D3D9DeviceProvider *pDP)
1435{
1436 HRESULT hr = S_OK;
1437
1438 IDirect3DDevice9 *pDevice = pDP->Device(0);
1439
1440 renderToTexture(pDevice, mpTexDst, mpTexSrc);
1441
1442 drawTexture(pDevice, mpTexDst, 50, 50, 200, 200);
1443
1444 HTEST(pDevice->Present(0, 0, 0, 0));
1445
1446 return S_OK;
1447}
1448
1449
1450/*
1451 * Render a texture to screen.
1452 */
1453
1454class D3D9RenderTextureToScreen: public D3D9Render
1455{
1456public:
1457 D3D9RenderTextureToScreen(float cPixelShift);
1458 virtual ~D3D9RenderTextureToScreen();
1459 virtual HRESULT InitRender(D3D9DeviceProvider *pDP);
1460 virtual HRESULT DoRender(D3D9DeviceProvider *pDP);
1461private:
1462 IDirect3DVertexBuffer9 *mpVB;
1463 IDirect3DVertexDeclaration9 *mpVertexDecl;
1464 IDirect3DVertexShader9 *mpVS;
1465 IDirect3DPixelShader9 *mpPS;
1466 IDirect3DTexture9 *mpTex;
1467
1468 static const int cxTexture = 4;
1469 static const int cyTexture = 4;
1470 float mcPixelShift;
1471
1472 struct Vertex
1473 {
1474 D3DVECTOR position;
1475 float x, y;
1476 };
1477 static D3DVERTEXELEMENT9 VertexElements[];
1478 static DWORD adwTextureData[cxTexture * cyTexture];
1479};
1480
1481D3DVERTEXELEMENT9 D3D9RenderTextureToScreen::VertexElements[] =
1482{
1483 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1484 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1485 D3DDECL_END()
1486};
1487
1488DWORD D3D9RenderTextureToScreen::adwTextureData[cxTexture * cyTexture] =
1489{
1490 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00FFFFFF,
1491 0x0000FF00, 0x00FF0000, 0x000000FF, 0x00FFFFFF,
1492 0x00FF0000, 0x000000FF, 0x0000FF00, 0x00FFFFFF,
1493 0x0000FFFF, 0x00FF00FF, 0x00FFFF00, 0x00FFFFFF,
1494};
1495
1496
1497D3D9RenderTextureToScreen::D3D9RenderTextureToScreen(float cPixelShift)
1498 :
1499 mpVB(0),
1500 mpVertexDecl(0),
1501 mpVS(0),
1502 mpPS(0),
1503 mpTex(0),
1504 mcPixelShift(cPixelShift)
1505{
1506}
1507
1508D3D9RenderTextureToScreen::~D3D9RenderTextureToScreen()
1509{
1510 D3D_RELEASE(mpVS);
1511 D3D_RELEASE(mpPS);
1512 D3D_RELEASE(mpVB);
1513 D3D_RELEASE(mpVertexDecl);
1514 D3D_RELEASE(mpTex);
1515}
1516
1517HRESULT D3D9RenderTextureToScreen::InitRender(D3D9DeviceProvider *pDP)
1518{
1519 IDirect3DDevice9 *pDevice = pDP->Device(0);
1520
1521 static DWORD aVSCode[] =
1522 {
1523 0xFFFE0200, // vs_2_0
1524 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, // def c0, 1, 0, 0, 0
1525 0x0200001f, 0x80000000, 0x900f0000, // dcl_position v0
1526 0x0200001f, 0x80000005, 0x900f0001, // dcl_texcoord v1
1527 0x02000001, 0xc0070000, 0x90e40000, // mov oPos.xyz, v0
1528 0x02000001, 0xc0080000, 0xa0000000, // mov oPos.w, c0.x
1529 0x02000001, 0xe0030000, 0x90e40001, // mov oT0.xy, v1
1530 0x0000FFFF
1531 };
1532
1533 static DWORD aPSCodePass[] =
1534 {
1535 0xffff0200, // ps_2_0
1536 0x0200001f, 0x80000000, 0xb0030000, // dcl t0.xy
1537 0x0200001f, 0x90000000, 0xa00f0800, // dcl_2d s0
1538 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, // texld r0, t0, s0
1539 0x02000001, 0x800f0800, 0x80e40000, // mov oC0, r0
1540 0x0000ffff
1541 };
1542
1543 static DWORD aPSCodeCoord[] =
1544 {
1545 0xffff0200, // ps_2_0
1546 0x0200001f, 0x80000000, 0xb0010000, // dcl t0.x
1547 0x02000001, 0x800f0000, 0xb0000000, // mov r0, t0.x
1548 0x02000001, 0x800f0800, 0x80e40000, // mov oC0, r0
1549 0x0000ffff
1550 };
1551
1552 D3DVIEWPORT9 vp;
1553 pDevice->GetViewport(&vp);
1554
1555 int x1 = 1;
1556 int y1 = 1;
1557 int x2 = x1 + cxTexture * 1;
1558 int y2 = y1 + cyTexture * 1;
1559
1560 float cPixelShift = mcPixelShift;
1561
1562 #define VX(x) ( 2.0f * (float(x) + cPixelShift) / float(vp.Width) - 1.0f)
1563 #define VY(y) (-2.0f * (float(y) + cPixelShift) / float(vp.Height) + 1.0f)
1564
1565 Vertex vTopLeft = { { VX(x1), VY(y1), 0.0f }, 0.0f, 0.0f};
1566 Vertex vBottomLeft = { { VX(x1), VY(y2), 0.0f }, 0.0f, 1.0f};
1567 Vertex vTopRight = { { VX(x2), VY(y1), 0.0f }, 1.0f, 0.0f};
1568 Vertex vBottomRight = { { VX(x2), VY(y2), 0.0f }, 1.0f, 1.0f};
1569
1570 Vertex aVertices[6] =
1571 {
1572 vBottomLeft, vBottomRight, vTopLeft,
1573 vTopLeft, vBottomRight, vTopRight
1574 };
1575
1576 HRESULT hr = S_OK;
1577
1578 HTEST(pDevice->CreateVertexDeclaration(VertexElements, &mpVertexDecl));
1579 HTEST(pDevice->CreateVertexBuffer(sizeof(aVertices),
1580 0, /* D3DUSAGE_* */
1581 0, /* FVF */
1582 D3DPOOL_DEFAULT,
1583 &mpVB,
1584 0));
1585 HTEST(pDevice->CreateVertexShader(aVSCode, &mpVS));
1586 HTEST(pDevice->CreatePixelShader(aPSCodePass, &mpPS));
1587
1588 HTEST(d3dCopyToVertexBuffer(mpVB, aVertices, sizeof(aVertices)));
1589
1590 HTEST(pDevice->CreateTexture(cxTexture,
1591 cyTexture,
1592 1,
1593 D3DUSAGE_DYNAMIC,
1594 D3DFMT_A8R8G8B8,
1595 D3DPOOL_DEFAULT,
1596 &mpTex,
1597 NULL));
1598
1599 D3DLOCKED_RECT LockedRect;
1600 HTEST(mpTex->LockRect(0, &LockedRect, NULL /* entire texture */, D3DLOCK_DISCARD));
1601
1602 unsigned char *pu8Dst = (unsigned char *)LockedRect.pBits;
1603 for (int y = 0; y < cyTexture; ++y)
1604 {
1605 memcpy(pu8Dst, &adwTextureData[y * cxTexture], 4 * cxTexture);
1606 pu8Dst += LockedRect.Pitch;
1607 }
1608
1609 HTEST(mpTex->UnlockRect(0));
1610
1611 return hr;
1612}
1613
1614HRESULT D3D9RenderTextureToScreen::DoRender(D3D9DeviceProvider *pDP)
1615{
1616 HRESULT hr = S_OK;
1617
1618 IDirect3DDevice9 *pDevice = pDP->Device(0);
1619
1620 HTEST(pDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff7f7f7f, 1.0f, 0));
1621
1622 HTEST(pDevice->BeginScene());
1623
1624 HTEST(pDevice->SetStreamSource(0, mpVB, 0, sizeof(Vertex)));
1625 HTEST(pDevice->SetVertexDeclaration(mpVertexDecl));
1626 HTEST(pDevice->SetVertexShader(mpVS));
1627 HTEST(pDevice->SetPixelShader(mpPS));
1628 HTEST(pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE));
1629 HTEST(pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE));
1630
1631 HTEST(pDevice->SetTexture(0, mpTex));
1632 HTEST(pDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR));
1633 HTEST(pDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR));
1634 HTEST(pDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR));
1635
1636 HTEST(pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2));
1637
1638 HTEST(pDevice->EndScene());
1639
1640 HTEST(pDevice->Present(0, 0, 0, 0));
1641
1642 return S_OK;
1643}
1644
1645
1646/*
1647 * "Public" interface.
1648 */
1649
1650D3D9Render *CreateRender(int iRenderId)
1651{
1652 switch (iRenderId)
1653 {
1654 case 11:
1655 return new D3D9RenderTextureToScreen(0.0f);
1656 case 10:
1657 return new D3D9RenderTextureToScreen(-0.5f);
1658 case 9:
1659 return new D3D9RenderTexture();
1660 case 8:
1661 return new D3D9RenderColorFill();
1662 case 7:
1663 return new D3D9RenderShared();
1664 case 6:
1665 return new D3D9RenderDepth();
1666 case 5:
1667 return new D3D9RenderInstance();
1668 case 4:
1669 return new D3D9RenderCubeMap();
1670 case 3:
1671 return new D3D9RenderTriangleShader();
1672 case 2:
1673 return new D3D9RenderTriangleFVF();
1674 case 1:
1675 return new D3D9RenderTriangle();
1676 case 0:
1677 return new D3D9RenderClear();
1678 default:
1679 break;
1680 }
1681 return 0;
1682}
1683
1684void DeleteRender(D3D9Render *pRender)
1685{
1686 delete pRender;
1687}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use