10bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens// 30bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// Licensed under the Apache License, Version 2.0 (the "License"); 40bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// you may not use this file except in compliance with the License. 50bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// You may obtain a copy of the License at 6ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens// 70bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// http://www.apache.org/licenses/LICENSE-2.0 8ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens// 90bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// Unless required by applicable law or agreed to in writing, software 100bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// distributed under the License is distributed on an "AS IS" BASIS, 110bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 120bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// See the License for the specific language governing permissions and 130bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// limitations under the License. 14ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 15ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens#include "Direct3DSwapChain9.hpp" 16ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 17ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens#include "Direct3DDevice9.hpp" 18ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens#include "Renderer.hpp" 19ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens#include "Timer.hpp" 20ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens#include "Resource.hpp" 21ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens#include "Configurator.hpp" 22ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens#include "Debug.hpp" 23ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 24ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens#include "FrameBufferDD.hpp" 25ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens#include "FrameBufferGDI.hpp" 26ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 27ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capensnamespace D3D9 28ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens{ 29ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens Direct3DSwapChain9::Direct3DSwapChain9(Direct3DDevice9 *device, D3DPRESENT_PARAMETERS *presentParameters) : device(device), presentParameters(*presentParameters) 30ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 31ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens frameBuffer = 0; 32ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 33ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens for(int i = 0; i < 3; i++) 34ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 35ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens backBuffer[i] = 0; 36ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 37ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 38ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens reset(presentParameters); 39ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 40ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 41ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens Direct3DSwapChain9::~Direct3DSwapChain9() 42ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 43ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens release(); 44ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 45ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 46ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens long Direct3DSwapChain9::QueryInterface(const IID &iid, void **object) 47ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 48ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens CriticalSection cs(device); 49ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 50ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens TRACE(""); 51ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 52ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens if(iid == IID_IDirect3DSwapChain9 || 53ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens iid == IID_IUnknown) 54ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 55ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens AddRef(); 56ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens *object = this; 57ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 58ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens return S_OK; 59ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 60ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 61ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens *object = 0; 62ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 63ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens return NOINTERFACE(iid); 64ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 65ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 66ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens unsigned long Direct3DSwapChain9::AddRef() 67ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 68ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens TRACE(""); 69ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 70ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens return Unknown::AddRef(); 71ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 72ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 73ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens unsigned long Direct3DSwapChain9::Release() 74ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 75ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens TRACE(""); 76ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 77ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens return Unknown::Release(); 78ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 79ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 80ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens long Direct3DSwapChain9::Present(const RECT *sourceRect, const RECT *destRect, HWND destWindowOverride, const RGNDATA *dirtyRegion, unsigned long flags) 81ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 82ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens CriticalSection cs(device); 83ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 84ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens TRACE(""); 85ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 86ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens #if PERF_PROFILE 87ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens profiler.nextFrame(); 88ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens #endif 89ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 90ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens #if PERF_HUD 91ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens sw::Renderer *renderer = device->renderer; 92ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 93ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens static int64_t frame = sw::Timer::ticks(); 94ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 95ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens int64_t frameTime = sw::Timer::ticks() - frame; 96ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens frame = sw::Timer::ticks(); 97ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 98ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens if(frameTime > 0) 99ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 100ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens unsigned int *frameBuffer = (unsigned int*)lockBackBuffer(0); // FIXME: Don't assume A8R8G8B8 mode 101ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens unsigned int stride = backBuffer[0]->getInternalPitchP(); 102ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 103ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens int thread; 104ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens for(thread = 0; thread < renderer->getThreadCount(); thread++) 105ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 106ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens int64_t drawTime = renderer->getVertexTime(thread) + renderer->getSetupTime(thread) + renderer->getPixelTime(thread); 107ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 108ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens int vertexPercentage = sw::clamp((int)(100 * renderer->getVertexTime(thread) / frameTime), 0, 100); 109ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens int setupPercentage = sw::clamp((int)(100 * renderer->getSetupTime(thread) / frameTime), 0, 100); 110ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens int pixelPercentage = sw::clamp((int)(100 * renderer->getPixelTime(thread) / frameTime), 0, 100); 111ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 112ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens for(int i = 0; i < 100; i++) 113ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 114ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens frameBuffer[thread * stride + i] = 0x00000000; 115ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 116ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 117ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens unsigned int *buffer = frameBuffer; 118ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 119ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens for(int i = 0; i < vertexPercentage; i++) 120ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 121ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens buffer[thread * stride] = 0x000000FF; 122ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens buffer++; 123ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 124ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 125ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens for(int i = 0; i < setupPercentage; i++) 126ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 127ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens buffer[thread * stride] = 0x0000FF00; 128ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens buffer++; 129ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 130ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 131ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens for(int i = 0; i < pixelPercentage; i++) 132ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 133ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens buffer[thread * stride] = 0x00FF0000; 134ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens buffer++; 135ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 136ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 137ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens frameBuffer[thread * stride + 100] = 0x00FFFFFF; 138ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 139ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 140ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens for(int i = 0; i <= 100; i++) 141ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 142ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens frameBuffer[thread * stride + i] = 0x00FFFFFF; 143ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 144ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 145ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens unlockBackBuffer(0); 146ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 147ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 148ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens renderer->resetTimers(); 149ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens #endif 150ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 151ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens HWND window = destWindowOverride ? destWindowOverride : presentParameters.hDeviceWindow; 152ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 153ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens POINT point; 154ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens GetCursorPos(&point); 155ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens ScreenToClient(window, &point); 156ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 157ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens frameBuffer->setCursorPosition(point.x, point.y); 158ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 159ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens if(!sourceRect && !destRect) // FIXME: More cases? 160ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 161241f789c783201a64127b7f28fea89db18c2609cNicolas Capens frameBuffer->flip(window, backBuffer[0]); 162ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 163ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens else // FIXME: Check for SWAPEFFECT_COPY 164ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 16566839438a7ed306493ed2b8721d197cd3663c67aNicolas Capens sw::Rect sRect(0, 0, 0, 0); 16666839438a7ed306493ed2b8721d197cd3663c67aNicolas Capens sw::Rect dRect(0, 0, 0, 0); 167ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 168ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens if(sourceRect) 169ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 17066839438a7ed306493ed2b8721d197cd3663c67aNicolas Capens sRect.x0 = sourceRect->left; 17166839438a7ed306493ed2b8721d197cd3663c67aNicolas Capens sRect.y0 = sourceRect->top; 17266839438a7ed306493ed2b8721d197cd3663c67aNicolas Capens sRect.x1 = sourceRect->right; 17366839438a7ed306493ed2b8721d197cd3663c67aNicolas Capens sRect.y1 = sourceRect->bottom; 174ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 175ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 176ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens if(destRect) 177ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 17866839438a7ed306493ed2b8721d197cd3663c67aNicolas Capens dRect.x0 = destRect->left; 17966839438a7ed306493ed2b8721d197cd3663c67aNicolas Capens dRect.y0 = destRect->top; 18066839438a7ed306493ed2b8721d197cd3663c67aNicolas Capens dRect.x1 = destRect->right; 18166839438a7ed306493ed2b8721d197cd3663c67aNicolas Capens dRect.y1 = destRect->bottom; 182ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 183ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 184241f789c783201a64127b7f28fea89db18c2609cNicolas Capens frameBuffer->blit(window, backBuffer[0], sourceRect ? &sRect : nullptr, destRect ? &dRect : nullptr); 185ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 186ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 187ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens return D3D_OK; 188ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 189ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 190ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens long Direct3DSwapChain9::GetFrontBufferData(IDirect3DSurface9 *destSurface) 191ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 192ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens CriticalSection cs(device); 193ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 194ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens TRACE(""); 195ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 196ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens if(!destSurface) 197ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 198ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens return INVALIDCALL(); 199ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 2000bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 201ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens sw::Surface *dest = static_cast<Direct3DSurface9*>(destSurface); 202ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens void *buffer = dest->lockExternal(0, 0, 0, sw::LOCK_WRITEONLY, sw::PRIVATE); 203ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 204ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens frameBuffer->screenshot(buffer); 205ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 206ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens dest->unlockExternal(); 2070bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 208ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens return D3D_OK; 209ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 210ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 211ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens long Direct3DSwapChain9::GetBackBuffer(unsigned int index, D3DBACKBUFFER_TYPE type, IDirect3DSurface9 **backBuffer) 212ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 213ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens CriticalSection cs(device); 214ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 215ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens TRACE(""); 216ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 217ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens if(!backBuffer/* || type != D3DBACKBUFFER_TYPE_MONO*/) 218ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 219ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens return INVALIDCALL(); 220ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 221ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 222ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens *backBuffer = 0; 223ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 224ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens if(index >= 3 || this->backBuffer[index] == 0) 225ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 226ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens return INVALIDCALL(); 227ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 228ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 229ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens *backBuffer = this->backBuffer[index]; 230ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens this->backBuffer[index]->AddRef(); 231ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 232ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens return D3D_OK; 233ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 234ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 235ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens long Direct3DSwapChain9::GetRasterStatus(D3DRASTER_STATUS *rasterStatus) 236ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 237ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens CriticalSection cs(device); 238ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 239ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens TRACE(""); 240ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 241ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens if(!rasterStatus) 242ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 243ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens return INVALIDCALL(); 244ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 245ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 246ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens bool inVerticalBlank; 247ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens unsigned int scanline; 248ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens bool supported = frameBuffer->getScanline(inVerticalBlank, scanline); 249ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 250ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens if(supported) 251ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 252ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens rasterStatus->InVBlank = inVerticalBlank; 253ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens rasterStatus->ScanLine = scanline; 254ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 255ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens else 256ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 257ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens return INVALIDCALL(); 258ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 259ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 260ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens return D3D_OK; 261ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 262ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 263ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens long Direct3DSwapChain9::GetDisplayMode(D3DDISPLAYMODE *displayMode) 264ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 265ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens CriticalSection cs(device); 266ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 267ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens TRACE(""); 268ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 269ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens if(!displayMode) 270ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 271ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens return INVALIDCALL(); 272ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 273ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 274ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens device->getAdapterDisplayMode(D3DADAPTER_DEFAULT, displayMode); 275ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 276ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens return D3D_OK; 277ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 278ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 279ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens long Direct3DSwapChain9::GetDevice(IDirect3DDevice9 **device) 280ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 281ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens CriticalSection cs(this->device); 282ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 283ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens TRACE(""); 284ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 285ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens if(!device) 286ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 287ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens return INVALIDCALL(); 288ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 289ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 290ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens this->device->AddRef(); 291ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens *device = this->device; 292ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 293ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens return D3D_OK; 294ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 295ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 296ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens long Direct3DSwapChain9::GetPresentParameters(D3DPRESENT_PARAMETERS *presentParameters) 297ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 298ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens CriticalSection cs(device); 299ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 300ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens TRACE(""); 301ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 302ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens if(!presentParameters) 303ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 304ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens return INVALIDCALL(); 305ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 306ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 307ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens *presentParameters = this->presentParameters; 308ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 309ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens return D3D_OK; 310ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 311ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 312ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens void Direct3DSwapChain9::reset(D3DPRESENT_PARAMETERS *presentParameters) 313ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 314ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens release(); 315ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 316ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens ASSERT(presentParameters->BackBufferCount <= 3); // Maximum of three back buffers 317ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 318ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens if(presentParameters->BackBufferCount == 0) 319ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 320ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens presentParameters->BackBufferCount = 1; 321ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 322ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 323ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens if(presentParameters->BackBufferFormat == D3DFMT_UNKNOWN) 324ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 325ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens D3DDISPLAYMODE displayMode; 326ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens GetDisplayMode(&displayMode); 327ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 328ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens presentParameters->BackBufferFormat = displayMode.Format; 329ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 330ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 331ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens D3DDEVICE_CREATION_PARAMETERS creationParameters; 332ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens device->GetCreationParameters(&creationParameters); 333ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 334ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens HWND windowHandle = presentParameters->hDeviceWindow ? presentParameters->hDeviceWindow : creationParameters.hFocusWindow; 335ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 336ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens if(presentParameters->Windowed && (presentParameters->BackBufferHeight == 0 || presentParameters->BackBufferWidth == 0)) 337ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 338ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens RECT rectangle; 339ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens GetClientRect(windowHandle, &rectangle); 340ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 341ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens presentParameters->BackBufferWidth = rectangle.right - rectangle.left; 342ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens presentParameters->BackBufferHeight = rectangle.bottom - rectangle.top; 343ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 344ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 34566839438a7ed306493ed2b8721d197cd3663c67aNicolas Capens frameBuffer = createFrameBufferWin(windowHandle, presentParameters->BackBufferWidth, presentParameters->BackBufferHeight, presentParameters->Windowed == FALSE, true); 346ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 34766839438a7ed306493ed2b8721d197cd3663c67aNicolas Capens lockable = presentParameters->Flags & D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; 348ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 349ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens backBuffer[0] = 0; 350ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens backBuffer[1] = 0; 351ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens backBuffer[2] = 0; 352ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 353ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens for(int i = 0; i < (int)presentParameters->BackBufferCount; i++) 354ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 355ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens backBuffer[i] = new Direct3DSurface9(device, this, presentParameters->BackBufferWidth, presentParameters->BackBufferHeight, presentParameters->BackBufferFormat, D3DPOOL_DEFAULT, presentParameters->MultiSampleType, presentParameters->MultiSampleQuality, lockable, D3DUSAGE_RENDERTARGET); 356ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens backBuffer[i]->bind(); 357ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 358ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 359ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens this->presentParameters = *presentParameters; 360ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 361ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 362ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens void Direct3DSwapChain9::release() 363ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 364ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens delete frameBuffer; 365ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens frameBuffer = 0; 366ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 367ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens for(int i = 0; i < 3; i++) 368ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 369ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens if(backBuffer[i]) 370ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 371ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens backBuffer[i]->unbind(); 372ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens backBuffer[i] = 0; 373ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 374ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 375ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 376ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 377ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens void Direct3DSwapChain9::setGammaRamp(sw::GammaRamp *gammaRamp, bool calibrate) 378ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 379ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens frameBuffer->setGammaRamp(gammaRamp, calibrate); 380ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 381ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 382ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens void Direct3DSwapChain9::getGammaRamp(sw::GammaRamp *gammaRamp) 383ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 384ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens frameBuffer->getGammaRamp(gammaRamp); 385ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 386ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens 387ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens void *Direct3DSwapChain9::lockBackBuffer(int index) 388ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 389ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens return backBuffer[index]->lockInternal(0, 0, 0, sw::LOCK_READWRITE, sw::PUBLIC); // FIXME: External 390ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 3910bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 392ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens void Direct3DSwapChain9::unlockBackBuffer(int index) 393ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens { 394ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens backBuffer[index]->unlockInternal(); // FIXME: External 395ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens } 396ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens} 397