gfx/angle/src/libGLESv2/renderer/Blit.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 #include "precompiled.h"
michael@0 2 //
michael@0 3 // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
michael@0 4 // Use of this source code is governed by a BSD-style license that can be
michael@0 5 // found in the LICENSE file.
michael@0 6 //
michael@0 7
michael@0 8 // Blit.cpp: Surface copy utility class.
michael@0 9
michael@0 10 #include "libGLESv2/renderer/Blit.h"
michael@0 11
michael@0 12 #include "libGLESv2/main.h"
michael@0 13 #include "libGLESv2/renderer/renderer9_utils.h"
michael@0 14 #include "libGLESv2/renderer/TextureStorage9.h"
michael@0 15 #include "libGLESv2/renderer/RenderTarget9.h"
michael@0 16 #include "libGLESv2/renderer/Renderer9.h"
michael@0 17 #include "libGLESv2/Framebuffer.h"
michael@0 18 #include "libGLESv2/Renderbuffer.h"
michael@0 19
michael@0 20 namespace
michael@0 21 {
michael@0 22 #include "libGLESv2/renderer/shaders/compiled/standardvs.h"
michael@0 23 #include "libGLESv2/renderer/shaders/compiled/flipyvs.h"
michael@0 24 #include "libGLESv2/renderer/shaders/compiled/passthroughps.h"
michael@0 25 #include "libGLESv2/renderer/shaders/compiled/luminanceps.h"
michael@0 26 #include "libGLESv2/renderer/shaders/compiled/componentmaskps.h"
michael@0 27
michael@0 28 const BYTE* const g_shaderCode[] =
michael@0 29 {
michael@0 30 g_vs20_standardvs,
michael@0 31 g_vs20_flipyvs,
michael@0 32 g_ps20_passthroughps,
michael@0 33 g_ps20_luminanceps,
michael@0 34 g_ps20_componentmaskps
michael@0 35 };
michael@0 36
michael@0 37 const size_t g_shaderSize[] =
michael@0 38 {
michael@0 39 sizeof(g_vs20_standardvs),
michael@0 40 sizeof(g_vs20_flipyvs),
michael@0 41 sizeof(g_ps20_passthroughps),
michael@0 42 sizeof(g_ps20_luminanceps),
michael@0 43 sizeof(g_ps20_componentmaskps)
michael@0 44 };
michael@0 45 }
michael@0 46
michael@0 47 namespace rx
michael@0 48 {
michael@0 49 Blit::Blit(rx::Renderer9 *renderer)
michael@0 50 : mRenderer(renderer), mQuadVertexBuffer(NULL), mQuadVertexDeclaration(NULL), mSavedStateBlock(NULL), mSavedRenderTarget(NULL), mSavedDepthStencil(NULL)
michael@0 51 {
michael@0 52 initGeometry();
michael@0 53 memset(mCompiledShaders, 0, sizeof(mCompiledShaders));
michael@0 54 }
michael@0 55
michael@0 56 Blit::~Blit()
michael@0 57 {
michael@0 58 if (mSavedStateBlock) mSavedStateBlock->Release();
michael@0 59 if (mQuadVertexBuffer) mQuadVertexBuffer->Release();
michael@0 60 if (mQuadVertexDeclaration) mQuadVertexDeclaration->Release();
michael@0 61
michael@0 62 for (int i = 0; i < SHADER_COUNT; i++)
michael@0 63 {
michael@0 64 if (mCompiledShaders[i])
michael@0 65 {
michael@0 66 mCompiledShaders[i]->Release();
michael@0 67 }
michael@0 68 }
michael@0 69 }
michael@0 70
michael@0 71 void Blit::initGeometry()
michael@0 72 {
michael@0 73 static const float quad[] =
michael@0 74 {
michael@0 75 -1, -1,
michael@0 76 -1, 1,
michael@0 77 1, -1,
michael@0 78 1, 1
michael@0 79 };
michael@0 80
michael@0 81 IDirect3DDevice9 *device = mRenderer->getDevice();
michael@0 82
michael@0 83 HRESULT result = device->CreateVertexBuffer(sizeof(quad), D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &mQuadVertexBuffer, NULL);
michael@0 84
michael@0 85 if (FAILED(result))
michael@0 86 {
michael@0 87 ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
michael@0 88 return gl::error(GL_OUT_OF_MEMORY);
michael@0 89 }
michael@0 90
michael@0 91 void *lockPtr = NULL;
michael@0 92 result = mQuadVertexBuffer->Lock(0, 0, &lockPtr, 0);
michael@0 93
michael@0 94 if (FAILED(result) || lockPtr == NULL)
michael@0 95 {
michael@0 96 ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
michael@0 97 return gl::error(GL_OUT_OF_MEMORY);
michael@0 98 }
michael@0 99
michael@0 100 memcpy(lockPtr, quad, sizeof(quad));
michael@0 101 mQuadVertexBuffer->Unlock();
michael@0 102
michael@0 103 static const D3DVERTEXELEMENT9 elements[] =
michael@0 104 {
michael@0 105 { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
michael@0 106 D3DDECL_END()
michael@0 107 };
michael@0 108
michael@0 109 result = device->CreateVertexDeclaration(elements, &mQuadVertexDeclaration);
michael@0 110
michael@0 111 if (FAILED(result))
michael@0 112 {
michael@0 113 ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
michael@0 114 return gl::error(GL_OUT_OF_MEMORY);
michael@0 115 }
michael@0 116 }
michael@0 117
michael@0 118 template <class D3DShaderType>
michael@0 119 bool Blit::setShader(ShaderId source, const char *profile,
michael@0 120 D3DShaderType *(rx::Renderer9::*createShader)(const DWORD *, size_t length),
michael@0 121 HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType*))
michael@0 122 {
michael@0 123 IDirect3DDevice9 *device = mRenderer->getDevice();
michael@0 124
michael@0 125 D3DShaderType *shader;
michael@0 126
michael@0 127 if (mCompiledShaders[source] != NULL)
michael@0 128 {
michael@0 129 shader = static_cast<D3DShaderType*>(mCompiledShaders[source]);
michael@0 130 }
michael@0 131 else
michael@0 132 {
michael@0 133 const BYTE* shaderCode = g_shaderCode[source];
michael@0 134 size_t shaderSize = g_shaderSize[source];
michael@0 135
michael@0 136 shader = (mRenderer->*createShader)(reinterpret_cast<const DWORD*>(shaderCode), shaderSize);
michael@0 137 if (!shader)
michael@0 138 {
michael@0 139 ERR("Failed to create shader for blit operation");
michael@0 140 return false;
michael@0 141 }
michael@0 142
michael@0 143 mCompiledShaders[source] = shader;
michael@0 144 }
michael@0 145
michael@0 146 HRESULT hr = (device->*setShader)(shader);
michael@0 147
michael@0 148 if (FAILED(hr))
michael@0 149 {
michael@0 150 ERR("Failed to set shader for blit operation");
michael@0 151 return false;
michael@0 152 }
michael@0 153
michael@0 154 return true;
michael@0 155 }
michael@0 156
michael@0 157 bool Blit::setVertexShader(ShaderId shader)
michael@0 158 {
michael@0 159 return setShader<IDirect3DVertexShader9>(shader, "vs_2_0", &rx::Renderer9::createVertexShader, &IDirect3DDevice9::SetVertexShader);
michael@0 160 }
michael@0 161
michael@0 162 bool Blit::setPixelShader(ShaderId shader)
michael@0 163 {
michael@0 164 return setShader<IDirect3DPixelShader9>(shader, "ps_2_0", &rx::Renderer9::createPixelShader, &IDirect3DDevice9::SetPixelShader);
michael@0 165 }
michael@0 166
michael@0 167 RECT Blit::getSurfaceRect(IDirect3DSurface9 *surface) const
michael@0 168 {
michael@0 169 D3DSURFACE_DESC desc;
michael@0 170 surface->GetDesc(&desc);
michael@0 171
michael@0 172 RECT rect;
michael@0 173 rect.left = 0;
michael@0 174 rect.top = 0;
michael@0 175 rect.right = desc.Width;
michael@0 176 rect.bottom = desc.Height;
michael@0 177
michael@0 178 return rect;
michael@0 179 }
michael@0 180
michael@0 181 bool Blit::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest)
michael@0 182 {
michael@0 183 IDirect3DTexture9 *texture = copySurfaceToTexture(source, getSurfaceRect(source));
michael@0 184 if (!texture)
michael@0 185 {
michael@0 186 return false;
michael@0 187 }
michael@0 188
michael@0 189 IDirect3DDevice9 *device = mRenderer->getDevice();
michael@0 190
michael@0 191 saveState();
michael@0 192
michael@0 193 device->SetTexture(0, texture);
michael@0 194 device->SetRenderTarget(0, dest);
michael@0 195
michael@0 196 setVertexShader(SHADER_VS_STANDARD);
michael@0 197 setPixelShader(SHADER_PS_PASSTHROUGH);
michael@0 198
michael@0 199 setCommonBlitState();
michael@0 200 device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
michael@0 201 device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
michael@0 202
michael@0 203 setViewport(getSurfaceRect(dest), 0, 0);
michael@0 204
michael@0 205 render();
michael@0 206
michael@0 207 texture->Release();
michael@0 208
michael@0 209 restoreState();
michael@0 210
michael@0 211 return true;
michael@0 212 }
michael@0 213
michael@0 214 bool Blit::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level)
michael@0 215 {
michael@0 216 RenderTarget9 *renderTarget = NULL;
michael@0 217 IDirect3DSurface9 *source = NULL;
michael@0 218 gl::Renderbuffer *colorbuffer = framebuffer->getColorbuffer(0);
michael@0 219
michael@0 220 if (colorbuffer)
michael@0 221 {
michael@0 222 renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget());
michael@0 223 }
michael@0 224
michael@0 225 if (renderTarget)
michael@0 226 {
michael@0 227 source = renderTarget->getSurface();
michael@0 228 }
michael@0 229
michael@0 230 if (!source)
michael@0 231 {
michael@0 232 ERR("Failed to retrieve the render target.");
michael@0 233 return gl::error(GL_OUT_OF_MEMORY, false);
michael@0 234 }
michael@0 235
michael@0 236 TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage->getStorageInstance());
michael@0 237 IDirect3DSurface9 *destSurface = storage9->getSurfaceLevel(level, true);
michael@0 238 bool result = false;
michael@0 239
michael@0 240 if (destSurface)
michael@0 241 {
michael@0 242 result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface);
michael@0 243 destSurface->Release();
michael@0 244 }
michael@0 245
michael@0 246 source->Release();
michael@0 247 return result;
michael@0 248 }
michael@0 249
michael@0 250 bool Blit::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level)
michael@0 251 {
michael@0 252 RenderTarget9 *renderTarget = NULL;
michael@0 253 IDirect3DSurface9 *source = NULL;
michael@0 254 gl::Renderbuffer *colorbuffer = framebuffer->getColorbuffer(0);
michael@0 255
michael@0 256 if (colorbuffer)
michael@0 257 {
michael@0 258 renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget());
michael@0 259 }
michael@0 260
michael@0 261 if (renderTarget)
michael@0 262 {
michael@0 263 source = renderTarget->getSurface();
michael@0 264 }
michael@0 265
michael@0 266 if (!source)
michael@0 267 {
michael@0 268 ERR("Failed to retrieve the render target.");
michael@0 269 return gl::error(GL_OUT_OF_MEMORY, false);
michael@0 270 }
michael@0 271
michael@0 272 TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage->getStorageInstance());
michael@0 273 IDirect3DSurface9 *destSurface = storage9->getCubeMapSurface(target, level, true);
michael@0 274 bool result = false;
michael@0 275
michael@0 276 if (destSurface)
michael@0 277 {
michael@0 278 result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface);
michael@0 279 destSurface->Release();
michael@0 280 }
michael@0 281
michael@0 282 source->Release();
michael@0 283 return result;
michael@0 284 }
michael@0 285
michael@0 286 bool Blit::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest)
michael@0 287 {
michael@0 288 if (!dest)
michael@0 289 {
michael@0 290 return false;
michael@0 291 }
michael@0 292
michael@0 293 IDirect3DDevice9 *device = mRenderer->getDevice();
michael@0 294
michael@0 295 D3DSURFACE_DESC sourceDesc;
michael@0 296 D3DSURFACE_DESC destDesc;
michael@0 297 source->GetDesc(&sourceDesc);
michael@0 298 dest->GetDesc(&destDesc);
michael@0 299
michael@0 300 if (sourceDesc.Format == destDesc.Format && destDesc.Usage & D3DUSAGE_RENDERTARGET &&
michael@0 301 d3d9_gl::IsFormatChannelEquivalent(destDesc.Format, destFormat)) // Can use StretchRect
michael@0 302 {
michael@0 303 RECT destRect = {xoffset, yoffset, xoffset + (sourceRect.right - sourceRect.left), yoffset + (sourceRect.bottom - sourceRect.top)};
michael@0 304 HRESULT result = device->StretchRect(source, &sourceRect, dest, &destRect, D3DTEXF_POINT);
michael@0 305
michael@0 306 if (FAILED(result))
michael@0 307 {
michael@0 308 ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
michael@0 309 return gl::error(GL_OUT_OF_MEMORY, false);
michael@0 310 }
michael@0 311 }
michael@0 312 else
michael@0 313 {
michael@0 314 return formatConvert(source, sourceRect, destFormat, xoffset, yoffset, dest);
michael@0 315 }
michael@0 316 return true;
michael@0 317 }
michael@0 318
michael@0 319 bool Blit::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest)
michael@0 320 {
michael@0 321 IDirect3DTexture9 *texture = copySurfaceToTexture(source, sourceRect);
michael@0 322 if (!texture)
michael@0 323 {
michael@0 324 return false;
michael@0 325 }
michael@0 326
michael@0 327 IDirect3DDevice9 *device = mRenderer->getDevice();
michael@0 328
michael@0 329 saveState();
michael@0 330
michael@0 331 device->SetTexture(0, texture);
michael@0 332 device->SetRenderTarget(0, dest);
michael@0 333
michael@0 334 setViewport(sourceRect, xoffset, yoffset);
michael@0 335
michael@0 336 setCommonBlitState();
michael@0 337 if (setFormatConvertShaders(destFormat))
michael@0 338 {
michael@0 339 render();
michael@0 340 }
michael@0 341
michael@0 342 texture->Release();
michael@0 343
michael@0 344 restoreState();
michael@0 345
michael@0 346 return true;
michael@0 347 }
michael@0 348
michael@0 349 bool Blit::setFormatConvertShaders(GLenum destFormat)
michael@0 350 {
michael@0 351 bool okay = setVertexShader(SHADER_VS_STANDARD);
michael@0 352
michael@0 353 switch (destFormat)
michael@0 354 {
michael@0 355 default: UNREACHABLE();
michael@0 356 case GL_RGBA:
michael@0 357 case GL_BGRA_EXT:
michael@0 358 case GL_RGB:
michael@0 359 case GL_ALPHA:
michael@0 360 okay = okay && setPixelShader(SHADER_PS_COMPONENTMASK);
michael@0 361 break;
michael@0 362
michael@0 363 case GL_LUMINANCE:
michael@0 364 case GL_LUMINANCE_ALPHA:
michael@0 365 okay = okay && setPixelShader(SHADER_PS_LUMINANCE);
michael@0 366 break;
michael@0 367 }
michael@0 368
michael@0 369 if (!okay)
michael@0 370 {
michael@0 371 return false;
michael@0 372 }
michael@0 373
michael@0 374 enum { X = 0, Y = 1, Z = 2, W = 3 };
michael@0 375
michael@0 376 // The meaning of this constant depends on the shader that was selected.
michael@0 377 // See the shader assembly code above for details.
michael@0 378 float psConst0[4] = { 0, 0, 0, 0 };
michael@0 379
michael@0 380 switch (destFormat)
michael@0 381 {
michael@0 382 default: UNREACHABLE();
michael@0 383 case GL_RGBA:
michael@0 384 case GL_BGRA_EXT:
michael@0 385 psConst0[X] = 1;
michael@0 386 psConst0[Z] = 1;
michael@0 387 break;
michael@0 388
michael@0 389 case GL_RGB:
michael@0 390 psConst0[X] = 1;
michael@0 391 psConst0[W] = 1;
michael@0 392 break;
michael@0 393
michael@0 394 case GL_ALPHA:
michael@0 395 psConst0[Z] = 1;
michael@0 396 break;
michael@0 397
michael@0 398 case GL_LUMINANCE:
michael@0 399 psConst0[Y] = 1;
michael@0 400 break;
michael@0 401
michael@0 402 case GL_LUMINANCE_ALPHA:
michael@0 403 psConst0[X] = 1;
michael@0 404 break;
michael@0 405 }
michael@0 406
michael@0 407 mRenderer->getDevice()->SetPixelShaderConstantF(0, psConst0, 1);
michael@0 408
michael@0 409 return true;
michael@0 410 }
michael@0 411
michael@0 412 IDirect3DTexture9 *Blit::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect)
michael@0 413 {
michael@0 414 if (!surface)
michael@0 415 {
michael@0 416 return NULL;
michael@0 417 }
michael@0 418
michael@0 419 IDirect3DDevice9 *device = mRenderer->getDevice();
michael@0 420
michael@0 421 D3DSURFACE_DESC sourceDesc;
michael@0 422 surface->GetDesc(&sourceDesc);
michael@0 423
michael@0 424 // Copy the render target into a texture
michael@0 425 IDirect3DTexture9 *texture;
michael@0 426 HRESULT result = device->CreateTexture(sourceRect.right - sourceRect.left, sourceRect.bottom - sourceRect.top, 1, D3DUSAGE_RENDERTARGET, sourceDesc.Format, D3DPOOL_DEFAULT, &texture, NULL);
michael@0 427
michael@0 428 if (FAILED(result))
michael@0 429 {
michael@0 430 ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
michael@0 431 return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
michael@0 432 }
michael@0 433
michael@0 434 IDirect3DSurface9 *textureSurface;
michael@0 435 result = texture->GetSurfaceLevel(0, &textureSurface);
michael@0 436
michael@0 437 if (FAILED(result))
michael@0 438 {
michael@0 439 ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
michael@0 440 texture->Release();
michael@0 441 return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
michael@0 442 }
michael@0 443
michael@0 444 mRenderer->endScene();
michael@0 445 result = device->StretchRect(surface, &sourceRect, textureSurface, NULL, D3DTEXF_NONE);
michael@0 446
michael@0 447 textureSurface->Release();
michael@0 448
michael@0 449 if (FAILED(result))
michael@0 450 {
michael@0 451 ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
michael@0 452 texture->Release();
michael@0 453 return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
michael@0 454 }
michael@0 455
michael@0 456 return texture;
michael@0 457 }
michael@0 458
michael@0 459 void Blit::setViewport(const RECT &sourceRect, GLint xoffset, GLint yoffset)
michael@0 460 {
michael@0 461 IDirect3DDevice9 *device = mRenderer->getDevice();
michael@0 462
michael@0 463 D3DVIEWPORT9 vp;
michael@0 464 vp.X = xoffset;
michael@0 465 vp.Y = yoffset;
michael@0 466 vp.Width = sourceRect.right - sourceRect.left;
michael@0 467 vp.Height = sourceRect.bottom - sourceRect.top;
michael@0 468 vp.MinZ = 0.0f;
michael@0 469 vp.MaxZ = 1.0f;
michael@0 470 device->SetViewport(&vp);
michael@0 471
michael@0 472 float halfPixelAdjust[4] = { -1.0f/vp.Width, 1.0f/vp.Height, 0, 0 };
michael@0 473 device->SetVertexShaderConstantF(0, halfPixelAdjust, 1);
michael@0 474 }
michael@0 475
michael@0 476 void Blit::setCommonBlitState()
michael@0 477 {
michael@0 478 IDirect3DDevice9 *device = mRenderer->getDevice();
michael@0 479
michael@0 480 device->SetDepthStencilSurface(NULL);
michael@0 481
michael@0 482 device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
michael@0 483 device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
michael@0 484 device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
michael@0 485 device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
michael@0 486 device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
michael@0 487 device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED);
michael@0 488 device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE);
michael@0 489 device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
michael@0 490
michael@0 491 device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
michael@0 492 device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
michael@0 493 device->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, FALSE);
michael@0 494 device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
michael@0 495 device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
michael@0 496
michael@0 497 RECT scissorRect = {0}; // Scissoring is disabled for flipping, but we need this to capture and restore the old rectangle
michael@0 498 device->SetScissorRect(&scissorRect);
michael@0 499
michael@0 500 for(int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
michael@0 501 {
michael@0 502 device->SetStreamSourceFreq(i, 1);
michael@0 503 }
michael@0 504 }
michael@0 505
michael@0 506 void Blit::render()
michael@0 507 {
michael@0 508 IDirect3DDevice9 *device = mRenderer->getDevice();
michael@0 509
michael@0 510 HRESULT hr = device->SetStreamSource(0, mQuadVertexBuffer, 0, 2 * sizeof(float));
michael@0 511 hr = device->SetVertexDeclaration(mQuadVertexDeclaration);
michael@0 512
michael@0 513 mRenderer->startScene();
michael@0 514 hr = device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
michael@0 515 }
michael@0 516
michael@0 517 void Blit::saveState()
michael@0 518 {
michael@0 519 IDirect3DDevice9 *device = mRenderer->getDevice();
michael@0 520
michael@0 521 HRESULT hr;
michael@0 522
michael@0 523 device->GetDepthStencilSurface(&mSavedDepthStencil);
michael@0 524 device->GetRenderTarget(0, &mSavedRenderTarget);
michael@0 525
michael@0 526 if (mSavedStateBlock == NULL)
michael@0 527 {
michael@0 528 hr = device->BeginStateBlock();
michael@0 529 ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
michael@0 530
michael@0 531 setCommonBlitState();
michael@0 532
michael@0 533 static const float dummyConst[4] = { 0, 0, 0, 0 };
michael@0 534
michael@0 535 device->SetVertexShader(NULL);
michael@0 536 device->SetVertexShaderConstantF(0, dummyConst, 1);
michael@0 537 device->SetPixelShader(NULL);
michael@0 538 device->SetPixelShaderConstantF(0, dummyConst, 1);
michael@0 539
michael@0 540 D3DVIEWPORT9 dummyVp;
michael@0 541 dummyVp.X = 0;
michael@0 542 dummyVp.Y = 0;
michael@0 543 dummyVp.Width = 1;
michael@0 544 dummyVp.Height = 1;
michael@0 545 dummyVp.MinZ = 0;
michael@0 546 dummyVp.MaxZ = 1;
michael@0 547
michael@0 548 device->SetViewport(&dummyVp);
michael@0 549
michael@0 550 device->SetTexture(0, NULL);
michael@0 551
michael@0 552 device->SetStreamSource(0, mQuadVertexBuffer, 0, 0);
michael@0 553
michael@0 554 device->SetVertexDeclaration(mQuadVertexDeclaration);
michael@0 555
michael@0 556 hr = device->EndStateBlock(&mSavedStateBlock);
michael@0 557 ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
michael@0 558 }
michael@0 559
michael@0 560 ASSERT(mSavedStateBlock != NULL);
michael@0 561
michael@0 562 if (mSavedStateBlock != NULL)
michael@0 563 {
michael@0 564 hr = mSavedStateBlock->Capture();
michael@0 565 ASSERT(SUCCEEDED(hr));
michael@0 566 }
michael@0 567 }
michael@0 568
michael@0 569 void Blit::restoreState()
michael@0 570 {
michael@0 571 IDirect3DDevice9 *device = mRenderer->getDevice();
michael@0 572
michael@0 573 device->SetDepthStencilSurface(mSavedDepthStencil);
michael@0 574 if (mSavedDepthStencil != NULL)
michael@0 575 {
michael@0 576 mSavedDepthStencil->Release();
michael@0 577 mSavedDepthStencil = NULL;
michael@0 578 }
michael@0 579
michael@0 580 device->SetRenderTarget(0, mSavedRenderTarget);
michael@0 581 if (mSavedRenderTarget != NULL)
michael@0 582 {
michael@0 583 mSavedRenderTarget->Release();
michael@0 584 mSavedRenderTarget = NULL;
michael@0 585 }
michael@0 586
michael@0 587 ASSERT(mSavedStateBlock != NULL);
michael@0 588
michael@0 589 if (mSavedStateBlock != NULL)
michael@0 590 {
michael@0 591 mSavedStateBlock->Apply();
michael@0 592 }
michael@0 593 }
michael@0 594
michael@0 595 }

mercurial