1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "Direct3DSwapChain8.hpp" 16 17 #include "Direct3DDevice8.hpp" 18 #include "Config.hpp" 19 #include "Configurator.hpp" 20 #include "Debug.hpp" 21 22 #include "FrameBufferDD.hpp" 23 #include "FrameBufferGDI.hpp" 24 25 namespace D3D8 26 { Direct3DSwapChain8(Direct3DDevice8 * device,D3DPRESENT_PARAMETERS * presentParameters)27 Direct3DSwapChain8::Direct3DSwapChain8(Direct3DDevice8 *device, D3DPRESENT_PARAMETERS *presentParameters) : device(device), presentParameters(*presentParameters) 28 { 29 frameBuffer = 0; 30 31 for(int i = 0; i < 3; i++) 32 { 33 backBuffer[i] = 0; 34 } 35 36 reset(presentParameters); 37 } 38 ~Direct3DSwapChain8()39 Direct3DSwapChain8::~Direct3DSwapChain8() 40 { 41 release(); 42 } 43 QueryInterface(const IID & iid,void ** object)44 long Direct3DSwapChain8::QueryInterface(const IID &iid, void **object) 45 { 46 TRACE(""); 47 48 if(iid == IID_IDirect3DSwapChain8 || 49 iid == IID_IUnknown) 50 { 51 AddRef(); 52 *object = this; 53 54 return S_OK; 55 } 56 57 *object = 0; 58 59 return NOINTERFACE(iid); 60 } 61 AddRef()62 unsigned long Direct3DSwapChain8::AddRef() 63 { 64 TRACE(""); 65 66 return Unknown::AddRef(); 67 } 68 Release()69 unsigned long Direct3DSwapChain8::Release() 70 { 71 TRACE(""); 72 73 return Unknown::Release(); 74 } 75 Present(const RECT * sourceRect,const RECT * destRect,HWND destWindowOverride,const RGNDATA * dirtyRegion)76 long Direct3DSwapChain8::Present(const RECT *sourceRect, const RECT *destRect, HWND destWindowOverride, const RGNDATA *dirtyRegion) 77 { 78 TRACE(""); 79 80 #if PERF_PROFILE 81 profiler.nextFrame(); 82 #endif 83 84 if(!sourceRect && !destRect) // FIXME: More cases? 85 { 86 frameBuffer->flip(destWindowOverride, backBuffer[0]); 87 } 88 else // TODO: Check for SWAPEFFECT_COPY 89 { 90 sw::Rect sRect(0, 0, 0, 0); 91 sw::Rect dRect(0, 0, 0, 0); 92 93 if(sourceRect) 94 { 95 sRect.x0 = sourceRect->left; 96 sRect.y0 = sourceRect->top; 97 sRect.x1 = sourceRect->right; 98 sRect.y1 = sourceRect->bottom; 99 } 100 101 if(destRect) 102 { 103 dRect.x0 = destRect->left; 104 dRect.y0 = destRect->top; 105 dRect.x1 = destRect->right; 106 dRect.y1 = destRect->bottom; 107 } 108 109 frameBuffer->blit(destWindowOverride, backBuffer[0], sourceRect ? &sRect : nullptr, destRect ? &dRect : nullptr); 110 } 111 112 return D3D_OK; 113 } 114 GetBackBuffer(unsigned int index,D3DBACKBUFFER_TYPE type,IDirect3DSurface8 ** backBuffer)115 long Direct3DSwapChain8::GetBackBuffer(unsigned int index, D3DBACKBUFFER_TYPE type, IDirect3DSurface8 **backBuffer) 116 { 117 TRACE(""); 118 119 if(!backBuffer/* || type != D3DBACKBUFFER_TYPE_MONO*/) 120 { 121 return INVALIDCALL(); 122 } 123 124 if(index >= 3 || this->backBuffer[index] == 0) 125 { 126 return INVALIDCALL(); 127 } 128 129 this->backBuffer[index]->AddRef(); 130 *backBuffer = this->backBuffer[index]; 131 132 return D3D_OK; 133 } 134 reset(D3DPRESENT_PARAMETERS * presentParameters)135 void Direct3DSwapChain8::reset(D3DPRESENT_PARAMETERS *presentParameters) 136 { 137 release(); 138 139 this->presentParameters = *presentParameters; 140 141 ASSERT(presentParameters->BackBufferCount <= 3); // Maximum of three back buffers 142 143 if(presentParameters->BackBufferCount == 0) 144 { 145 presentParameters->BackBufferCount = 1; 146 } 147 148 D3DDEVICE_CREATION_PARAMETERS creationParameters; 149 device->GetCreationParameters(&creationParameters); 150 151 HWND windowHandle = presentParameters->hDeviceWindow ? presentParameters->hDeviceWindow : creationParameters.hFocusWindow; 152 153 int width = 0; 154 int height = 0; 155 156 if(presentParameters->Windowed && (presentParameters->BackBufferHeight == 0 || presentParameters->BackBufferWidth == 0)) 157 { 158 RECT rectangle; 159 GetClientRect(windowHandle, &rectangle); 160 161 width = rectangle.right - rectangle.left; 162 height = rectangle.bottom - rectangle.top; 163 } 164 else 165 { 166 width = presentParameters->BackBufferWidth; 167 height = presentParameters->BackBufferHeight; 168 } 169 170 frameBuffer = createFrameBufferWin(windowHandle, presentParameters->BackBufferWidth, presentParameters->BackBufferHeight, presentParameters->Windowed == FALSE, true); 171 172 lockable = presentParameters->Flags & D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; 173 174 backBuffer[0] = 0; 175 backBuffer[1] = 0; 176 backBuffer[2] = 0; 177 178 for(int i = 0; i < (int)presentParameters->BackBufferCount; i++) 179 { 180 backBuffer[i] = new Direct3DSurface8(device, this, width, height, presentParameters->BackBufferFormat, D3DPOOL_DEFAULT, presentParameters->MultiSampleType, lockable, D3DUSAGE_RENDERTARGET); 181 backBuffer[i]->bind(); 182 } 183 } 184 release()185 void Direct3DSwapChain8::release() 186 { 187 delete frameBuffer; 188 frameBuffer = 0; 189 190 for(int i = 0; i < 3; i++) 191 { 192 if(backBuffer[i]) 193 { 194 backBuffer[i]->unbind(); 195 backBuffer[i] = 0; 196 } 197 } 198 } 199 screenshot(void * destBuffer)200 void Direct3DSwapChain8::screenshot(void *destBuffer) 201 { 202 frameBuffer->screenshot(destBuffer); 203 } 204 setGammaRamp(sw::GammaRamp * gammaRamp,bool calibrate)205 void Direct3DSwapChain8::setGammaRamp(sw::GammaRamp *gammaRamp, bool calibrate) 206 { 207 frameBuffer->setGammaRamp(gammaRamp, calibrate); 208 } 209 getGammaRamp(sw::GammaRamp * gammaRamp)210 void Direct3DSwapChain8::getGammaRamp(sw::GammaRamp *gammaRamp) 211 { 212 frameBuffer->getGammaRamp(gammaRamp); 213 } 214 lockBackBuffer(int index)215 void *Direct3DSwapChain8::lockBackBuffer(int index) 216 { 217 return backBuffer[index]->lockInternal(0, 0, 0, sw::LOCK_READWRITE, sw::PUBLIC); // FIXME: External 218 } 219 unlockBackBuffer(int index)220 void Direct3DSwapChain8::unlockBackBuffer(int index) 221 { 222 backBuffer[index]->unlockInternal(); // FIXME: External 223 } 224 } 225