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 "Direct3DSurface9.hpp"
16ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
17ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens#include "Direct3DDevice9.hpp"
18ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens#include "Direct3DBaseTexture9.hpp"
19ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens#include "Capabilities.hpp"
20ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens#include "Resource.hpp"
21ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens#include "Debug.hpp"
22ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
23ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens#include <malloc.h>
24ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens#include <assert.h>
25ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
26ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capensextern bool quadLayoutEnabled;
27ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
28ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capensnamespace D3D9
29ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens{
30ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	sw::Resource *getParentResource(Unknown *container)
31ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
32ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		Direct3DBaseTexture9 *baseTexture = dynamic_cast<Direct3DBaseTexture9*>(container);
33ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
34ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		if(baseTexture)
35ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
36ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			return baseTexture->getResource();
37ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
38ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
39ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		return 0;
40ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
41ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
42ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	int sampleCount(D3DMULTISAMPLE_TYPE multiSample, unsigned int quality)
43ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
44ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		if(multiSample == D3DMULTISAMPLE_NONMASKABLE)
45ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
46ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			switch(quality)
47ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			{
48ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			case 0: return 2;
49ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			case 1: return 4;
50ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			case 2: return 8;
51ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			case 3: return 16;
52ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			}
53ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
54ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		else if(multiSample == D3DMULTISAMPLE_2_SAMPLES)
55ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
56ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			return 2;
57ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
58ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		else if(multiSample == D3DMULTISAMPLE_4_SAMPLES)
59ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
60ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			return 4;
61ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
62ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		else if(multiSample == D3DMULTISAMPLE_8_SAMPLES)
63ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
64ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			return 8;
65ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
66ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		else if(multiSample == D3DMULTISAMPLE_16_SAMPLES)
67ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
68ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			return 16;
69ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
70ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
71ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		return 1;
72ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
73ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
74ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	bool isLockable(D3DPOOL pool, unsigned long usage, bool lockableOverride)
75ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
76ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		return (pool != D3DPOOL_DEFAULT) || (usage & D3DUSAGE_DYNAMIC) || lockableOverride;
77ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
78ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
799c6d52227bcdddbce7d206e9be38f719a95e7416Alexis Hetu	Direct3DSurface9::Direct3DSurface9(Direct3DDevice9 *device, Unknown *container, int width, int height, D3DFORMAT format, D3DPOOL pool, D3DMULTISAMPLE_TYPE multiSample, unsigned int quality, bool lockableOverride, unsigned long usage)
80bfa23b3f4de49586d2bd25efb77fa92734bd6f26Nicolas Capens		: Direct3DResource9(device, D3DRTYPE_SURFACE, pool, memoryUsage(width, height, multiSample, quality, format)), Surface(getParentResource(container), width, height, 1, 0, sampleCount(multiSample, quality), translateFormat(format), isLockable(pool, usage, lockableOverride), (usage & D3DUSAGE_RENDERTARGET) || (usage & D3DUSAGE_DEPTHSTENCIL)), container(container), width(width), height(height), format(format), pool(pool), multiSample(multiSample), quality(quality), lockable(isLockable(pool, usage, lockableOverride)), usage(usage)
81ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
82ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		parentTexture = dynamic_cast<Direct3DBaseTexture9*>(container);
83ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
84ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
85ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	Direct3DSurface9::~Direct3DSurface9()
86ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
87ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
88ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
893b9e1eab3544111f3f1ff8fc652d6548acb608baNicolas Capens	void *Direct3DSurface9::lockInternal(int x, int y, int z, sw::Lock lock, sw::Accessor client)
903b9e1eab3544111f3f1ff8fc652d6548acb608baNicolas Capens	{
913b9e1eab3544111f3f1ff8fc652d6548acb608baNicolas Capens		return Surface::lockInternal(x, y, z, lock, client);
923b9e1eab3544111f3f1ff8fc652d6548acb608baNicolas Capens	}
933b9e1eab3544111f3f1ff8fc652d6548acb608baNicolas Capens
943b9e1eab3544111f3f1ff8fc652d6548acb608baNicolas Capens	void Direct3DSurface9::unlockInternal()
953b9e1eab3544111f3f1ff8fc652d6548acb608baNicolas Capens	{
963b9e1eab3544111f3f1ff8fc652d6548acb608baNicolas Capens		Surface::unlockInternal();
973b9e1eab3544111f3f1ff8fc652d6548acb608baNicolas Capens	}
983b9e1eab3544111f3f1ff8fc652d6548acb608baNicolas Capens
99ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	long Direct3DSurface9::QueryInterface(const IID &iid, void **object)
100ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
101ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		CriticalSection cs(device);
102ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
103ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		TRACE("");
104ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
105ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		if(iid == IID_IDirect3DSurface9 ||
106ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		   iid == IID_IDirect3DResource9 ||
107ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		   iid == IID_IUnknown)
108ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
109ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			AddRef();
110ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			*object = this;
111ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
112ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			return S_OK;
113ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
114ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
115ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		*object = 0;
116ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
117ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		return NOINTERFACE(iid);
118ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
119ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
120ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	unsigned long Direct3DSurface9::AddRef()
121ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
122ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		TRACE("");
123ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
124ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		if(parentTexture)
125ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
126ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			return parentTexture->AddRef();
127ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
128ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
129ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		return Direct3DResource9::AddRef();
130ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
131ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
132ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	unsigned long Direct3DSurface9::Release()
133ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
134ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		TRACE("");
135ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
136ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		if(parentTexture)
137ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
138ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			return parentTexture->Release();
139ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
140ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
141ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		return Direct3DResource9::Release();
142ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
143ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
144ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	long Direct3DSurface9::FreePrivateData(const GUID &guid)
145ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
146ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		CriticalSection cs(device);
147ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
148ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		TRACE("");
149ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
150ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		return Direct3DResource9::FreePrivateData(guid);
151ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
152ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
153ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	long Direct3DSurface9::GetPrivateData(const GUID &guid, void *data, unsigned long *size)
154ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
155ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		CriticalSection cs(device);
156ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
157ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		TRACE("");
158ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
159ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		return Direct3DResource9::GetPrivateData(guid, data, size);
160ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
161ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
162ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	void Direct3DSurface9::PreLoad()
163ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
164ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		CriticalSection cs(device);
165ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
166ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		TRACE("");
167ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
168ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		Direct3DResource9::PreLoad();
169ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
170ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
171ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	long Direct3DSurface9::SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags)
172ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
173ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		CriticalSection cs(device);
174ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
175ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		TRACE("");
176ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
177ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		return Direct3DResource9::SetPrivateData(guid, data, size, flags);
178ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
179ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
180ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	long Direct3DSurface9::GetDevice(IDirect3DDevice9 **device)
181ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
182ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		CriticalSection cs(this->device);
183ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
184ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		TRACE("");
185ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
186ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		return Direct3DResource9::GetDevice(device);
187ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
188ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
189ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	unsigned long Direct3DSurface9::SetPriority(unsigned long newPriority)
190ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
191ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		CriticalSection cs(device);
192ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
193ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		TRACE("");
194ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
195ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		return Direct3DResource9::SetPriority(newPriority);
196ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
197ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
198ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	unsigned long Direct3DSurface9::GetPriority()
199ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
200ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		CriticalSection cs(device);
201ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
202ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		TRACE("");
203ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
204ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		return Direct3DResource9::GetPriority();
205ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
206ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
207ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	D3DRESOURCETYPE Direct3DSurface9::GetType()
208ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
209ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		CriticalSection cs(device);
210ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
211ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		TRACE("");
212ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
213ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		return Direct3DResource9::GetType();
214ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
215ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
216ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	long Direct3DSurface9::GetDC(HDC *deviceContext)
217ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
218ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		CriticalSection cs(device);
219ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
220ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		TRACE("");
221ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
222ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		if(!deviceContext)
223ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
224ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			return INVALIDCALL();
225ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
226ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
227ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		UNIMPLEMENTED();
228ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
229ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		return D3D_OK;
230ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
231ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
232ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	long Direct3DSurface9::ReleaseDC(HDC deviceContext)
233ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
234ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		CriticalSection cs(device);
235ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
236ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		TRACE("");
237ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
238ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		UNIMPLEMENTED();
239ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
240ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		return D3D_OK;
241ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
242ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
243ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	long Direct3DSurface9::LockRect(D3DLOCKED_RECT *lockedRect, const RECT *rect, unsigned long flags)
244ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
245ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		CriticalSection cs(device);
246ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
247ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		TRACE("D3DLOCKED_RECT *lockedRect = 0x%0.8p, const RECT *rect = 0x%0.8p, unsigned long flags = %d", lockedRect, rect, flags);
248ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
249ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		if(!lockedRect)
250ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
251ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			return INVALIDCALL();
252ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
253ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
254ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		lockedRect->Pitch = 0;
255ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		lockedRect->pBits = 0;
256ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
257ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		if(!lockable)
258ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
259ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			return INVALIDCALL();
260ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
261ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
262ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		lockedRect->Pitch = getExternalPitchB();
263ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
264ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		sw::Lock lock = sw::LOCK_READWRITE;
265ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
266ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		if(flags & D3DLOCK_DISCARD)
267ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
268ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			lock = sw::LOCK_DISCARD;
269ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
270ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
271ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		if(flags & D3DLOCK_READONLY)
272ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
273ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			lock = sw::LOCK_READONLY;
274ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
275ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
276ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		if(rect)
277ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
278ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			lockedRect->pBits = lockExternal(rect->left, rect->top, 0, lock, sw::PUBLIC);
279ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
280ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		else
281ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
282ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			lockedRect->pBits = lockExternal(0, 0, 0, lock, sw::PUBLIC);
283ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
284ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
285ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		return D3D_OK;
286ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
287ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
288ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	long Direct3DSurface9::UnlockRect()
289ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
290ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		CriticalSection cs(device);
291ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
292ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		TRACE("");
293ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
294ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		unlockExternal();
295ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
296ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		return D3D_OK;
297ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
298ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
299ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	long Direct3DSurface9::GetContainer(const IID &iid, void **container)
300ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
301ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		CriticalSection cs(device);
302ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
303ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		TRACE("");
304ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
305ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		if(!container)
306ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
307ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			return INVALIDCALL();
308ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
309ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
310ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		long result = this->container->QueryInterface(iid, container);
311ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
312ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		if(result == S_OK)
313ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
314ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			return D3D_OK;
315ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
316ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
317ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		return INVALIDCALL();
318ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
319ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
320ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	long Direct3DSurface9::GetDesc(D3DSURFACE_DESC *description)
321ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
322ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		CriticalSection cs(device);
323ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
324ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		TRACE("");
325ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
326ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		if(!description)
327ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
328ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			return INVALIDCALL();
329ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
330ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
331ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		description->Format = format;
332ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		description->Pool = pool;
333ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		description->Type = D3DRTYPE_SURFACE;
334ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		description->Height = height;
335ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		description->Width = width;
336ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		description->MultiSampleType = multiSample;
337ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		description->MultiSampleQuality = quality;
338ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		description->Usage = usage;
339ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
340ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		return D3D_OK;
341ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
342ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
343ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	sw::Format Direct3DSurface9::translateFormat(D3DFORMAT format)
344ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
345ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		switch(format)
346ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
347ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_NULL:			return sw::FORMAT_NULL;
348ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_DXT1:			return sw::FORMAT_DXT1;
349ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_DXT2:			return sw::FORMAT_DXT3;
350ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_DXT3:			return sw::FORMAT_DXT3;
351ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_DXT4:			return sw::FORMAT_DXT5;
352ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_DXT5:			return sw::FORMAT_DXT5;
353ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_ATI1:			return sw::FORMAT_ATI1;
354ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_ATI2:			return sw::FORMAT_ATI2;
355ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_R3G3B2:			return sw::FORMAT_R3G3B2;
356ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_A8R3G3B2:		return sw::FORMAT_A8R3G3B2;
357ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_X4R4G4B4:		return sw::FORMAT_X4R4G4B4;
358ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_A4R4G4B4:		return sw::FORMAT_A4R4G4B4;
359ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_A8R8G8B8:		return sw::FORMAT_A8R8G8B8;
360ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_A8B8G8R8:		return sw::FORMAT_A8B8G8R8;
361ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_G16R16:			return sw::FORMAT_G16R16;
362ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_A2R10G10B10:	return sw::FORMAT_A2R10G10B10;
363ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_A2B10G10R10:	return sw::FORMAT_A2B10G10R10;
364ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_A16B16G16R16:	return sw::FORMAT_A16B16G16R16;
365ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_P8:				return sw::FORMAT_P8;
366ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_A8P8:			return sw::FORMAT_A8P8;
367ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_A8:				return sw::FORMAT_A8;
368ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_R5G6B5:			return sw::FORMAT_R5G6B5;
369ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_X1R5G5B5:		return sw::FORMAT_X1R5G5B5;
370ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_A1R5G5B5:		return sw::FORMAT_A1R5G5B5;
371ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_R8G8B8:			return sw::FORMAT_R8G8B8;
372ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_X8R8G8B8:		return sw::FORMAT_X8R8G8B8;
373ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_X8B8G8R8:		return sw::FORMAT_X8B8G8R8;
374ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_V8U8:			return sw::FORMAT_V8U8;
375ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_L6V5U5:			return sw::FORMAT_L6V5U5;
376ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_Q8W8V8U8:		return sw::FORMAT_Q8W8V8U8;
377ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_X8L8V8U8:		return sw::FORMAT_X8L8V8U8;
378ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_A2W10V10U10:	return sw::FORMAT_A2W10V10U10;
379ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_V16U16:			return sw::FORMAT_V16U16;
380ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_Q16W16V16U16:	return sw::FORMAT_Q16W16V16U16;
381ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_L8:				return sw::FORMAT_L8;
382ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_A4L4:			return sw::FORMAT_A4L4;
383ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_L16:			return sw::FORMAT_L16;
384ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_A8L8:			return sw::FORMAT_A8L8;
385ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_R16F:			return sw::FORMAT_R16F;
386ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_G16R16F:		return sw::FORMAT_G16R16F;
387ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_A16B16G16R16F:	return sw::FORMAT_A16B16G16R16F;
388ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_R32F:			return sw::FORMAT_R32F;
389ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_G32R32F:		return sw::FORMAT_G32R32F;
390ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_A32B32G32R32F:	return sw::FORMAT_A32B32G32R32F;
391ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_D16:			return sw::FORMAT_D16;
392ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_D32:			return sw::FORMAT_D32;
393ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_D24X8:			return sw::FORMAT_D24X8;
394ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_D24S8:			return sw::FORMAT_D24S8;
395ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_D24FS8:			return sw::FORMAT_D24FS8;
396ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_D32F_LOCKABLE:	return sw::FORMAT_D32F_LOCKABLE;
39766839438a7ed306493ed2b8721d197cd3663c67aNicolas Capens		case D3DFMT_DF24:			return sw::FORMAT_DF24S8;
39866839438a7ed306493ed2b8721d197cd3663c67aNicolas Capens		case D3DFMT_DF16:			return sw::FORMAT_DF16S8;
399ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFMT_INTZ:			return sw::FORMAT_INTZ;
400ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		default:
401ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			ASSERT(false);
402ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
403ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
404ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		return sw::FORMAT_NULL;
405ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
406ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
407ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	int Direct3DSurface9::bytes(D3DFORMAT format)
408ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
409ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		return Surface::bytes(translateFormat(format));
410ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
411ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
412bfa23b3f4de49586d2bd25efb77fa92734bd6f26Nicolas Capens	unsigned int Direct3DSurface9::memoryUsage(int width, int height, D3DMULTISAMPLE_TYPE multiSample, unsigned int quality, D3DFORMAT format)
413ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
414bfa23b3f4de49586d2bd25efb77fa92734bd6f26Nicolas Capens		return Surface::size(width, height, 1, 0, sampleCount(multiSample, quality), translateFormat(format));
415ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
416ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens}
417