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