1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/angle/src/libGLESv2/renderer/Blit.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,595 @@ 1.4 +#include "precompiled.h" 1.5 +// 1.6 +// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. 1.7 +// Use of this source code is governed by a BSD-style license that can be 1.8 +// found in the LICENSE file. 1.9 +// 1.10 + 1.11 +// Blit.cpp: Surface copy utility class. 1.12 + 1.13 +#include "libGLESv2/renderer/Blit.h" 1.14 + 1.15 +#include "libGLESv2/main.h" 1.16 +#include "libGLESv2/renderer/renderer9_utils.h" 1.17 +#include "libGLESv2/renderer/TextureStorage9.h" 1.18 +#include "libGLESv2/renderer/RenderTarget9.h" 1.19 +#include "libGLESv2/renderer/Renderer9.h" 1.20 +#include "libGLESv2/Framebuffer.h" 1.21 +#include "libGLESv2/Renderbuffer.h" 1.22 + 1.23 +namespace 1.24 +{ 1.25 +#include "libGLESv2/renderer/shaders/compiled/standardvs.h" 1.26 +#include "libGLESv2/renderer/shaders/compiled/flipyvs.h" 1.27 +#include "libGLESv2/renderer/shaders/compiled/passthroughps.h" 1.28 +#include "libGLESv2/renderer/shaders/compiled/luminanceps.h" 1.29 +#include "libGLESv2/renderer/shaders/compiled/componentmaskps.h" 1.30 + 1.31 +const BYTE* const g_shaderCode[] = 1.32 +{ 1.33 + g_vs20_standardvs, 1.34 + g_vs20_flipyvs, 1.35 + g_ps20_passthroughps, 1.36 + g_ps20_luminanceps, 1.37 + g_ps20_componentmaskps 1.38 +}; 1.39 + 1.40 +const size_t g_shaderSize[] = 1.41 +{ 1.42 + sizeof(g_vs20_standardvs), 1.43 + sizeof(g_vs20_flipyvs), 1.44 + sizeof(g_ps20_passthroughps), 1.45 + sizeof(g_ps20_luminanceps), 1.46 + sizeof(g_ps20_componentmaskps) 1.47 +}; 1.48 +} 1.49 + 1.50 +namespace rx 1.51 +{ 1.52 +Blit::Blit(rx::Renderer9 *renderer) 1.53 + : mRenderer(renderer), mQuadVertexBuffer(NULL), mQuadVertexDeclaration(NULL), mSavedStateBlock(NULL), mSavedRenderTarget(NULL), mSavedDepthStencil(NULL) 1.54 +{ 1.55 + initGeometry(); 1.56 + memset(mCompiledShaders, 0, sizeof(mCompiledShaders)); 1.57 +} 1.58 + 1.59 +Blit::~Blit() 1.60 +{ 1.61 + if (mSavedStateBlock) mSavedStateBlock->Release(); 1.62 + if (mQuadVertexBuffer) mQuadVertexBuffer->Release(); 1.63 + if (mQuadVertexDeclaration) mQuadVertexDeclaration->Release(); 1.64 + 1.65 + for (int i = 0; i < SHADER_COUNT; i++) 1.66 + { 1.67 + if (mCompiledShaders[i]) 1.68 + { 1.69 + mCompiledShaders[i]->Release(); 1.70 + } 1.71 + } 1.72 +} 1.73 + 1.74 +void Blit::initGeometry() 1.75 +{ 1.76 + static const float quad[] = 1.77 + { 1.78 + -1, -1, 1.79 + -1, 1, 1.80 + 1, -1, 1.81 + 1, 1 1.82 + }; 1.83 + 1.84 + IDirect3DDevice9 *device = mRenderer->getDevice(); 1.85 + 1.86 + HRESULT result = device->CreateVertexBuffer(sizeof(quad), D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &mQuadVertexBuffer, NULL); 1.87 + 1.88 + if (FAILED(result)) 1.89 + { 1.90 + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); 1.91 + return gl::error(GL_OUT_OF_MEMORY); 1.92 + } 1.93 + 1.94 + void *lockPtr = NULL; 1.95 + result = mQuadVertexBuffer->Lock(0, 0, &lockPtr, 0); 1.96 + 1.97 + if (FAILED(result) || lockPtr == NULL) 1.98 + { 1.99 + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); 1.100 + return gl::error(GL_OUT_OF_MEMORY); 1.101 + } 1.102 + 1.103 + memcpy(lockPtr, quad, sizeof(quad)); 1.104 + mQuadVertexBuffer->Unlock(); 1.105 + 1.106 + static const D3DVERTEXELEMENT9 elements[] = 1.107 + { 1.108 + { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, 1.109 + D3DDECL_END() 1.110 + }; 1.111 + 1.112 + result = device->CreateVertexDeclaration(elements, &mQuadVertexDeclaration); 1.113 + 1.114 + if (FAILED(result)) 1.115 + { 1.116 + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); 1.117 + return gl::error(GL_OUT_OF_MEMORY); 1.118 + } 1.119 +} 1.120 + 1.121 +template <class D3DShaderType> 1.122 +bool Blit::setShader(ShaderId source, const char *profile, 1.123 + D3DShaderType *(rx::Renderer9::*createShader)(const DWORD *, size_t length), 1.124 + HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType*)) 1.125 +{ 1.126 + IDirect3DDevice9 *device = mRenderer->getDevice(); 1.127 + 1.128 + D3DShaderType *shader; 1.129 + 1.130 + if (mCompiledShaders[source] != NULL) 1.131 + { 1.132 + shader = static_cast<D3DShaderType*>(mCompiledShaders[source]); 1.133 + } 1.134 + else 1.135 + { 1.136 + const BYTE* shaderCode = g_shaderCode[source]; 1.137 + size_t shaderSize = g_shaderSize[source]; 1.138 + 1.139 + shader = (mRenderer->*createShader)(reinterpret_cast<const DWORD*>(shaderCode), shaderSize); 1.140 + if (!shader) 1.141 + { 1.142 + ERR("Failed to create shader for blit operation"); 1.143 + return false; 1.144 + } 1.145 + 1.146 + mCompiledShaders[source] = shader; 1.147 + } 1.148 + 1.149 + HRESULT hr = (device->*setShader)(shader); 1.150 + 1.151 + if (FAILED(hr)) 1.152 + { 1.153 + ERR("Failed to set shader for blit operation"); 1.154 + return false; 1.155 + } 1.156 + 1.157 + return true; 1.158 +} 1.159 + 1.160 +bool Blit::setVertexShader(ShaderId shader) 1.161 +{ 1.162 + return setShader<IDirect3DVertexShader9>(shader, "vs_2_0", &rx::Renderer9::createVertexShader, &IDirect3DDevice9::SetVertexShader); 1.163 +} 1.164 + 1.165 +bool Blit::setPixelShader(ShaderId shader) 1.166 +{ 1.167 + return setShader<IDirect3DPixelShader9>(shader, "ps_2_0", &rx::Renderer9::createPixelShader, &IDirect3DDevice9::SetPixelShader); 1.168 +} 1.169 + 1.170 +RECT Blit::getSurfaceRect(IDirect3DSurface9 *surface) const 1.171 +{ 1.172 + D3DSURFACE_DESC desc; 1.173 + surface->GetDesc(&desc); 1.174 + 1.175 + RECT rect; 1.176 + rect.left = 0; 1.177 + rect.top = 0; 1.178 + rect.right = desc.Width; 1.179 + rect.bottom = desc.Height; 1.180 + 1.181 + return rect; 1.182 +} 1.183 + 1.184 +bool Blit::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest) 1.185 +{ 1.186 + IDirect3DTexture9 *texture = copySurfaceToTexture(source, getSurfaceRect(source)); 1.187 + if (!texture) 1.188 + { 1.189 + return false; 1.190 + } 1.191 + 1.192 + IDirect3DDevice9 *device = mRenderer->getDevice(); 1.193 + 1.194 + saveState(); 1.195 + 1.196 + device->SetTexture(0, texture); 1.197 + device->SetRenderTarget(0, dest); 1.198 + 1.199 + setVertexShader(SHADER_VS_STANDARD); 1.200 + setPixelShader(SHADER_PS_PASSTHROUGH); 1.201 + 1.202 + setCommonBlitState(); 1.203 + device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); 1.204 + device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); 1.205 + 1.206 + setViewport(getSurfaceRect(dest), 0, 0); 1.207 + 1.208 + render(); 1.209 + 1.210 + texture->Release(); 1.211 + 1.212 + restoreState(); 1.213 + 1.214 + return true; 1.215 +} 1.216 + 1.217 +bool Blit::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level) 1.218 +{ 1.219 + RenderTarget9 *renderTarget = NULL; 1.220 + IDirect3DSurface9 *source = NULL; 1.221 + gl::Renderbuffer *colorbuffer = framebuffer->getColorbuffer(0); 1.222 + 1.223 + if (colorbuffer) 1.224 + { 1.225 + renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget()); 1.226 + } 1.227 + 1.228 + if (renderTarget) 1.229 + { 1.230 + source = renderTarget->getSurface(); 1.231 + } 1.232 + 1.233 + if (!source) 1.234 + { 1.235 + ERR("Failed to retrieve the render target."); 1.236 + return gl::error(GL_OUT_OF_MEMORY, false); 1.237 + } 1.238 + 1.239 + TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage->getStorageInstance()); 1.240 + IDirect3DSurface9 *destSurface = storage9->getSurfaceLevel(level, true); 1.241 + bool result = false; 1.242 + 1.243 + if (destSurface) 1.244 + { 1.245 + result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface); 1.246 + destSurface->Release(); 1.247 + } 1.248 + 1.249 + source->Release(); 1.250 + return result; 1.251 +} 1.252 + 1.253 +bool Blit::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level) 1.254 +{ 1.255 + RenderTarget9 *renderTarget = NULL; 1.256 + IDirect3DSurface9 *source = NULL; 1.257 + gl::Renderbuffer *colorbuffer = framebuffer->getColorbuffer(0); 1.258 + 1.259 + if (colorbuffer) 1.260 + { 1.261 + renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget()); 1.262 + } 1.263 + 1.264 + if (renderTarget) 1.265 + { 1.266 + source = renderTarget->getSurface(); 1.267 + } 1.268 + 1.269 + if (!source) 1.270 + { 1.271 + ERR("Failed to retrieve the render target."); 1.272 + return gl::error(GL_OUT_OF_MEMORY, false); 1.273 + } 1.274 + 1.275 + TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage->getStorageInstance()); 1.276 + IDirect3DSurface9 *destSurface = storage9->getCubeMapSurface(target, level, true); 1.277 + bool result = false; 1.278 + 1.279 + if (destSurface) 1.280 + { 1.281 + result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface); 1.282 + destSurface->Release(); 1.283 + } 1.284 + 1.285 + source->Release(); 1.286 + return result; 1.287 +} 1.288 + 1.289 +bool Blit::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest) 1.290 +{ 1.291 + if (!dest) 1.292 + { 1.293 + return false; 1.294 + } 1.295 + 1.296 + IDirect3DDevice9 *device = mRenderer->getDevice(); 1.297 + 1.298 + D3DSURFACE_DESC sourceDesc; 1.299 + D3DSURFACE_DESC destDesc; 1.300 + source->GetDesc(&sourceDesc); 1.301 + dest->GetDesc(&destDesc); 1.302 + 1.303 + if (sourceDesc.Format == destDesc.Format && destDesc.Usage & D3DUSAGE_RENDERTARGET && 1.304 + d3d9_gl::IsFormatChannelEquivalent(destDesc.Format, destFormat)) // Can use StretchRect 1.305 + { 1.306 + RECT destRect = {xoffset, yoffset, xoffset + (sourceRect.right - sourceRect.left), yoffset + (sourceRect.bottom - sourceRect.top)}; 1.307 + HRESULT result = device->StretchRect(source, &sourceRect, dest, &destRect, D3DTEXF_POINT); 1.308 + 1.309 + if (FAILED(result)) 1.310 + { 1.311 + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); 1.312 + return gl::error(GL_OUT_OF_MEMORY, false); 1.313 + } 1.314 + } 1.315 + else 1.316 + { 1.317 + return formatConvert(source, sourceRect, destFormat, xoffset, yoffset, dest); 1.318 + } 1.319 + return true; 1.320 +} 1.321 + 1.322 +bool Blit::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest) 1.323 +{ 1.324 + IDirect3DTexture9 *texture = copySurfaceToTexture(source, sourceRect); 1.325 + if (!texture) 1.326 + { 1.327 + return false; 1.328 + } 1.329 + 1.330 + IDirect3DDevice9 *device = mRenderer->getDevice(); 1.331 + 1.332 + saveState(); 1.333 + 1.334 + device->SetTexture(0, texture); 1.335 + device->SetRenderTarget(0, dest); 1.336 + 1.337 + setViewport(sourceRect, xoffset, yoffset); 1.338 + 1.339 + setCommonBlitState(); 1.340 + if (setFormatConvertShaders(destFormat)) 1.341 + { 1.342 + render(); 1.343 + } 1.344 + 1.345 + texture->Release(); 1.346 + 1.347 + restoreState(); 1.348 + 1.349 + return true; 1.350 +} 1.351 + 1.352 +bool Blit::setFormatConvertShaders(GLenum destFormat) 1.353 +{ 1.354 + bool okay = setVertexShader(SHADER_VS_STANDARD); 1.355 + 1.356 + switch (destFormat) 1.357 + { 1.358 + default: UNREACHABLE(); 1.359 + case GL_RGBA: 1.360 + case GL_BGRA_EXT: 1.361 + case GL_RGB: 1.362 + case GL_ALPHA: 1.363 + okay = okay && setPixelShader(SHADER_PS_COMPONENTMASK); 1.364 + break; 1.365 + 1.366 + case GL_LUMINANCE: 1.367 + case GL_LUMINANCE_ALPHA: 1.368 + okay = okay && setPixelShader(SHADER_PS_LUMINANCE); 1.369 + break; 1.370 + } 1.371 + 1.372 + if (!okay) 1.373 + { 1.374 + return false; 1.375 + } 1.376 + 1.377 + enum { X = 0, Y = 1, Z = 2, W = 3 }; 1.378 + 1.379 + // The meaning of this constant depends on the shader that was selected. 1.380 + // See the shader assembly code above for details. 1.381 + float psConst0[4] = { 0, 0, 0, 0 }; 1.382 + 1.383 + switch (destFormat) 1.384 + { 1.385 + default: UNREACHABLE(); 1.386 + case GL_RGBA: 1.387 + case GL_BGRA_EXT: 1.388 + psConst0[X] = 1; 1.389 + psConst0[Z] = 1; 1.390 + break; 1.391 + 1.392 + case GL_RGB: 1.393 + psConst0[X] = 1; 1.394 + psConst0[W] = 1; 1.395 + break; 1.396 + 1.397 + case GL_ALPHA: 1.398 + psConst0[Z] = 1; 1.399 + break; 1.400 + 1.401 + case GL_LUMINANCE: 1.402 + psConst0[Y] = 1; 1.403 + break; 1.404 + 1.405 + case GL_LUMINANCE_ALPHA: 1.406 + psConst0[X] = 1; 1.407 + break; 1.408 + } 1.409 + 1.410 + mRenderer->getDevice()->SetPixelShaderConstantF(0, psConst0, 1); 1.411 + 1.412 + return true; 1.413 +} 1.414 + 1.415 +IDirect3DTexture9 *Blit::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect) 1.416 +{ 1.417 + if (!surface) 1.418 + { 1.419 + return NULL; 1.420 + } 1.421 + 1.422 + IDirect3DDevice9 *device = mRenderer->getDevice(); 1.423 + 1.424 + D3DSURFACE_DESC sourceDesc; 1.425 + surface->GetDesc(&sourceDesc); 1.426 + 1.427 + // Copy the render target into a texture 1.428 + IDirect3DTexture9 *texture; 1.429 + HRESULT result = device->CreateTexture(sourceRect.right - sourceRect.left, sourceRect.bottom - sourceRect.top, 1, D3DUSAGE_RENDERTARGET, sourceDesc.Format, D3DPOOL_DEFAULT, &texture, NULL); 1.430 + 1.431 + if (FAILED(result)) 1.432 + { 1.433 + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); 1.434 + return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL); 1.435 + } 1.436 + 1.437 + IDirect3DSurface9 *textureSurface; 1.438 + result = texture->GetSurfaceLevel(0, &textureSurface); 1.439 + 1.440 + if (FAILED(result)) 1.441 + { 1.442 + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); 1.443 + texture->Release(); 1.444 + return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL); 1.445 + } 1.446 + 1.447 + mRenderer->endScene(); 1.448 + result = device->StretchRect(surface, &sourceRect, textureSurface, NULL, D3DTEXF_NONE); 1.449 + 1.450 + textureSurface->Release(); 1.451 + 1.452 + if (FAILED(result)) 1.453 + { 1.454 + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); 1.455 + texture->Release(); 1.456 + return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL); 1.457 + } 1.458 + 1.459 + return texture; 1.460 +} 1.461 + 1.462 +void Blit::setViewport(const RECT &sourceRect, GLint xoffset, GLint yoffset) 1.463 +{ 1.464 + IDirect3DDevice9 *device = mRenderer->getDevice(); 1.465 + 1.466 + D3DVIEWPORT9 vp; 1.467 + vp.X = xoffset; 1.468 + vp.Y = yoffset; 1.469 + vp.Width = sourceRect.right - sourceRect.left; 1.470 + vp.Height = sourceRect.bottom - sourceRect.top; 1.471 + vp.MinZ = 0.0f; 1.472 + vp.MaxZ = 1.0f; 1.473 + device->SetViewport(&vp); 1.474 + 1.475 + float halfPixelAdjust[4] = { -1.0f/vp.Width, 1.0f/vp.Height, 0, 0 }; 1.476 + device->SetVertexShaderConstantF(0, halfPixelAdjust, 1); 1.477 +} 1.478 + 1.479 +void Blit::setCommonBlitState() 1.480 +{ 1.481 + IDirect3DDevice9 *device = mRenderer->getDevice(); 1.482 + 1.483 + device->SetDepthStencilSurface(NULL); 1.484 + 1.485 + device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); 1.486 + device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); 1.487 + device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); 1.488 + device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); 1.489 + device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0); 1.490 + device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED); 1.491 + device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE); 1.492 + device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); 1.493 + 1.494 + device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); 1.495 + device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); 1.496 + device->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, FALSE); 1.497 + device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); 1.498 + device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); 1.499 + 1.500 + RECT scissorRect = {0}; // Scissoring is disabled for flipping, but we need this to capture and restore the old rectangle 1.501 + device->SetScissorRect(&scissorRect); 1.502 + 1.503 + for(int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) 1.504 + { 1.505 + device->SetStreamSourceFreq(i, 1); 1.506 + } 1.507 +} 1.508 + 1.509 +void Blit::render() 1.510 +{ 1.511 + IDirect3DDevice9 *device = mRenderer->getDevice(); 1.512 + 1.513 + HRESULT hr = device->SetStreamSource(0, mQuadVertexBuffer, 0, 2 * sizeof(float)); 1.514 + hr = device->SetVertexDeclaration(mQuadVertexDeclaration); 1.515 + 1.516 + mRenderer->startScene(); 1.517 + hr = device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); 1.518 +} 1.519 + 1.520 +void Blit::saveState() 1.521 +{ 1.522 + IDirect3DDevice9 *device = mRenderer->getDevice(); 1.523 + 1.524 + HRESULT hr; 1.525 + 1.526 + device->GetDepthStencilSurface(&mSavedDepthStencil); 1.527 + device->GetRenderTarget(0, &mSavedRenderTarget); 1.528 + 1.529 + if (mSavedStateBlock == NULL) 1.530 + { 1.531 + hr = device->BeginStateBlock(); 1.532 + ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); 1.533 + 1.534 + setCommonBlitState(); 1.535 + 1.536 + static const float dummyConst[4] = { 0, 0, 0, 0 }; 1.537 + 1.538 + device->SetVertexShader(NULL); 1.539 + device->SetVertexShaderConstantF(0, dummyConst, 1); 1.540 + device->SetPixelShader(NULL); 1.541 + device->SetPixelShaderConstantF(0, dummyConst, 1); 1.542 + 1.543 + D3DVIEWPORT9 dummyVp; 1.544 + dummyVp.X = 0; 1.545 + dummyVp.Y = 0; 1.546 + dummyVp.Width = 1; 1.547 + dummyVp.Height = 1; 1.548 + dummyVp.MinZ = 0; 1.549 + dummyVp.MaxZ = 1; 1.550 + 1.551 + device->SetViewport(&dummyVp); 1.552 + 1.553 + device->SetTexture(0, NULL); 1.554 + 1.555 + device->SetStreamSource(0, mQuadVertexBuffer, 0, 0); 1.556 + 1.557 + device->SetVertexDeclaration(mQuadVertexDeclaration); 1.558 + 1.559 + hr = device->EndStateBlock(&mSavedStateBlock); 1.560 + ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); 1.561 + } 1.562 + 1.563 + ASSERT(mSavedStateBlock != NULL); 1.564 + 1.565 + if (mSavedStateBlock != NULL) 1.566 + { 1.567 + hr = mSavedStateBlock->Capture(); 1.568 + ASSERT(SUCCEEDED(hr)); 1.569 + } 1.570 +} 1.571 + 1.572 +void Blit::restoreState() 1.573 +{ 1.574 + IDirect3DDevice9 *device = mRenderer->getDevice(); 1.575 + 1.576 + device->SetDepthStencilSurface(mSavedDepthStencil); 1.577 + if (mSavedDepthStencil != NULL) 1.578 + { 1.579 + mSavedDepthStencil->Release(); 1.580 + mSavedDepthStencil = NULL; 1.581 + } 1.582 + 1.583 + device->SetRenderTarget(0, mSavedRenderTarget); 1.584 + if (mSavedRenderTarget != NULL) 1.585 + { 1.586 + mSavedRenderTarget->Release(); 1.587 + mSavedRenderTarget = NULL; 1.588 + } 1.589 + 1.590 + ASSERT(mSavedStateBlock != NULL); 1.591 + 1.592 + if (mSavedStateBlock != NULL) 1.593 + { 1.594 + mSavedStateBlock->Apply(); 1.595 + } 1.596 +} 1.597 + 1.598 +}