blob: 28f3fbffbbe2dca21b52fd0c4f3f7b12f99c5121 [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.comb8c28ed2010-04-13 03:26:32 +000045Blit::Blit(Context *context)
daniel@transgaming.com1ddd1dd2010-05-11 02:29:34 +000046 : mContext(context), 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
67void Blit::initGeometry()
68{
69 static const float quad[] =
70 {
71 -1, -1,
72 -1, 1,
73 1, -1,
74 1, 1
75 };
76
77 IDirect3DDevice9 *device = getDevice();
78
daniel@transgaming.comaa614602011-04-28 16:20:58 +000079 HRESULT result = device->CreateVertexBuffer(sizeof(quad), D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &mQuadVertexBuffer, NULL);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +000080
daniel@transgaming.comaa614602011-04-28 16:20:58 +000081 if (FAILED(result))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +000082 {
daniel@transgaming.comaa614602011-04-28 16:20:58 +000083 ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +000084 return error(GL_OUT_OF_MEMORY);
85 }
86
daniel@transgaming.comaa614602011-04-28 16:20:58 +000087 void *lockPtr = NULL;
88 result = mQuadVertexBuffer->Lock(0, 0, &lockPtr, 0);
89
90 if (FAILED(result) || lockPtr == NULL)
91 {
92 ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
93 return error(GL_OUT_OF_MEMORY);
94 }
95
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +000096 memcpy(lockPtr, quad, sizeof(quad));
97 mQuadVertexBuffer->Unlock();
98
99 static const D3DVERTEXELEMENT9 elements[] =
100 {
101 { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
102 D3DDECL_END()
103 };
104
daniel@transgaming.comaa614602011-04-28 16:20:58 +0000105 result = device->CreateVertexDeclaration(elements, &mQuadVertexDeclaration);
106
107 if (FAILED(result))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000108 {
daniel@transgaming.comaa614602011-04-28 16:20:58 +0000109 ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000110 return error(GL_OUT_OF_MEMORY);
111 }
112}
113
114template <class D3DShaderType>
115bool Blit::setShader(ShaderId source, const char *profile,
apatrick@chromium.org3cfd7222012-07-13 22:36:58 +0000116 D3DShaderType *(egl::Display::*createShader)(const DWORD *, size_t length),
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000117 HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType*))
118{
apatrick@chromium.org3cfd7222012-07-13 22:36:58 +0000119 egl::Display *display = getDisplay();
120 IDirect3DDevice9 *device = display->getDevice();
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
apatrick@chromium.org99fbbe82012-07-19 19:11:24 +0000133 shader = (display->*createShader)(reinterpret_cast<const DWORD*>(shaderCode), shaderSize);
134 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{
apatrick@chromium.org99fbbe82012-07-19 19:11:24 +0000156 return setShader<IDirect3DVertexShader9>(shader, "vs_2_0", &egl::Display::createVertexShader, &IDirect3DDevice9::SetVertexShader);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000157}
158
159bool Blit::setPixelShader(ShaderId shader)
160{
apatrick@chromium.org99fbbe82012-07-19 19:11:24 +0000161 return setShader<IDirect3DPixelShader9>(shader, "ps_2_0", &egl::Display::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
186 IDirect3DDevice9 *device = getDevice();
daniel@transgaming.com1ddd1dd2010-05-11 02:29:34 +0000187
188 saveState();
189
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +0000190 device->SetTexture(0, texture);
191 device->SetRenderTarget(0, dest);
192
193 setVertexShader(SHADER_VS_STANDARD);
194 setPixelShader(SHADER_PS_PASSTHROUGH);
195
196 setCommonBlitState();
197 device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
198 device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
199
200 setViewport(getSurfaceRect(dest), 0, 0);
201
202 render();
203
204 texture->Release();
205
daniel@transgaming.com1ddd1dd2010-05-11 02:29:34 +0000206 restoreState();
207
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +0000208 return true;
209}
210
daniel@transgaming.comeef864a2011-04-22 11:33:27 +0000211bool Blit::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest)
212{
213 IDirect3DDevice9 *device = getDevice();
214
215 D3DSURFACE_DESC sourceDesc;
216 D3DSURFACE_DESC destDesc;
217 source->GetDesc(&sourceDesc);
218 dest->GetDesc(&destDesc);
219
daniel@transgaming.comad52cb12012-10-17 18:14:45 +0000220 if (sourceDesc.Format == destDesc.Format && destDesc.Usage & D3DUSAGE_RENDERTARGET &&
221 dx2es::IsFormatChannelEquivalent(destDesc.Format, destFormat)) // Can use StretchRect
daniel@transgaming.comeef864a2011-04-22 11:33:27 +0000222 {
223 RECT destRect = {xoffset, yoffset, xoffset + (sourceRect.right - sourceRect.left), yoffset + (sourceRect.bottom - sourceRect.top)};
224 HRESULT result = device->StretchRect(source, &sourceRect, dest, &destRect, D3DTEXF_POINT);
225
226 if (FAILED(result))
227 {
228 ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
229 return error(GL_OUT_OF_MEMORY, false);
230 }
231 }
232 else
233 {
234 return formatConvert(source, sourceRect, destFormat, xoffset, yoffset, dest);
235 }
236
237 return true;
238}
239
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000240bool Blit::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest)
241{
242 IDirect3DTexture9 *texture = copySurfaceToTexture(source, sourceRect);
243 if (!texture)
244 {
245 return false;
246 }
247
248 IDirect3DDevice9 *device = getDevice();
249
daniel@transgaming.com1ddd1dd2010-05-11 02:29:34 +0000250 saveState();
251
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000252 device->SetTexture(0, texture);
253 device->SetRenderTarget(0, dest);
254
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +0000255 setViewport(sourceRect, xoffset, yoffset);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000256
257 setCommonBlitState();
258 if (setFormatConvertShaders(destFormat))
259 {
260 render();
261 }
262
263 texture->Release();
264
daniel@transgaming.com1ddd1dd2010-05-11 02:29:34 +0000265 restoreState();
266
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000267 return true;
268}
269
270bool Blit::setFormatConvertShaders(GLenum destFormat)
271{
272 bool okay = setVertexShader(SHADER_VS_STANDARD);
273
274 switch (destFormat)
275 {
276 default: UNREACHABLE();
277 case GL_RGBA:
daniel@transgaming.coma9198d92010-08-08 04:49:56 +0000278 case GL_BGRA_EXT:
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000279 case GL_RGB:
280 case GL_ALPHA:
281 okay = okay && setPixelShader(SHADER_PS_COMPONENTMASK);
282 break;
283
284 case GL_LUMINANCE:
285 case GL_LUMINANCE_ALPHA:
286 okay = okay && setPixelShader(SHADER_PS_LUMINANCE);
287 break;
288 }
289
290 if (!okay)
291 {
292 return false;
293 }
294
295 enum { X = 0, Y = 1, Z = 2, W = 3 };
296
297 // The meaning of this constant depends on the shader that was selected.
298 // See the shader assembly code above for details.
299 float psConst0[4] = { 0, 0, 0, 0 };
300
301 switch (destFormat)
302 {
303 default: UNREACHABLE();
304 case GL_RGBA:
daniel@transgaming.coma9198d92010-08-08 04:49:56 +0000305 case GL_BGRA_EXT:
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000306 psConst0[X] = 1;
307 psConst0[Z] = 1;
308 break;
309
310 case GL_RGB:
311 psConst0[X] = 1;
312 psConst0[W] = 1;
313 break;
314
315 case GL_ALPHA:
316 psConst0[Z] = 1;
317 break;
318
319 case GL_LUMINANCE:
320 psConst0[Y] = 1;
321 break;
322
323 case GL_LUMINANCE_ALPHA:
324 psConst0[X] = 1;
325 break;
326 }
327
328 getDevice()->SetPixelShaderConstantF(0, psConst0, 1);
329
330 return true;
331}
332
333IDirect3DTexture9 *Blit::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect)
334{
daniel@transgaming.comd36c6a02010-08-31 12:15:09 +0000335 if (!surface)
336 {
337 return NULL;
338 }
339
daniel@transgaming.comae072af2010-05-05 18:47:28 +0000340 egl::Display *display = getDisplay();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000341 IDirect3DDevice9 *device = getDevice();
342
343 D3DSURFACE_DESC sourceDesc;
344 surface->GetDesc(&sourceDesc);
345
346 // Copy the render target into a texture
347 IDirect3DTexture9 *texture;
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +0000348 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 +0000349
350 if (FAILED(result))
351 {
352 ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
353 return error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
354 }
355
356 IDirect3DSurface9 *textureSurface;
357 result = texture->GetSurfaceLevel(0, &textureSurface);
358
359 if (FAILED(result))
360 {
361 ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
362 texture->Release();
363 return error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
364 }
365
daniel@transgaming.comae072af2010-05-05 18:47:28 +0000366 display->endScene();
daniel@transgaming.com4c5142c2010-10-15 17:58:27 +0000367 result = device->StretchRect(surface, &sourceRect, textureSurface, NULL, D3DTEXF_NONE);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000368
369 textureSurface->Release();
370
371 if (FAILED(result))
372 {
373 ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
374 texture->Release();
375 return error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
376 }
377
378 return texture;
379}
380
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +0000381void Blit::setViewport(const RECT &sourceRect, GLint xoffset, GLint yoffset)
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000382{
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000383 IDirect3DDevice9 *device = getDevice();
384
385 D3DVIEWPORT9 vp;
386 vp.X = xoffset;
387 vp.Y = yoffset;
388 vp.Width = sourceRect.right - sourceRect.left;
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +0000389 vp.Height = sourceRect.bottom - sourceRect.top;
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000390 vp.MinZ = 0.0f;
391 vp.MaxZ = 1.0f;
392 device->SetViewport(&vp);
393
394 float halfPixelAdjust[4] = { -1.0f/vp.Width, 1.0f/vp.Height, 0, 0 };
395 device->SetVertexShaderConstantF(0, halfPixelAdjust, 1);
396}
397
398void Blit::setCommonBlitState()
399{
400 IDirect3DDevice9 *device = getDevice();
401
402 device->SetDepthStencilSurface(NULL);
403
404 device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
405 device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
406 device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
407 device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
408 device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
409 device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED);
410 device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE);
411 device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
412
413 device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
414 device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
415 device->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, FALSE);
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +0000416 device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
417 device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
daniel@transgaming.com81655a72010-05-20 19:18:17 +0000418
daniel@transgaming.com74d760b2010-11-03 12:27:18 +0000419 RECT scissorRect = {0}; // Scissoring is disabled for flipping, but we need this to capture and restore the old rectangle
420 device->SetScissorRect(&scissorRect);
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +0000421
422 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
423 {
424 device->SetStreamSourceFreq(i, 1);
425 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000426}
427
428void Blit::render()
429{
daniel@transgaming.comae072af2010-05-05 18:47:28 +0000430 egl::Display *display = getDisplay();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000431 IDirect3DDevice9 *device = getDevice();
432
433 HRESULT hr = device->SetStreamSource(0, mQuadVertexBuffer, 0, 2 * sizeof(float));
434 hr = device->SetVertexDeclaration(mQuadVertexDeclaration);
435
daniel@transgaming.comae072af2010-05-05 18:47:28 +0000436 display->startScene();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000437 hr = device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000438}
439
daniel@transgaming.com1ddd1dd2010-05-11 02:29:34 +0000440void Blit::saveState()
441{
442 IDirect3DDevice9 *device = getDevice();
443
444 HRESULT hr;
445
446 device->GetDepthStencilSurface(&mSavedDepthStencil);
447 device->GetRenderTarget(0, &mSavedRenderTarget);
448
449 if (mSavedStateBlock == NULL)
450 {
451 hr = device->BeginStateBlock();
452 ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
453
454 setCommonBlitState();
455
456 static const float dummyConst[4] = { 0, 0, 0, 0 };
457
458 device->SetVertexShader(NULL);
459 device->SetVertexShaderConstantF(0, dummyConst, 1);
460 device->SetPixelShader(NULL);
461 device->SetPixelShaderConstantF(0, dummyConst, 1);
462
463 D3DVIEWPORT9 dummyVp;
464 dummyVp.X = 0;
465 dummyVp.Y = 0;
466 dummyVp.Width = 1;
467 dummyVp.Height = 1;
468 dummyVp.MinZ = 0;
469 dummyVp.MaxZ = 1;
470
471 device->SetViewport(&dummyVp);
472
473 device->SetTexture(0, NULL);
474
475 device->SetStreamSource(0, mQuadVertexBuffer, 0, 0);
476
477 device->SetVertexDeclaration(mQuadVertexDeclaration);
478
479 hr = device->EndStateBlock(&mSavedStateBlock);
480 ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
481 }
482
483 ASSERT(mSavedStateBlock != NULL);
484
485 if (mSavedStateBlock != NULL)
486 {
487 hr = mSavedStateBlock->Capture();
488 ASSERT(SUCCEEDED(hr));
489 }
490}
491
492void Blit::restoreState()
493{
494 IDirect3DDevice9 *device = getDevice();
495
496 device->SetDepthStencilSurface(mSavedDepthStencil);
497 if (mSavedDepthStencil != NULL)
498 {
499 mSavedDepthStencil->Release();
500 mSavedDepthStencil = NULL;
501 }
502
503 device->SetRenderTarget(0, mSavedRenderTarget);
504 if (mSavedRenderTarget != NULL)
505 {
506 mSavedRenderTarget->Release();
507 mSavedRenderTarget = NULL;
508 }
509
510 ASSERT(mSavedStateBlock != NULL);
511
512 if (mSavedStateBlock != NULL)
513 {
514 mSavedStateBlock->Apply();
515 }
516}
517
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000518}