1a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// 2a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. 3a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// Use of this source code is governed by a BSD-style license that can be 4a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// found in the LICENSE file. 5a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// 6a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 7a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// Blit.cpp: Surface copy utility class. 8a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 9a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block#include "libGLESv2/Blit.h" 10a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 11a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block#include <d3dx9.h> 12a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 13a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block#include "common/debug.h" 14a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 15a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block#include "libGLESv2/main.h" 16a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 17a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blocknamespace 18a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 19a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// Standard Vertex Shader 20a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// Input 0 is the homogenous position. 21a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// Outputs the homogenous position as-is. 22a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// Outputs a tex coord with (0,0) in the upper-left corner of the screen and (1,1) in the bottom right. 23a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// C0.X must be negative half-pixel width, C0.Y must be half-pixel height. C0.ZW must be 0. 24a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockconst char standardvs[] = 25a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"struct VS_OUTPUT\n" 26a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"{\n" 27a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block" float4 position : POSITION;\n" 28a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block" float4 texcoord : TEXCOORD0;\n" 29a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"};\n" 30a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"\n" 31a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"uniform float4 halfPixelSize : c0;\n" 32a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"\n" 33a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"VS_OUTPUT main(in float4 position : POSITION)\n" 34a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"{\n" 35a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block" VS_OUTPUT Out;\n" 36a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"\n" 37a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block" Out.position = position + halfPixelSize;\n" 38a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block" Out.texcoord = position * float4(0.5, -0.5, 1.0, 1.0) + float4(0.5, 0.5, 0, 0);\n" 39a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"\n" 40a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block" return Out;\n" 41a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"}\n"; 42a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 43a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// Flip Y Vertex Shader 44a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// Input 0 is the homogenous position. 45a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// Outputs the homogenous position as-is. 46a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// Outputs a tex coord with (0,1) in the upper-left corner of the screen and (1,0) in the bottom right. 47a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// C0.XY must be the half-pixel width and height. C0.ZW must be 0. 48a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockconst char flipyvs[] = 49a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"struct VS_OUTPUT\n" 50a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"{\n" 51a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block" float4 position : POSITION;\n" 52a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block" float4 texcoord : TEXCOORD0;\n" 53a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"};\n" 54a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"\n" 55a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"uniform float4 halfPixelSize : c0;\n" 56a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"\n" 57a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"VS_OUTPUT main(in float4 position : POSITION)\n" 58a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"{\n" 59a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block" VS_OUTPUT Out;\n" 60a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"\n" 61a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block" Out.position = position + halfPixelSize;\n" 62a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block" Out.texcoord = position * float4(0.5, 0.5, 1.0, 1.0) + float4(0.5, 0.5, 0, 0);\n" 63a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"\n" 64a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block" return Out;\n" 65a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"}\n"; 66a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 67a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// Passthrough Pixel Shader 68a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// Outputs texture 0 sampled at texcoord 0. 69a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockconst char passthroughps[] = 70a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"sampler2D tex : s0;\n" 71a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"\n" 72a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"float4 main(float4 texcoord : TEXCOORD0) : COLOR\n" 73a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"{\n" 74a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block" return tex2D(tex, texcoord.xy);\n" 75a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"}\n"; 76a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 77a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// Luminance Conversion Pixel Shader 78a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// Outputs sample(tex0, tc0).rrra. 79a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// For LA output (pass A) set C0.X = 1, C0.Y = 0. 80a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// For L output (A = 1) set C0.X = 0, C0.Y = 1. 81a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockconst char luminanceps[] = 82a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"sampler2D tex : s0;\n" 83a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"\n" 84a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"uniform float4 mode : c0;\n" 85a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"\n" 86a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"float4 main(float4 texcoord : TEXCOORD0) : COLOR\n" 87a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"{\n" 88a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block" float4 tmp = tex2D(tex, texcoord.xy);\n" 89a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block" tmp.w = tmp.w * mode.x + mode.y;\n" 90a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block" return tmp.xxxw;\n" 91a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"}\n"; 92a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 93a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// RGB/A Component Mask Pixel Shader 94a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// Outputs sample(tex0, tc0) with options to force RGB = 0 and/or A = 1. 95a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// To force RGB = 0, set C0.X = 0, otherwise C0.X = 1. 96a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// To force A = 1, set C0.Z = 0, C0.W = 1, otherwise C0.Z = 1, C0.W = 0. 97a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockconst char componentmaskps[] = 98a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"sampler2D tex : s0;\n" 99a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"\n" 100a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"uniform float4 mode : c0;\n" 101a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"\n" 102a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"float4 main(float4 texcoord : TEXCOORD0) : COLOR\n" 103a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"{\n" 104a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block" float4 tmp = tex2D(tex, texcoord.xy);\n" 105a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block" tmp.xyz = tmp.xyz * mode.x;\n" 106a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block" tmp.w = tmp.w * mode.z + mode.w;\n" 107a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block" return tmp;\n" 108a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block"}\n"; 109a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 110a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 111a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 112a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blocknamespace gl 113a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 114a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 115a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockconst char * const Blit::mShaderSource[] = 116a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 117a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block standardvs, 118a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block flipyvs, 119a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block passthroughps, 120a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block luminanceps, 121a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block componentmaskps 122a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block}; 123a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 124a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve BlockBlit::Blit(Context *context) 125a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block : mContext(context), mQuadVertexBuffer(NULL), mQuadVertexDeclaration(NULL), mSavedRenderTarget(NULL), mSavedDepthStencil(NULL), mSavedStateBlock(NULL) 126a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 127a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block initGeometry(); 128a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block memset(mCompiledShaders, 0, sizeof(mCompiledShaders)); 129a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 130a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 131a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve BlockBlit::~Blit() 132a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 133a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (mSavedStateBlock) mSavedStateBlock->Release(); 134a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (mQuadVertexBuffer) mQuadVertexBuffer->Release(); 135a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (mQuadVertexDeclaration) mQuadVertexDeclaration->Release(); 136a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 137a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block for (int i = 0; i < SHADER_COUNT; i++) 138a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 139a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (mCompiledShaders[i]) 140a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 141a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mCompiledShaders[i]->Release(); 142a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 143a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 144a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 145a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 146a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockvoid Blit::initGeometry() 147a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 148a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block static const float quad[] = 149a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 150a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block -1, -1, 151a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block -1, 1, 152a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 1, -1, 153a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 1, 1 154a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block }; 155a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 156a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block IDirect3DDevice9 *device = getDevice(); 157a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 158a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block HRESULT hr = device->CreateVertexBuffer(sizeof(quad), D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &mQuadVertexBuffer, NULL); 159a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 160a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (FAILED(hr)) 161a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 162a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); 163a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return error(GL_OUT_OF_MEMORY); 164a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 165a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 166a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block void *lockPtr; 167a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mQuadVertexBuffer->Lock(0, 0, &lockPtr, 0); 168a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block memcpy(lockPtr, quad, sizeof(quad)); 169a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mQuadVertexBuffer->Unlock(); 170a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 171a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block static const D3DVERTEXELEMENT9 elements[] = 172a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 173a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, 174a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block D3DDECL_END() 175a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block }; 176a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 177a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block hr = device->CreateVertexDeclaration(elements, &mQuadVertexDeclaration); 178a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (FAILED(hr)) 179a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 180a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); 181a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return error(GL_OUT_OF_MEMORY); 182a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 183a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 184a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 185a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blocktemplate <class D3DShaderType> 186a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockbool Blit::setShader(ShaderId source, const char *profile, 187a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block HRESULT (WINAPI IDirect3DDevice9::*createShader)(const DWORD *, D3DShaderType**), 188a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType*)) 189a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 190a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block IDirect3DDevice9 *device = getDevice(); 191a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 192a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block D3DShaderType *shader; 193a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 194a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (mCompiledShaders[source] != NULL) 195a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 196a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block shader = static_cast<D3DShaderType*>(mCompiledShaders[source]); 197a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 198a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block else 199a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 200a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ID3DXBuffer *shaderCode; 201a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block HRESULT hr = D3DXCompileShader(mShaderSource[source], strlen(mShaderSource[source]), NULL, NULL, "main", profile, 0, &shaderCode, NULL, NULL); 202a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 203a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (FAILED(hr)) 204a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 205a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ERR("Failed to compile %s shader for blit operation %d, error 0x%08X.", profile, (int)source, hr); 206a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return false; 207a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 208a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 209a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block hr = (device->*createShader)(static_cast<const DWORD*>(shaderCode->GetBufferPointer()), &shader); 210a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (FAILED(hr)) 211a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 212a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block shaderCode->Release(); 213a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ERR("Failed to create %s shader for blit operation %d, error 0x%08X.", profile, (int)source, hr); 214a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return false; 215a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 216a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 217a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block shaderCode->Release(); 218a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 219a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mCompiledShaders[source] = shader; 220a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 221a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 222a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block HRESULT hr = (device->*setShader)(shader); 223a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 224a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (FAILED(hr)) 225a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 226a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ERR("Failed to set %s shader for blit operation %d, error 0x%08X.", profile, (int)source, hr); 227a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return false; 228a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 229a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 230a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return true; 231a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 232a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 233a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockbool Blit::setVertexShader(ShaderId shader) 234a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 2355abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return setShader<IDirect3DVertexShader9>(shader, mContext->supportsShaderModel3() ? "vs_3_0" : "vs_2_0", &IDirect3DDevice9::CreateVertexShader, &IDirect3DDevice9::SetVertexShader); 236a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 237a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 238a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockbool Blit::setPixelShader(ShaderId shader) 239a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 2405abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return setShader<IDirect3DPixelShader9>(shader, mContext->supportsShaderModel3() ? "ps_3_0" : "ps_2_0", &IDirect3DDevice9::CreatePixelShader, &IDirect3DDevice9::SetPixelShader); 241a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 242a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 243a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve BlockRECT Blit::getSurfaceRect(IDirect3DSurface9 *surface) const 244a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 245a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block D3DSURFACE_DESC desc; 246a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block surface->GetDesc(&desc); 247a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 248a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block RECT rect; 249a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block rect.left = 0; 250a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block rect.top = 0; 251a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block rect.right = desc.Width; 252a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block rect.bottom = desc.Height; 253a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 254a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return rect; 255a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 256a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 257a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockbool Blit::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest) 258a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 259a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block IDirect3DTexture9 *texture = copySurfaceToTexture(source, getSurfaceRect(source)); 260a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (!texture) 261a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 262a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return false; 263a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 264a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 265a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block IDirect3DDevice9 *device = getDevice(); 266a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 267a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block saveState(); 268a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 269a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetTexture(0, texture); 270a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetRenderTarget(0, dest); 271a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 272a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block setVertexShader(SHADER_VS_STANDARD); 273a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block setPixelShader(SHADER_PS_PASSTHROUGH); 274a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 275a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block setCommonBlitState(); 276a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); 277a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); 278a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 279a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block setViewport(getSurfaceRect(dest), 0, 0); 280a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 281a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block render(); 282a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 283a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block texture->Release(); 284a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 285a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block restoreState(); 286a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 287a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return true; 288a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 289a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 290a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockbool Blit::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest) 291a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 292a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block IDirect3DTexture9 *texture = copySurfaceToTexture(source, sourceRect); 293a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (!texture) 294a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 295a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return false; 296a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 297a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 298a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block IDirect3DDevice9 *device = getDevice(); 299a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 300a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block saveState(); 301a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 302a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetTexture(0, texture); 303a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetRenderTarget(0, dest); 304a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 305a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block setViewport(sourceRect, xoffset, yoffset); 306a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 307a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block setCommonBlitState(); 308a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (setFormatConvertShaders(destFormat)) 309a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 310a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block render(); 311a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 312a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 313a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block texture->Release(); 314a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 315a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block restoreState(); 316a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 317a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return true; 318a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 319a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 320a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockbool Blit::setFormatConvertShaders(GLenum destFormat) 321a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 322a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block bool okay = setVertexShader(SHADER_VS_STANDARD); 323a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 324a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block switch (destFormat) 325a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 326a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block default: UNREACHABLE(); 327a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case GL_RGBA: 3285abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick case GL_BGRA_EXT: 329a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case GL_RGB: 330a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case GL_ALPHA: 331a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block okay = okay && setPixelShader(SHADER_PS_COMPONENTMASK); 332a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block break; 333a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 334a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case GL_LUMINANCE: 335a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case GL_LUMINANCE_ALPHA: 336a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block okay = okay && setPixelShader(SHADER_PS_LUMINANCE); 337a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block break; 338a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 339a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 340a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (!okay) 341a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 342a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return false; 343a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 344a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 345a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block enum { X = 0, Y = 1, Z = 2, W = 3 }; 346a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 347a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // The meaning of this constant depends on the shader that was selected. 348a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // See the shader assembly code above for details. 349a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block float psConst0[4] = { 0, 0, 0, 0 }; 350a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 351a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block switch (destFormat) 352a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 353a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block default: UNREACHABLE(); 354a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case GL_RGBA: 3555abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick case GL_BGRA_EXT: 356a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block psConst0[X] = 1; 357a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block psConst0[Z] = 1; 358a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block break; 359a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 360a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case GL_RGB: 361a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block psConst0[X] = 1; 362a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block psConst0[W] = 1; 363a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block break; 364a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 365a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case GL_ALPHA: 366a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block psConst0[Z] = 1; 367a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block break; 368a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 369a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case GL_LUMINANCE: 370a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block psConst0[Y] = 1; 371a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block break; 372a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 373a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case GL_LUMINANCE_ALPHA: 374a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block psConst0[X] = 1; 375a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block break; 376a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 377a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 378a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block getDevice()->SetPixelShaderConstantF(0, psConst0, 1); 379a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 380a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return true; 381a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 382a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 383a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve BlockIDirect3DTexture9 *Blit::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect) 384a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 385ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (!surface) 386ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch { 387ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return NULL; 388ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch } 389ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 390a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block egl::Display *display = getDisplay(); 391a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block IDirect3DDevice9 *device = getDevice(); 392a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 393a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block D3DSURFACE_DESC sourceDesc; 394a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block surface->GetDesc(&sourceDesc); 395a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 396a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // Copy the render target into a texture 397a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block IDirect3DTexture9 *texture; 398a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block HRESULT result = device->CreateTexture(sourceRect.right - sourceRect.left, sourceRect.bottom - sourceRect.top, 1, D3DUSAGE_RENDERTARGET, sourceDesc.Format, D3DPOOL_DEFAULT, &texture, NULL); 399a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 400a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (FAILED(result)) 401a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 402a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); 403a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL); 404a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 405a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 406a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block IDirect3DSurface9 *textureSurface; 407a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block result = texture->GetSurfaceLevel(0, &textureSurface); 408a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 409a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (FAILED(result)) 410a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 411a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); 412a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block texture->Release(); 413a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL); 414a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 415a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 416a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block display->endScene(); 417ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch result = device->StretchRect(surface, &sourceRect, textureSurface, NULL, D3DTEXF_NONE); 418a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 419a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block textureSurface->Release(); 420a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 421a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (FAILED(result)) 422a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 423a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); 424a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block texture->Release(); 425a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL); 426a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 427a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 428a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return texture; 429a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 430a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 431a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockvoid Blit::setViewport(const RECT &sourceRect, GLint xoffset, GLint yoffset) 432a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 433a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block IDirect3DDevice9 *device = getDevice(); 434a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 435a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block D3DVIEWPORT9 vp; 436a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block vp.X = xoffset; 437a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block vp.Y = yoffset; 438a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block vp.Width = sourceRect.right - sourceRect.left; 439a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block vp.Height = sourceRect.bottom - sourceRect.top; 440a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block vp.MinZ = 0.0f; 441a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block vp.MaxZ = 1.0f; 442a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetViewport(&vp); 443a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 444a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block float halfPixelAdjust[4] = { -1.0f/vp.Width, 1.0f/vp.Height, 0, 0 }; 445a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetVertexShaderConstantF(0, halfPixelAdjust, 1); 446a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 447a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 448a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockvoid Blit::setCommonBlitState() 449a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 450a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block IDirect3DDevice9 *device = getDevice(); 451a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 452a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetDepthStencilSurface(NULL); 453a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 454a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); 455a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); 456a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); 457a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); 458a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0); 459a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED); 460a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE); 461a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); 462a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 463a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); 464a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); 465a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, FALSE); 466a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); 467a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); 468a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 469ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch RECT scissorRect = {0}; // Scissoring is disabled for flipping, but we need this to capture and restore the old rectangle 470ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch device->SetScissorRect(&scissorRect); 471a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 472a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 473a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockvoid Blit::render() 474a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 475a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block egl::Display *display = getDisplay(); 476a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block IDirect3DDevice9 *device = getDevice(); 477a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 478a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block HRESULT hr = device->SetStreamSource(0, mQuadVertexBuffer, 0, 2 * sizeof(float)); 479a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block hr = device->SetVertexDeclaration(mQuadVertexDeclaration); 480a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 481a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block display->startScene(); 482a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block hr = device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); 483a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 484a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 485a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockvoid Blit::saveState() 486a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 487a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block IDirect3DDevice9 *device = getDevice(); 488a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 489a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block HRESULT hr; 490a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 491a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->GetDepthStencilSurface(&mSavedDepthStencil); 492a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->GetRenderTarget(0, &mSavedRenderTarget); 493a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 494a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (mSavedStateBlock == NULL) 495a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 496a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block hr = device->BeginStateBlock(); 497a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); 498a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 499a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block setCommonBlitState(); 500a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 501a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block static const float dummyConst[4] = { 0, 0, 0, 0 }; 502a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 503a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetVertexShader(NULL); 504a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetVertexShaderConstantF(0, dummyConst, 1); 505a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetPixelShader(NULL); 506a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetPixelShaderConstantF(0, dummyConst, 1); 507a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 508a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block D3DVIEWPORT9 dummyVp; 509a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block dummyVp.X = 0; 510a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block dummyVp.Y = 0; 511a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block dummyVp.Width = 1; 512a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block dummyVp.Height = 1; 513a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block dummyVp.MinZ = 0; 514a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block dummyVp.MaxZ = 1; 515a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 516a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetViewport(&dummyVp); 517a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 518a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetTexture(0, NULL); 519a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 520a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetStreamSource(0, mQuadVertexBuffer, 0, 0); 521a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 522a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetVertexDeclaration(mQuadVertexDeclaration); 523a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 524a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block hr = device->EndStateBlock(&mSavedStateBlock); 525a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); 526a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 527a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 528a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(mSavedStateBlock != NULL); 529a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 530a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (mSavedStateBlock != NULL) 531a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 532a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block hr = mSavedStateBlock->Capture(); 533a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(SUCCEEDED(hr)); 534a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 535a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 536a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 537a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockvoid Blit::restoreState() 538a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 539a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block IDirect3DDevice9 *device = getDevice(); 540a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 541a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetDepthStencilSurface(mSavedDepthStencil); 542a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (mSavedDepthStencil != NULL) 543a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 544a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mSavedDepthStencil->Release(); 545a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mSavedDepthStencil = NULL; 546a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 547a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 548a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block device->SetRenderTarget(0, mSavedRenderTarget); 549a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (mSavedRenderTarget != NULL) 550a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 551a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mSavedRenderTarget->Release(); 552a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mSavedRenderTarget = NULL; 553a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 554a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 555a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(mSavedStateBlock != NULL); 556a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 557a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (mSavedStateBlock != NULL) 558a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 559a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mSavedStateBlock->Apply(); 560a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 561a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 562a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 563a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 564