blob: 7b4c68fe94373024b3b7591adc3f5ade8f924ed5 [file] [log] [blame]
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001//
2// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Blit.cpp: Surface copy utility class.
8
daniel@transgaming.combbf56f72010-04-20 18:52:13 +00009#include "libGLESv2/Blit.h"
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +000010
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +000011#include "common/debug.h"
12
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000013#include "libGLESv2/main.h"
daniel@transgaming.comad52cb12012-10-17 18:14:45 +000014#include "libGLESv2/utilities.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000015
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +000016namespace
17{
apatrick@chromium.org99fbbe82012-07-19 19:11:24 +000018#include "libGLESv2/shaders/standardvs.h"
19#include "libGLESv2/shaders/flipyvs.h"
20#include "libGLESv2/shaders/passthroughps.h"
21#include "libGLESv2/shaders/luminanceps.h"
22#include "libGLESv2/shaders/componentmaskps.h"
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +000023
apatrick@chromium.org99fbbe82012-07-19 19:11:24 +000024const BYTE* const g_shaderCode[] =
25{
26 g_vs20_standardvs,
27 g_vs20_flipyvs,
28 g_ps20_passthroughps,
29 g_ps20_luminanceps,
30 g_ps20_componentmaskps
31};
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +000032
apatrick@chromium.org99fbbe82012-07-19 19:11:24 +000033const size_t g_shaderSize[] =
34{
35 sizeof(g_vs20_standardvs),
36 sizeof(g_vs20_flipyvs),
37 sizeof(g_ps20_passthroughps),
38 sizeof(g_ps20_luminanceps),
39 sizeof(g_ps20_componentmaskps)
40};
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +000041}
42
43namespace gl
44{
daniel@transgaming.com2507f412012-10-31 18:46:48 +000045Blit::Blit(renderer::Renderer9 *renderer)
daniel@transgaming.come4733d72012-10-31 18:07:01 +000046 : mRenderer(renderer), mQuadVertexBuffer(NULL), mQuadVertexDeclaration(NULL), mSavedRenderTarget(NULL), mSavedDepthStencil(NULL), mSavedStateBlock(NULL)
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +000047{
48 initGeometry();
49 memset(mCompiledShaders, 0, sizeof(mCompiledShaders));
50}
51
52Blit::~Blit()
53{
daniel@transgaming.com1ddd1dd2010-05-11 02:29:34 +000054 if (mSavedStateBlock) mSavedStateBlock->Release();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +000055 if (mQuadVertexBuffer) mQuadVertexBuffer->Release();
56 if (mQuadVertexDeclaration) mQuadVertexDeclaration->Release();
57
58 for (int i = 0; i < SHADER_COUNT; i++)
59 {
60 if (mCompiledShaders[i])
61 {
62 mCompiledShaders[i]->Release();
63 }
64 }
65}
66
daniel@transgaming.com621ce052012-10-31 17:52:29 +000067// D3D9_REPLACE
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +000068void Blit::initGeometry()
69{
70 static const float quad[] =
71 {
72 -1, -1,
73 -1, 1,
74 1, -1,
75 1, 1
76 };
77
daniel@transgaming.come4733d72012-10-31 18:07:01 +000078 IDirect3DDevice9 *device = mRenderer->getDevice();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +000079
daniel@transgaming.comaa614602011-04-28 16:20:58 +000080 HRESULT result = device->CreateVertexBuffer(sizeof(quad), D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &mQuadVertexBuffer, NULL);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +000081
daniel@transgaming.comaa614602011-04-28 16:20:58 +000082 if (FAILED(result))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +000083 {
daniel@transgaming.comaa614602011-04-28 16:20:58 +000084 ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +000085 return error(GL_OUT_OF_MEMORY);
86 }
87
daniel@transgaming.comaa614602011-04-28 16:20:58 +000088 void *lockPtr = NULL;
89 result = mQuadVertexBuffer->Lock(0, 0, &lockPtr, 0);
90
91 if (FAILED(result) || lockPtr == NULL)
92 {
93 ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
94 return error(GL_OUT_OF_MEMORY);
95 }
96
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +000097 memcpy(lockPtr, quad, sizeof(quad));
98 mQuadVertexBuffer->Unlock();
99
100 static const D3DVERTEXELEMENT9 elements[] =
101 {
102 { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
103 D3DDECL_END()
104 };
105
daniel@transgaming.comaa614602011-04-28 16:20:58 +0000106 result = device->CreateVertexDeclaration(elements, &mQuadVertexDeclaration);
107
108 if (FAILED(result))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000109 {
daniel@transgaming.comaa614602011-04-28 16:20:58 +0000110 ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000111 return error(GL_OUT_OF_MEMORY);
112 }
113}
114
115template <class D3DShaderType>
116bool Blit::setShader(ShaderId source, const char *profile,
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000117 D3DShaderType *(renderer::Renderer9::*createShader)(const DWORD *, size_t length),
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000118 HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType*))
119{
daniel@transgaming.come4733d72012-10-31 18:07:01 +0000120 IDirect3DDevice9 *device = mRenderer->getDevice(); // D3D9_REPLACE
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000121
122 D3DShaderType *shader;
123
124 if (mCompiledShaders[source] != NULL)
125 {
126 shader = static_cast<D3DShaderType*>(mCompiledShaders[source]);
127 }
128 else
129 {
apatrick@chromium.org99fbbe82012-07-19 19:11:24 +0000130 const BYTE* shaderCode = g_shaderCode[source];
131 size_t shaderSize = g_shaderSize[source];
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000132
daniel@transgaming.come4733d72012-10-31 18:07:01 +0000133 shader = (mRenderer->*createShader)(reinterpret_cast<const DWORD*>(shaderCode), shaderSize);
apatrick@chromium.org99fbbe82012-07-19 19:11:24 +0000134 if (!shader)
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000135 {
apatrick@chromium.org99fbbe82012-07-19 19:11:24 +0000136 ERR("Failed to create shader for blit operation");
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000137 return false;
138 }
139
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000140 mCompiledShaders[source] = shader;
141 }
142
143 HRESULT hr = (device->*setShader)(shader);
144
145 if (FAILED(hr))
146 {
apatrick@chromium.org99fbbe82012-07-19 19:11:24 +0000147 ERR("Failed to set shader for blit operation");
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000148 return false;
149 }
150
151 return true;
152}
153
154bool Blit::setVertexShader(ShaderId shader)
155{
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000156 return setShader<IDirect3DVertexShader9>(shader, "vs_2_0", &renderer::Renderer9::createVertexShader, &IDirect3DDevice9::SetVertexShader);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000157}
158
159bool Blit::setPixelShader(ShaderId shader)
160{
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000161 return setShader<IDirect3DPixelShader9>(shader, "ps_2_0", &renderer::Renderer9::createPixelShader, &IDirect3DDevice9::SetPixelShader);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000162}
163
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +0000164RECT Blit::getSurfaceRect(IDirect3DSurface9 *surface) const
165{
166 D3DSURFACE_DESC desc;
167 surface->GetDesc(&desc);
168
169 RECT rect;
170 rect.left = 0;
171 rect.top = 0;
172 rect.right = desc.Width;
173 rect.bottom = desc.Height;
174
175 return rect;
176}
177
178bool Blit::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest)
179{
180 IDirect3DTexture9 *texture = copySurfaceToTexture(source, getSurfaceRect(source));
181 if (!texture)
182 {
183 return false;
184 }
185
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000186 // D3D9_REPLACE
daniel@transgaming.come4733d72012-10-31 18:07:01 +0000187 IDirect3DDevice9 *device = mRenderer->getDevice();
daniel@transgaming.com1ddd1dd2010-05-11 02:29:34 +0000188
189 saveState();
190
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +0000191 device->SetTexture(0, texture);
192 device->SetRenderTarget(0, dest);
193
194 setVertexShader(SHADER_VS_STANDARD);
195 setPixelShader(SHADER_PS_PASSTHROUGH);
196
197 setCommonBlitState();
198 device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
199 device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
200
201 setViewport(getSurfaceRect(dest), 0, 0);
202
203 render();
204
205 texture->Release();
206
daniel@transgaming.com1ddd1dd2010-05-11 02:29:34 +0000207 restoreState();
208
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +0000209 return true;
210}
211
daniel@transgaming.comeef864a2011-04-22 11:33:27 +0000212bool Blit::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest)
213{
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000214 // D3D9_REPLACE
daniel@transgaming.come4733d72012-10-31 18:07:01 +0000215 IDirect3DDevice9 *device = mRenderer->getDevice();
daniel@transgaming.comeef864a2011-04-22 11:33:27 +0000216
217 D3DSURFACE_DESC sourceDesc;
218 D3DSURFACE_DESC destDesc;
219 source->GetDesc(&sourceDesc);
220 dest->GetDesc(&destDesc);
221
daniel@transgaming.comad52cb12012-10-17 18:14:45 +0000222 if (sourceDesc.Format == destDesc.Format && destDesc.Usage & D3DUSAGE_RENDERTARGET &&
223 dx2es::IsFormatChannelEquivalent(destDesc.Format, destFormat)) // Can use StretchRect
daniel@transgaming.comeef864a2011-04-22 11:33:27 +0000224 {
225 RECT destRect = {xoffset, yoffset, xoffset + (sourceRect.right - sourceRect.left), yoffset + (sourceRect.bottom - sourceRect.top)};
226 HRESULT result = device->StretchRect(source, &sourceRect, dest, &destRect, D3DTEXF_POINT);
227
228 if (FAILED(result))
229 {
230 ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
231 return error(GL_OUT_OF_MEMORY, false);
232 }
233 }
234 else
235 {
236 return formatConvert(source, sourceRect, destFormat, xoffset, yoffset, dest);
237 }
238
239 return true;
240}
241
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000242bool Blit::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest)
243{
244 IDirect3DTexture9 *texture = copySurfaceToTexture(source, sourceRect);
245 if (!texture)
246 {
247 return false;
248 }
249
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000250 // D3D9_REPLACE
daniel@transgaming.come4733d72012-10-31 18:07:01 +0000251 IDirect3DDevice9 *device = mRenderer->getDevice();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000252
daniel@transgaming.com1ddd1dd2010-05-11 02:29:34 +0000253 saveState();
254
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000255 device->SetTexture(0, texture);
256 device->SetRenderTarget(0, dest);
257
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +0000258 setViewport(sourceRect, xoffset, yoffset);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000259
260 setCommonBlitState();
261 if (setFormatConvertShaders(destFormat))
262 {
263 render();
264 }
265
266 texture->Release();
267
daniel@transgaming.com1ddd1dd2010-05-11 02:29:34 +0000268 restoreState();
269
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000270 return true;
271}
272
273bool Blit::setFormatConvertShaders(GLenum destFormat)
274{
275 bool okay = setVertexShader(SHADER_VS_STANDARD);
276
277 switch (destFormat)
278 {
279 default: UNREACHABLE();
280 case GL_RGBA:
daniel@transgaming.coma9198d92010-08-08 04:49:56 +0000281 case GL_BGRA_EXT:
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000282 case GL_RGB:
283 case GL_ALPHA:
284 okay = okay && setPixelShader(SHADER_PS_COMPONENTMASK);
285 break;
286
287 case GL_LUMINANCE:
288 case GL_LUMINANCE_ALPHA:
289 okay = okay && setPixelShader(SHADER_PS_LUMINANCE);
290 break;
291 }
292
293 if (!okay)
294 {
295 return false;
296 }
297
298 enum { X = 0, Y = 1, Z = 2, W = 3 };
299
300 // The meaning of this constant depends on the shader that was selected.
301 // See the shader assembly code above for details.
302 float psConst0[4] = { 0, 0, 0, 0 };
303
304 switch (destFormat)
305 {
306 default: UNREACHABLE();
307 case GL_RGBA:
daniel@transgaming.coma9198d92010-08-08 04:49:56 +0000308 case GL_BGRA_EXT:
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000309 psConst0[X] = 1;
310 psConst0[Z] = 1;
311 break;
312
313 case GL_RGB:
314 psConst0[X] = 1;
315 psConst0[W] = 1;
316 break;
317
318 case GL_ALPHA:
319 psConst0[Z] = 1;
320 break;
321
322 case GL_LUMINANCE:
323 psConst0[Y] = 1;
324 break;
325
326 case GL_LUMINANCE_ALPHA:
327 psConst0[X] = 1;
328 break;
329 }
330
daniel@transgaming.come4733d72012-10-31 18:07:01 +0000331 mRenderer->getDevice()->SetPixelShaderConstantF(0, psConst0, 1); // D3D9_REPLACE
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000332
333 return true;
334}
335
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000336// D3D9_REPLACE
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000337IDirect3DTexture9 *Blit::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect)
338{
daniel@transgaming.comd36c6a02010-08-31 12:15:09 +0000339 if (!surface)
340 {
341 return NULL;
342 }
343
daniel@transgaming.come4733d72012-10-31 18:07:01 +0000344 IDirect3DDevice9 *device = mRenderer->getDevice(); // D3D9_REPLACE
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000345
346 D3DSURFACE_DESC sourceDesc;
347 surface->GetDesc(&sourceDesc);
348
349 // Copy the render target into a texture
350 IDirect3DTexture9 *texture;
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +0000351 HRESULT result = device->CreateTexture(sourceRect.right - sourceRect.left, sourceRect.bottom - sourceRect.top, 1, D3DUSAGE_RENDERTARGET, sourceDesc.Format, D3DPOOL_DEFAULT, &texture, NULL);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000352
353 if (FAILED(result))
354 {
355 ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
356 return error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
357 }
358
359 IDirect3DSurface9 *textureSurface;
360 result = texture->GetSurfaceLevel(0, &textureSurface);
361
362 if (FAILED(result))
363 {
364 ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
365 texture->Release();
366 return error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
367 }
368
daniel@transgaming.come4733d72012-10-31 18:07:01 +0000369 mRenderer->endScene();
daniel@transgaming.com4c5142c2010-10-15 17:58:27 +0000370 result = device->StretchRect(surface, &sourceRect, textureSurface, NULL, D3DTEXF_NONE);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000371
372 textureSurface->Release();
373
374 if (FAILED(result))
375 {
376 ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
377 texture->Release();
378 return error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
379 }
380
381 return texture;
382}
383
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +0000384void Blit::setViewport(const RECT &sourceRect, GLint xoffset, GLint yoffset)
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000385{
daniel@transgaming.come4733d72012-10-31 18:07:01 +0000386 IDirect3DDevice9 *device = mRenderer->getDevice(); // D3D9_REPLACE
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000387
388 D3DVIEWPORT9 vp;
389 vp.X = xoffset;
390 vp.Y = yoffset;
391 vp.Width = sourceRect.right - sourceRect.left;
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +0000392 vp.Height = sourceRect.bottom - sourceRect.top;
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000393 vp.MinZ = 0.0f;
394 vp.MaxZ = 1.0f;
395 device->SetViewport(&vp);
396
397 float halfPixelAdjust[4] = { -1.0f/vp.Width, 1.0f/vp.Height, 0, 0 };
398 device->SetVertexShaderConstantF(0, halfPixelAdjust, 1);
399}
400
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000401// D3D9_REPLACE
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000402void Blit::setCommonBlitState()
403{
daniel@transgaming.come4733d72012-10-31 18:07:01 +0000404 IDirect3DDevice9 *device = mRenderer->getDevice();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000405
406 device->SetDepthStencilSurface(NULL);
407
408 device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
409 device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
410 device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
411 device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
412 device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
413 device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED);
414 device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE);
415 device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
416
417 device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
418 device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
419 device->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, FALSE);
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +0000420 device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
421 device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
daniel@transgaming.com81655a72010-05-20 19:18:17 +0000422
daniel@transgaming.com74d760b2010-11-03 12:27:18 +0000423 RECT scissorRect = {0}; // Scissoring is disabled for flipping, but we need this to capture and restore the old rectangle
424 device->SetScissorRect(&scissorRect);
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +0000425
426 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
427 {
428 device->SetStreamSourceFreq(i, 1);
429 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000430}
431
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000432// D3D9_REPLACE
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000433void Blit::render()
434{
daniel@transgaming.come4733d72012-10-31 18:07:01 +0000435 IDirect3DDevice9 *device = mRenderer->getDevice();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000436
437 HRESULT hr = device->SetStreamSource(0, mQuadVertexBuffer, 0, 2 * sizeof(float));
438 hr = device->SetVertexDeclaration(mQuadVertexDeclaration);
439
daniel@transgaming.come4733d72012-10-31 18:07:01 +0000440 mRenderer->startScene();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000441 hr = device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000442}
443
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000444// D3D9_REPLACE
daniel@transgaming.com1ddd1dd2010-05-11 02:29:34 +0000445void Blit::saveState()
446{
daniel@transgaming.come4733d72012-10-31 18:07:01 +0000447 IDirect3DDevice9 *device = mRenderer->getDevice();
daniel@transgaming.com1ddd1dd2010-05-11 02:29:34 +0000448
449 HRESULT hr;
450
451 device->GetDepthStencilSurface(&mSavedDepthStencil);
452 device->GetRenderTarget(0, &mSavedRenderTarget);
453
454 if (mSavedStateBlock == NULL)
455 {
456 hr = device->BeginStateBlock();
457 ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
458
459 setCommonBlitState();
460
461 static const float dummyConst[4] = { 0, 0, 0, 0 };
462
463 device->SetVertexShader(NULL);
464 device->SetVertexShaderConstantF(0, dummyConst, 1);
465 device->SetPixelShader(NULL);
466 device->SetPixelShaderConstantF(0, dummyConst, 1);
467
468 D3DVIEWPORT9 dummyVp;
469 dummyVp.X = 0;
470 dummyVp.Y = 0;
471 dummyVp.Width = 1;
472 dummyVp.Height = 1;
473 dummyVp.MinZ = 0;
474 dummyVp.MaxZ = 1;
475
476 device->SetViewport(&dummyVp);
477
478 device->SetTexture(0, NULL);
479
480 device->SetStreamSource(0, mQuadVertexBuffer, 0, 0);
481
482 device->SetVertexDeclaration(mQuadVertexDeclaration);
483
484 hr = device->EndStateBlock(&mSavedStateBlock);
485 ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
486 }
487
488 ASSERT(mSavedStateBlock != NULL);
489
490 if (mSavedStateBlock != NULL)
491 {
492 hr = mSavedStateBlock->Capture();
493 ASSERT(SUCCEEDED(hr));
494 }
495}
496
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000497// D3D9_REPLACE
daniel@transgaming.com1ddd1dd2010-05-11 02:29:34 +0000498void Blit::restoreState()
499{
daniel@transgaming.come4733d72012-10-31 18:07:01 +0000500 IDirect3DDevice9 *device = mRenderer->getDevice();
daniel@transgaming.com1ddd1dd2010-05-11 02:29:34 +0000501
502 device->SetDepthStencilSurface(mSavedDepthStencil);
503 if (mSavedDepthStencil != NULL)
504 {
505 mSavedDepthStencil->Release();
506 mSavedDepthStencil = NULL;
507 }
508
509 device->SetRenderTarget(0, mSavedRenderTarget);
510 if (mSavedRenderTarget != NULL)
511 {
512 mSavedRenderTarget->Release();
513 mSavedRenderTarget = NULL;
514 }
515
516 ASSERT(mSavedStateBlock != NULL);
517
518 if (mSavedStateBlock != NULL)
519 {
520 mSavedStateBlock->Apply();
521 }
522}
523
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000524}