blob: 60af1260b95a660855c1885271bb5cb1b73fff24 [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
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
78 IDirect3DDevice9 *device = getDevice();
79
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,
apatrick@chromium.org3cfd7222012-07-13 22:36:58 +0000117 D3DShaderType *(egl::Display::*createShader)(const DWORD *, size_t length),
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000118 HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType*))
119{
apatrick@chromium.org3cfd7222012-07-13 22:36:58 +0000120 egl::Display *display = getDisplay();
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000121 IDirect3DDevice9 *device = display->getRenderer()->getDevice(); // D3D9_REPLACE
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000122
123 D3DShaderType *shader;
124
125 if (mCompiledShaders[source] != NULL)
126 {
127 shader = static_cast<D3DShaderType*>(mCompiledShaders[source]);
128 }
129 else
130 {
apatrick@chromium.org99fbbe82012-07-19 19:11:24 +0000131 const BYTE* shaderCode = g_shaderCode[source];
132 size_t shaderSize = g_shaderSize[source];
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000133
apatrick@chromium.org99fbbe82012-07-19 19:11:24 +0000134 shader = (display->*createShader)(reinterpret_cast<const DWORD*>(shaderCode), shaderSize);
135 if (!shader)
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000136 {
apatrick@chromium.org99fbbe82012-07-19 19:11:24 +0000137 ERR("Failed to create shader for blit operation");
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000138 return false;
139 }
140
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000141 mCompiledShaders[source] = shader;
142 }
143
144 HRESULT hr = (device->*setShader)(shader);
145
146 if (FAILED(hr))
147 {
apatrick@chromium.org99fbbe82012-07-19 19:11:24 +0000148 ERR("Failed to set shader for blit operation");
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000149 return false;
150 }
151
152 return true;
153}
154
155bool Blit::setVertexShader(ShaderId shader)
156{
apatrick@chromium.org99fbbe82012-07-19 19:11:24 +0000157 return setShader<IDirect3DVertexShader9>(shader, "vs_2_0", &egl::Display::createVertexShader, &IDirect3DDevice9::SetVertexShader);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000158}
159
160bool Blit::setPixelShader(ShaderId shader)
161{
apatrick@chromium.org99fbbe82012-07-19 19:11:24 +0000162 return setShader<IDirect3DPixelShader9>(shader, "ps_2_0", &egl::Display::createPixelShader, &IDirect3DDevice9::SetPixelShader);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000163}
164
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +0000165RECT Blit::getSurfaceRect(IDirect3DSurface9 *surface) const
166{
167 D3DSURFACE_DESC desc;
168 surface->GetDesc(&desc);
169
170 RECT rect;
171 rect.left = 0;
172 rect.top = 0;
173 rect.right = desc.Width;
174 rect.bottom = desc.Height;
175
176 return rect;
177}
178
179bool Blit::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest)
180{
181 IDirect3DTexture9 *texture = copySurfaceToTexture(source, getSurfaceRect(source));
182 if (!texture)
183 {
184 return false;
185 }
186
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000187 // D3D9_REPLACE
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +0000188 IDirect3DDevice9 *device = getDevice();
daniel@transgaming.com1ddd1dd2010-05-11 02:29:34 +0000189
190 saveState();
191
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +0000192 device->SetTexture(0, texture);
193 device->SetRenderTarget(0, dest);
194
195 setVertexShader(SHADER_VS_STANDARD);
196 setPixelShader(SHADER_PS_PASSTHROUGH);
197
198 setCommonBlitState();
199 device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
200 device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
201
202 setViewport(getSurfaceRect(dest), 0, 0);
203
204 render();
205
206 texture->Release();
207
daniel@transgaming.com1ddd1dd2010-05-11 02:29:34 +0000208 restoreState();
209
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +0000210 return true;
211}
212
daniel@transgaming.comeef864a2011-04-22 11:33:27 +0000213bool Blit::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest)
214{
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000215 // D3D9_REPLACE
daniel@transgaming.comeef864a2011-04-22 11:33:27 +0000216 IDirect3DDevice9 *device = getDevice();
217
218 D3DSURFACE_DESC sourceDesc;
219 D3DSURFACE_DESC destDesc;
220 source->GetDesc(&sourceDesc);
221 dest->GetDesc(&destDesc);
222
daniel@transgaming.comad52cb12012-10-17 18:14:45 +0000223 if (sourceDesc.Format == destDesc.Format && destDesc.Usage & D3DUSAGE_RENDERTARGET &&
224 dx2es::IsFormatChannelEquivalent(destDesc.Format, destFormat)) // Can use StretchRect
daniel@transgaming.comeef864a2011-04-22 11:33:27 +0000225 {
226 RECT destRect = {xoffset, yoffset, xoffset + (sourceRect.right - sourceRect.left), yoffset + (sourceRect.bottom - sourceRect.top)};
227 HRESULT result = device->StretchRect(source, &sourceRect, dest, &destRect, D3DTEXF_POINT);
228
229 if (FAILED(result))
230 {
231 ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
232 return error(GL_OUT_OF_MEMORY, false);
233 }
234 }
235 else
236 {
237 return formatConvert(source, sourceRect, destFormat, xoffset, yoffset, dest);
238 }
239
240 return true;
241}
242
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000243bool Blit::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest)
244{
245 IDirect3DTexture9 *texture = copySurfaceToTexture(source, sourceRect);
246 if (!texture)
247 {
248 return false;
249 }
250
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000251 // D3D9_REPLACE
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000252 IDirect3DDevice9 *device = getDevice();
253
daniel@transgaming.com1ddd1dd2010-05-11 02:29:34 +0000254 saveState();
255
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000256 device->SetTexture(0, texture);
257 device->SetRenderTarget(0, dest);
258
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +0000259 setViewport(sourceRect, xoffset, yoffset);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000260
261 setCommonBlitState();
262 if (setFormatConvertShaders(destFormat))
263 {
264 render();
265 }
266
267 texture->Release();
268
daniel@transgaming.com1ddd1dd2010-05-11 02:29:34 +0000269 restoreState();
270
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000271 return true;
272}
273
274bool Blit::setFormatConvertShaders(GLenum destFormat)
275{
276 bool okay = setVertexShader(SHADER_VS_STANDARD);
277
278 switch (destFormat)
279 {
280 default: UNREACHABLE();
281 case GL_RGBA:
daniel@transgaming.coma9198d92010-08-08 04:49:56 +0000282 case GL_BGRA_EXT:
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000283 case GL_RGB:
284 case GL_ALPHA:
285 okay = okay && setPixelShader(SHADER_PS_COMPONENTMASK);
286 break;
287
288 case GL_LUMINANCE:
289 case GL_LUMINANCE_ALPHA:
290 okay = okay && setPixelShader(SHADER_PS_LUMINANCE);
291 break;
292 }
293
294 if (!okay)
295 {
296 return false;
297 }
298
299 enum { X = 0, Y = 1, Z = 2, W = 3 };
300
301 // The meaning of this constant depends on the shader that was selected.
302 // See the shader assembly code above for details.
303 float psConst0[4] = { 0, 0, 0, 0 };
304
305 switch (destFormat)
306 {
307 default: UNREACHABLE();
308 case GL_RGBA:
daniel@transgaming.coma9198d92010-08-08 04:49:56 +0000309 case GL_BGRA_EXT:
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000310 psConst0[X] = 1;
311 psConst0[Z] = 1;
312 break;
313
314 case GL_RGB:
315 psConst0[X] = 1;
316 psConst0[W] = 1;
317 break;
318
319 case GL_ALPHA:
320 psConst0[Z] = 1;
321 break;
322
323 case GL_LUMINANCE:
324 psConst0[Y] = 1;
325 break;
326
327 case GL_LUMINANCE_ALPHA:
328 psConst0[X] = 1;
329 break;
330 }
331
332 getDevice()->SetPixelShaderConstantF(0, psConst0, 1);
333
334 return true;
335}
336
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000337// D3D9_REPLACE
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000338IDirect3DTexture9 *Blit::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect)
339{
daniel@transgaming.comd36c6a02010-08-31 12:15:09 +0000340 if (!surface)
341 {
342 return NULL;
343 }
344
daniel@transgaming.comae072af2010-05-05 18:47:28 +0000345 egl::Display *display = getDisplay();
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000346 renderer::Renderer *renderer = display->getRenderer();
347 IDirect3DDevice9 *device = renderer->getDevice(); // D3D9_REPLACE
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000348
349 D3DSURFACE_DESC sourceDesc;
350 surface->GetDesc(&sourceDesc);
351
352 // Copy the render target into a texture
353 IDirect3DTexture9 *texture;
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +0000354 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 +0000355
356 if (FAILED(result))
357 {
358 ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
359 return error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
360 }
361
362 IDirect3DSurface9 *textureSurface;
363 result = texture->GetSurfaceLevel(0, &textureSurface);
364
365 if (FAILED(result))
366 {
367 ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
368 texture->Release();
369 return error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
370 }
371
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000372 renderer->endScene();
daniel@transgaming.com4c5142c2010-10-15 17:58:27 +0000373 result = device->StretchRect(surface, &sourceRect, textureSurface, NULL, D3DTEXF_NONE);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000374
375 textureSurface->Release();
376
377 if (FAILED(result))
378 {
379 ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
380 texture->Release();
381 return error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
382 }
383
384 return texture;
385}
386
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +0000387void Blit::setViewport(const RECT &sourceRect, GLint xoffset, GLint yoffset)
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000388{
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000389 IDirect3DDevice9 *device = getDevice(); // D3D9_REPLACE
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000390
391 D3DVIEWPORT9 vp;
392 vp.X = xoffset;
393 vp.Y = yoffset;
394 vp.Width = sourceRect.right - sourceRect.left;
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +0000395 vp.Height = sourceRect.bottom - sourceRect.top;
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000396 vp.MinZ = 0.0f;
397 vp.MaxZ = 1.0f;
398 device->SetViewport(&vp);
399
400 float halfPixelAdjust[4] = { -1.0f/vp.Width, 1.0f/vp.Height, 0, 0 };
401 device->SetVertexShaderConstantF(0, halfPixelAdjust, 1);
402}
403
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000404// D3D9_REPLACE
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000405void Blit::setCommonBlitState()
406{
407 IDirect3DDevice9 *device = getDevice();
408
409 device->SetDepthStencilSurface(NULL);
410
411 device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
412 device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
413 device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
414 device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
415 device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
416 device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED);
417 device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE);
418 device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
419
420 device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
421 device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
422 device->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, FALSE);
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +0000423 device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
424 device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
daniel@transgaming.com81655a72010-05-20 19:18:17 +0000425
daniel@transgaming.com74d760b2010-11-03 12:27:18 +0000426 RECT scissorRect = {0}; // Scissoring is disabled for flipping, but we need this to capture and restore the old rectangle
427 device->SetScissorRect(&scissorRect);
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +0000428
429 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
430 {
431 device->SetStreamSourceFreq(i, 1);
432 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000433}
434
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000435// D3D9_REPLACE
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000436void Blit::render()
437{
daniel@transgaming.comae072af2010-05-05 18:47:28 +0000438 egl::Display *display = getDisplay();
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000439 renderer::Renderer *renderer = display->getRenderer();
440 IDirect3DDevice9 *device = renderer->getDevice();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000441
442 HRESULT hr = device->SetStreamSource(0, mQuadVertexBuffer, 0, 2 * sizeof(float));
443 hr = device->SetVertexDeclaration(mQuadVertexDeclaration);
444
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000445 renderer->startScene();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000446 hr = device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000447}
448
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000449// D3D9_REPLACE
daniel@transgaming.com1ddd1dd2010-05-11 02:29:34 +0000450void Blit::saveState()
451{
452 IDirect3DDevice9 *device = getDevice();
453
454 HRESULT hr;
455
456 device->GetDepthStencilSurface(&mSavedDepthStencil);
457 device->GetRenderTarget(0, &mSavedRenderTarget);
458
459 if (mSavedStateBlock == NULL)
460 {
461 hr = device->BeginStateBlock();
462 ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
463
464 setCommonBlitState();
465
466 static const float dummyConst[4] = { 0, 0, 0, 0 };
467
468 device->SetVertexShader(NULL);
469 device->SetVertexShaderConstantF(0, dummyConst, 1);
470 device->SetPixelShader(NULL);
471 device->SetPixelShaderConstantF(0, dummyConst, 1);
472
473 D3DVIEWPORT9 dummyVp;
474 dummyVp.X = 0;
475 dummyVp.Y = 0;
476 dummyVp.Width = 1;
477 dummyVp.Height = 1;
478 dummyVp.MinZ = 0;
479 dummyVp.MaxZ = 1;
480
481 device->SetViewport(&dummyVp);
482
483 device->SetTexture(0, NULL);
484
485 device->SetStreamSource(0, mQuadVertexBuffer, 0, 0);
486
487 device->SetVertexDeclaration(mQuadVertexDeclaration);
488
489 hr = device->EndStateBlock(&mSavedStateBlock);
490 ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
491 }
492
493 ASSERT(mSavedStateBlock != NULL);
494
495 if (mSavedStateBlock != NULL)
496 {
497 hr = mSavedStateBlock->Capture();
498 ASSERT(SUCCEEDED(hr));
499 }
500}
501
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000502// D3D9_REPLACE
daniel@transgaming.com1ddd1dd2010-05-11 02:29:34 +0000503void Blit::restoreState()
504{
505 IDirect3DDevice9 *device = getDevice();
506
507 device->SetDepthStencilSurface(mSavedDepthStencil);
508 if (mSavedDepthStencil != NULL)
509 {
510 mSavedDepthStencil->Release();
511 mSavedDepthStencil = NULL;
512 }
513
514 device->SetRenderTarget(0, mSavedRenderTarget);
515 if (mSavedRenderTarget != NULL)
516 {
517 mSavedRenderTarget->Release();
518 mSavedRenderTarget = NULL;
519 }
520
521 ASSERT(mSavedStateBlock != NULL);
522
523 if (mSavedStateBlock != NULL)
524 {
525 mSavedStateBlock->Apply();
526 }
527}
528
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000529}