1 /**************************************************************************
2  *
3  * Copyright 2010 Luca Barbieri
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sublicense, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the
14  * next paragraph) shall be included in all copies or substantial
15  * portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20  * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  *
25  **************************************************************************/
26 
27 template<typename Base = ID3D11DeviceChild>
28 struct GalliumD3D11DeviceChild : public GalliumPrivateDataComObject<Base, dual_refcnt_t>
29 {
30 	GalliumD3D11Screen* device; // must not be null
31 
32 
33 	// if this is called, the subclass constructor must set device itself
GalliumD3D11DeviceChildGalliumD3D11DeviceChild34 	GalliumD3D11DeviceChild()
35 	: device(0)
36 	{}
37 
GalliumD3D11DeviceChildGalliumD3D11DeviceChild38 	GalliumD3D11DeviceChild(GalliumD3D11Screen* p_device)
39 	{
40 		// we store the reference count minus one in refcnt
41 		device = p_device;
42 		device->AddRef();
43 	}
44 
~GalliumD3D11DeviceChildGalliumD3D11DeviceChild45 	virtual ~GalliumD3D11DeviceChild()
46 	{
47 		if(device)
48 			device->Release();
49 	}
50 
51 	/* The purpose of this is to avoid cyclic garbage, since this won't hold
52 	 * a pointer to the device if it is only held by a pipeline binding in the immediate context
53 	 *
54 	 * TODO: we could only manipulate the device refcnt when atomic_refcnt == 0 changes,
55 	 * but this requires more complex atomic ops
56 	 */
add_refGalliumD3D11DeviceChild57 	inline ULONG add_ref()
58 	{
59 		return GalliumPrivateDataComObject<Base, dual_refcnt_t>::add_ref();
60 	}
61 
releaseGalliumD3D11DeviceChild62 	inline ULONG release()
63 	{
64 		return GalliumPrivateDataComObject<Base, dual_refcnt_t>::release();
65 	}
66 
AddRefGalliumD3D11DeviceChild67 	virtual ULONG STDMETHODCALLTYPE AddRef()
68 	{
69 		return add_ref();
70 	}
71 
ReleaseGalliumD3D11DeviceChild72 	virtual ULONG STDMETHODCALLTYPE Release()
73 	{
74 		return release();
75 	}
76 
GetDeviceGalliumD3D11DeviceChild77 	virtual void STDMETHODCALLTYPE GetDevice(
78 		ID3D11Device **out_device
79 	 )
80 	{
81 		device->AddRef();
82 		*out_device = device;
83 	}
84 };
85 
86 template<typename Base = ID3D11DeviceChild, typename Object = void>
87 struct GalliumD3D11Object : public GalliumD3D11DeviceChild<Base>
88 {
89 	Object* object;
GalliumD3D11ObjectGalliumD3D11Object90 	GalliumD3D11Object(GalliumD3D11Screen* device, Object* object)
91 	: GalliumD3D11DeviceChild<Base>(device), object(object)
92 	{}
93 
94 	virtual ~GalliumD3D11Object();
95 };
96 
97 #define IMPLEMENT_OBJECT_DTOR(name, gallium) \
98 template<> \
99 GalliumD3D11Object<ID3D11##name, void>::~GalliumD3D11Object() \
100 { \
101 	DX10_ONLY(device->Unbind##name(this)); \
102 	device->immediate_pipe->delete_##gallium##_state(device->immediate_pipe, object); \
103 }
104 
105 #define IMPLEMENT_VIEW_DTOR(name, gallium) \
106 template<> \
107 GalliumD3D11Object<ID3D11##name, struct pipe_##gallium>::~GalliumD3D11Object() \
108 { \
109 	DX10_ONLY(device->Unbind##name(this)); \
110 	pipe_##gallium##_reference(&object, 0); \
111 }
112 
113 IMPLEMENT_OBJECT_DTOR(InputLayout, vertex_elements)
114 IMPLEMENT_OBJECT_DTOR(DepthStencilState, depth_stencil_alpha)
115 IMPLEMENT_OBJECT_DTOR(RasterizerState, rasterizer)
116 IMPLEMENT_OBJECT_DTOR(SamplerState, sampler)
117 IMPLEMENT_OBJECT_DTOR(BlendState, blend)
118 IMPLEMENT_OBJECT_DTOR(VertexShader, vs)
119 IMPLEMENT_OBJECT_DTOR(PixelShader, fs)
120 IMPLEMENT_OBJECT_DTOR(GeometryShader, gs)
121 
122 IMPLEMENT_VIEW_DTOR(ShaderResourceView, sampler_view)
123 IMPLEMENT_VIEW_DTOR(RenderTargetView, surface)
124 IMPLEMENT_VIEW_DTOR(DepthStencilView, surface)
125 
126 #if API >= 11
127 // IMPLEMENT_VIEW_DTOR(UnorderedAccessView, surface);
128 // IMPLEMENT_OBJECT_DTOR(HullShader, tcs);
129 // IMPLEMENT_OBJECT_DTOR(DomainShader, tes);
130 // IMPLEMENT_OBJECT_DTOR(ComputeShader, cs);
131 #else
132 IMPLEMENT_OBJECT_DTOR(BlendState1, blend)
133 IMPLEMENT_VIEW_DTOR(ShaderResourceView1, sampler_view)
134 #endif
135 
136 template<typename Base, typename Desc, typename Object = void>
137 struct GalliumD3D11DescribedObject : public GalliumD3D11Object<Base, Object>
138 {
139 	Desc desc;
GalliumD3D11DescribedObjectGalliumD3D11DescribedObject140 	GalliumD3D11DescribedObject(GalliumD3D11Screen* device, Object* object, const Desc& desc)
141 	: GalliumD3D11Object<Base, Object>(device, object), desc(desc)
142 	{}
143 
GetDescGalliumD3D11DescribedObject144 	virtual void STDMETHODCALLTYPE GetDesc(Desc *out_desc)
145 	{
146 		memcpy(out_desc, &desc, sizeof(desc));
147 	}
148 };
149 
150 typedef GalliumD3D11Object<ID3D11InputLayout> GalliumD3D11InputLayout;
151 typedef GalliumD3D11DescribedObject<ID3D11DepthStencilState, D3D11_DEPTH_STENCIL_DESC> GalliumD3D11DepthStencilState;
152 typedef GalliumD3D11DescribedObject<ID3D11RasterizerState, D3D11_RASTERIZER_DESC> GalliumD3D11RasterizerStateBase;
153 typedef GalliumD3D11DescribedObject<ID3D11SamplerState, D3D11_SAMPLER_DESC> GalliumD3D11SamplerState;
154 
155 #if API >= 11
156 typedef GalliumD3D11DescribedObject<ID3D11BlendState, D3D11_BLEND_DESC> GalliumD3D11BlendState;
157 #else
158 typedef GalliumD3D10DescribedObject<ID3D10BlendState1, D3D10_BLEND_DESC> GalliumD3D10BlendStateBase;
159 
160 struct GalliumD3D10BlendState : public GalliumD3D10BlendStateBase
161 {
convert_to_d3d10GalliumD3D10BlendState162 	static D3D10_BLEND_DESC convert_to_d3d10(const D3D10_BLEND_DESC1& desc1)
163 	{
164 		D3D10_BLEND_DESC desc;
165 		desc.AlphaToCoverageEnable = desc1.AlphaToCoverageEnable;
166 		desc.SrcBlend = desc1.RenderTarget[0].SrcBlend;
167 		desc.DestBlend = desc1.RenderTarget[0].DestBlend;
168 		desc.BlendOp = desc1.RenderTarget[0].BlendOp;
169 		desc.SrcBlendAlpha = desc1.RenderTarget[0].SrcBlendAlpha;
170 		desc.DestBlendAlpha = desc1.RenderTarget[0].DestBlendAlpha;
171 		desc.BlendOpAlpha = desc1.RenderTarget[0].BlendOpAlpha;
172 		for(unsigned i = 0; i < 8; ++i)
173 		{
174 			desc.BlendEnable[i] = desc1.RenderTarget[i].BlendEnable;
175 			desc.RenderTargetWriteMask[i] = desc1.RenderTarget[i].RenderTargetWriteMask;
176 		}
177 		return desc;
178 	}
179 
180 	D3D10_BLEND_DESC1 desc1;
181 
GalliumD3D10BlendStateGalliumD3D10BlendState182 	GalliumD3D10BlendState(GalliumD3D10Screen* device, void* object, const D3D10_BLEND_DESC& desc)
183 	: GalliumD3D10BlendStateBase(device, object, desc)
184 	{
185 		memset(&desc1, 0, sizeof(desc1));
186 		desc1.AlphaToCoverageEnable = desc.AlphaToCoverageEnable;
187 		desc1.RenderTarget[0].SrcBlend = desc.SrcBlend;
188 		desc1.RenderTarget[0].DestBlend = desc.DestBlend;
189 		desc1.RenderTarget[0].BlendOp = desc.BlendOp;
190 		desc1.RenderTarget[0].SrcBlendAlpha = desc.SrcBlendAlpha;
191 		desc1.RenderTarget[0].DestBlendAlpha = desc.DestBlendAlpha;
192 		desc1.RenderTarget[0].BlendOpAlpha = desc.BlendOpAlpha;
193 		for(unsigned i = 0; i < 8; ++i)
194 		{
195 			desc1.RenderTarget[i].BlendEnable = desc.BlendEnable[i];
196 			desc1.RenderTarget[i].RenderTargetWriteMask = desc.RenderTargetWriteMask[i];
197 		}
198 	}
199 
GalliumD3D10BlendStateGalliumD3D10BlendState200 	GalliumD3D10BlendState(GalliumD3D10Screen* device, void* object, const D3D10_BLEND_DESC1& desc)
201 	: GalliumD3D10BlendStateBase(device, object, convert_to_d3d10(desc)), desc1(desc1)
202 	{}
203 
GetDesc1GalliumD3D10BlendState204 	virtual void STDMETHODCALLTYPE GetDesc1(D3D10_BLEND_DESC1 *out_desc)
205 	{
206 		memcpy(out_desc, &desc1, sizeof(desc1));
207 	}
208 };
209 #endif
210 
211 struct GalliumD3D11RasterizerState : public GalliumD3D11RasterizerStateBase
212 {
GalliumD3D11RasterizerStateGalliumD3D11RasterizerState213 	GalliumD3D11RasterizerState(GalliumD3D11Screen* device, void* object, const D3D11_RASTERIZER_DESC& desc)
214 	: GalliumD3D11RasterizerStateBase(device, object, desc)
215 	{}
216 };
217 
218 template<typename Base = ID3D11DeviceChild>
219 struct GalliumD3D11Shader : public GalliumD3D11Object<Base>
220 {
GalliumD3D11ShaderGalliumD3D11Shader221 	GalliumD3D11Shader(GalliumD3D11Screen* device, void* object)
222 	: GalliumD3D11Object<Base>(device, object)
223 	{}
224 };
225 
226 typedef GalliumD3D11Shader<ID3D11VertexShader> GalliumD3D11VertexShader;
227 typedef GalliumD3D11Shader<ID3D11GeometryShader> GalliumD3D11GeometryShader;
228 typedef GalliumD3D11Shader<ID3D11PixelShader> GalliumD3D11PixelShader;
229 
230 #if API >= 11
231 /*
232 typedef GalliumD3D11Shader<ID3D11HullShader> GalliumD3D11HullShader;
233 typedef GalliumD3D11Shader<ID3D11DomainShader> GalliumD3D11DomainShader;
234 typedef GalliumD3D11Shader<ID3D11ComputeShader> GalliumD3D11ComputeShader;
235 */
236 #endif
237 
238 template<typename Base = ID3D11Resource>
239 struct GalliumD3D11ResourceBase : public GalliumD3D11DeviceChild<Base>
240 {
241 	unsigned eviction_priority;
242 
SetEvictionPriorityGalliumD3D11ResourceBase243 	virtual void STDMETHODCALLTYPE SetEvictionPriority(
244 		unsigned new_eviction_priority
245 	)
246 	{
247 		eviction_priority = new_eviction_priority;
248 	}
249 
GetEvictionPriorityGalliumD3D11ResourceBase250 	virtual unsigned STDMETHODCALLTYPE GetEvictionPriority()
251 	{
252 		return eviction_priority;
253 	}
254 };
255 
256 template<typename Real>
257 struct GalliumDXGIResource : public IDXGIResource
258 {
SetEvictionPriorityGalliumDXGIResource259 	virtual HRESULT STDMETHODCALLTYPE SetEvictionPriority(
260 		unsigned new_eviction_priority
261 	)
262 	{
263 		static_cast<Real*>(this)->eviction_priority = new_eviction_priority;
264 		return S_OK;
265 	}
266 
GetEvictionPriorityGalliumDXGIResource267 	virtual HRESULT STDMETHODCALLTYPE GetEvictionPriority(unsigned* out_eviction_priority)
268 	{
269 	 	*out_eviction_priority = static_cast<Real*>(this)->eviction_priority;
270 	 	return S_OK;
271 	}
272 
GetDeviceGalliumDXGIResource273 	virtual HRESULT STDMETHODCALLTYPE GetDevice(
274 		REFIID riid,
275 		void **out_parent)
276 	{
277 		if(!static_cast<Real*>(this)->device)
278 			return E_NOINTERFACE;
279 		return static_cast<Real*>(this)->device->QueryInterface(riid, out_parent);
280 	}
281 
GetParentGalliumDXGIResource282 	virtual HRESULT STDMETHODCALLTYPE GetParent(
283 		REFIID riid,
284 		void **out_parent)
285 	{
286 		if(!static_cast<Real*>(this)->device)
287 			return E_NOINTERFACE;
288 		return static_cast<Real*>(this)->device->QueryInterface(riid, out_parent);
289 	}
290 };
291 
292 template<typename T>
293 struct com_traits<GalliumDXGIResource<T> > : public com_traits<IDXGIResource>
294 {};
295 
296 template<typename Base = ID3D11Resource>
297 struct GalliumD3D11Resource
298 	: public GalliumMultiComObject<
299 		GalliumMultiPrivateDataComObject<
300 			GalliumD3D11ResourceBase<Base>,
301 			GalliumDXGIResource<GalliumD3D11Resource<Base> >
302 		>,
303 		IGalliumResource
304 	>
305 {
306 	struct pipe_resource* resource;
307 	std::unordered_map<unsigned, pipe_transfer*> transfers;
308 	float min_lod;
309 	DXGI_USAGE dxgi_usage;
310 
311 	GalliumD3D11Resource(GalliumD3D11Screen* device = 0, struct pipe_resource* resource = 0, unsigned dxgi_usage = 0)
312 	: resource(resource), min_lod(0), dxgi_usage(dxgi_usage)
313 	{
314 		this->device = device;
315 		if(device)
316 			device->AddRef();
317 		this->eviction_priority = 0;
318 	}
319 
320 	~GalliumD3D11Resource()
321 	{
322 		pipe_resource_reference(&resource, 0);
323 	}
324 
325 	virtual HRESULT STDMETHODCALLTYPE GetUsage(
326 		DXGI_USAGE *out_usage
327 	 )
328 	{
329 		*out_usage = this->dxgi_usage;
330 		return S_OK;
331 	}
332 
333 	virtual HRESULT STDMETHODCALLTYPE GetSharedHandle(HANDLE *out_shared_handle)
334 	{
335 		return E_NOTIMPL;
336 	}
337 
338 	virtual struct pipe_resource* STDMETHODCALLTYPE GetGalliumResource()
339 	{
340 		return resource;
341 	}
342 };
343 
344 template<typename Base, typename Desc, D3D11_RESOURCE_DIMENSION Dim>
345 struct GalliumD3D11TypedResource : public GalliumD3D11Resource<Base>
346 {
347 	Desc desc;
348 	GalliumD3D11TypedResource() {}
349 	GalliumD3D11TypedResource(GalliumD3D11Screen* device, struct pipe_resource* resource, const Desc& desc, unsigned dxgi_usage)
350 	: GalliumD3D11Resource<Base>(device, resource, dxgi_usage), desc(desc)
351 	{}
352 	virtual void STDMETHODCALLTYPE GetType(
353 		D3D11_RESOURCE_DIMENSION *out_resource_dimension)
354 	{
355 		*out_resource_dimension = Dim;
356 	}
357 	virtual void STDMETHODCALLTYPE GetDesc(Desc *out_desc)
358 	{
359 		memcpy(out_desc, &desc, sizeof(desc));
360 	}
361 };
362 
363 typedef GalliumD3D11TypedResource<ID3D11Texture1D, D3D11_TEXTURE1D_DESC, D3D11_RESOURCE_DIMENSION_TEXTURE1D> GalliumD3D11Texture1DBase;
364 typedef GalliumD3D11TypedResource<ID3D11Texture2D, D3D11_TEXTURE2D_DESC, D3D11_RESOURCE_DIMENSION_TEXTURE2D> GalliumD3D11Texture2DBase;
365 typedef GalliumD3D11TypedResource<ID3D11Texture3D, D3D11_TEXTURE3D_DESC, D3D11_RESOURCE_DIMENSION_TEXTURE3D> GalliumD3D11Texture3DBase;
366 typedef GalliumD3D11TypedResource<ID3D11Buffer, D3D11_BUFFER_DESC, D3D11_RESOURCE_DIMENSION_BUFFER> GalliumD3D11BufferBase;
367 
368 #if API >= 11
369 typedef GalliumD3D11Texture1DBase GalliumD3D11Texture1D;
370 typedef GalliumD3D11Texture2DBase GalliumD3D11Texture2D;
371 typedef GalliumD3D11Texture3DBase GalliumD3D11Texture3D;
372 
373 struct GalliumD3D11Buffer : public GalliumD3D11BufferBase
374 {
375 	struct pipe_stream_output_target* so_target;
376 
377 	GalliumD3D11Buffer(GalliumD3D11Screen* device, struct pipe_resource* resource, const D3D11_BUFFER_DESC& desc, unsigned dxgi_usage)
378 	: GalliumD3D11BufferBase(device, resource, desc, dxgi_usage), so_target(0)
379 	{
380 	}
381 
382 	~GalliumD3D11Buffer()
383 	{
384 		if(so_target)
385 			pipe_so_target_reference(&so_target, NULL);
386 	}
387 };
388 #else
389 struct GalliumD3D10Buffer : public GalliumD3D10BufferBase
390 {
391 	struct pipe_stream_output_target *so_target;
392 
393 	GalliumD3D10Buffer(GalliumD3D10Screen* device, struct pipe_resource* resource, const D3D10_BUFFER_DESC& desc, unsigned dxgi_usage)
394 	: GalliumD3D10BufferBase(device, resource, desc, dxgi_usage)
395 	{
396 	}
397 
398 	~GalliumD3D10Buffer()
399 	{
400 		if(so_target)
401 			pipe_so_target_reference(&so_target, NULL);
402 
403 		device->UnbindBuffer(this);
404 	}
405 
406 	virtual HRESULT STDMETHODCALLTYPE Map(
407 		D3D10_MAP map_type,
408 		unsigned map_flags,
409 		void **out_data)
410 	{
411 		D3D10_MAPPED_SUBRESOURCE msr;
412 		HRESULT hr = device->Map(this, 0, map_type, map_flags, &msr);
413 		if(!SUCCEEDED(hr))
414 			return hr;
415 		*out_data = msr.pData;
416 		return S_OK;
417 	}
418 
419 	virtual void STDMETHODCALLTYPE Unmap()
420 	{
421 		device->Unmap(this, 0);
422 	}
423 };
424 
425 struct GalliumD3D10Texture1D : public GalliumD3D10Texture1DBase
426 {
427 	GalliumD3D10Texture1D(GalliumD3D10Screen* device, struct pipe_resource* resource, const D3D10_TEXTURE1D_DESC& desc, unsigned dxgi_usage)
428 	: GalliumD3D10Texture1DBase(device, resource, desc, dxgi_usage)
429 	{}
430 
431 	virtual HRESULT STDMETHODCALLTYPE Map(
432 		unsigned subresource,
433 		D3D10_MAP map_type,
434 		unsigned map_flags,
435 		void **out_data)
436 	{
437 		D3D10_MAPPED_SUBRESOURCE msr;
438 		HRESULT hr = device->Map(this, subresource, map_type, map_flags, &msr);
439 		if(!SUCCEEDED(hr))
440 			return hr;
441 		*out_data = msr.pData;
442 		return S_OK;
443 	}
444 
445 	virtual void STDMETHODCALLTYPE Unmap(
446 		unsigned subresource
447 	)
448 	{
449 		device->Unmap(this, subresource);
450 	}
451 };
452 
453 struct GalliumD3D10Texture2D : public GalliumD3D10Texture2DBase
454 {
455 	GalliumD3D10Texture2D() {}
456 	GalliumD3D10Texture2D(GalliumD3D10Screen* device, struct pipe_resource* resource, const D3D10_TEXTURE2D_DESC& desc, unsigned dxgi_usage)
457 	: GalliumD3D10Texture2DBase(device, resource, desc, dxgi_usage)
458 	{}
459 
460 	virtual HRESULT STDMETHODCALLTYPE Map(
461 		unsigned subresource,
462 		D3D10_MAP map_type,
463 		unsigned map_flags,
464 		D3D10_MAPPED_TEXTURE2D *out_mapped_subresource)
465 	{
466 		D3D10_MAPPED_SUBRESOURCE msr;
467 		HRESULT hr = device->Map(this, subresource, map_type, map_flags, &msr);
468 		if(!SUCCEEDED(hr))
469 			return hr;
470 		out_mapped_subresource->pData = msr.pData;
471 		out_mapped_subresource->RowPitch = msr.RowPitch;
472 		return S_OK;
473 	}
474 
475 	virtual void STDMETHODCALLTYPE Unmap(
476 		unsigned subresource
477 	)
478 	{
479 		device->Unmap(this, subresource);
480 	}
481 };
482 
483 
484 struct GalliumD3D10Texture3D : public GalliumD3D10Texture3DBase
485 {
486 	GalliumD3D10Texture3D(GalliumD3D10Screen* device, struct pipe_resource* resource, const D3D10_TEXTURE3D_DESC& desc, unsigned dxgi_usage)
487 	: GalliumD3D10Texture3DBase(device, resource, desc, dxgi_usage)
488 	{}
489 
490 	virtual HRESULT STDMETHODCALLTYPE Map(
491 		unsigned subresource,
492 		D3D10_MAP map_type,
493 		unsigned map_flags,
494 		D3D10_MAPPED_TEXTURE3D *out_mapped_subresource)
495 	{
496 		D3D10_MAPPED_SUBRESOURCE msr;
497 		HRESULT hr = device->Map(this, subresource, map_type, map_flags, &msr);
498 		if(!SUCCEEDED(hr))
499 			return hr;
500 		out_mapped_subresource->pData = msr.pData;
501 		out_mapped_subresource->RowPitch = msr.RowPitch;
502 		out_mapped_subresource->DepthPitch = msr.DepthPitch;
503 		return S_OK;
504 	}
505 
506 	virtual void STDMETHODCALLTYPE Unmap(
507 		unsigned subresource
508 	)
509 	{
510 		device->Unmap(this, subresource);
511 	}
512 };
513 #endif
514 
515 struct GalliumD3D11Surface : public GalliumMultiPrivateDataComObject<GalliumD3D11Texture2D, IDXGISurface1>
516 {
517 	GalliumD3D11Surface(GalliumD3D11Screen* device, struct pipe_resource* resource, const D3D11_TEXTURE2D_DESC& desc, unsigned dxgi_usage)
518 	{
519 		this->device = device;
520 		this->device->AddRef();
521 		this->resource = resource;
522 		this->desc = desc;
523 		this->dxgi_usage = dxgi_usage;
524 	}
525 
526 	virtual HRESULT STDMETHODCALLTYPE GetDesc(
527 		DXGI_SURFACE_DESC *out_desc)
528 	{
529 		out_desc->Format = this->desc.Format;
530 		out_desc->Width = this->desc.Width;
531 		out_desc->Height = this->desc.Height;
532 		out_desc->SampleDesc = this->desc.SampleDesc;
533 		return S_OK;
534 	}
535 
536 	virtual HRESULT STDMETHODCALLTYPE GetParent(
537 		REFIID riid,
538 		void **out_parent)
539 	{
540 		if(!device)
541 			return E_NOINTERFACE;
542 		return device->QueryInterface(riid, out_parent);
543 	}
544 
545 	/* TODO: somehow implement these */
546 	virtual HRESULT STDMETHODCALLTYPE GetDC(
547 		BOOL discard,
548 		HDC *out_hdc)
549 	{
550 		*out_hdc = 0;
551 		return E_NOTIMPL;
552 	}
553 
554 	virtual HRESULT STDMETHODCALLTYPE ReleaseDC(
555 		RECT *out_dirty_rect)
556 	{
557 		return E_NOTIMPL;
558 	}
559 
560 	virtual HRESULT STDMETHODCALLTYPE Map(
561 		DXGI_MAPPED_RECT *out_locked_rect,
562 		unsigned map_flags)
563 	{
564 		D3D11_MAP d3d_map;
565 		if(map_flags & DXGI_MAP_DISCARD)
566 			d3d_map = D3D11_MAP_WRITE_DISCARD;
567 		else
568 		{
569 			if(map_flags & DXGI_MAP_READ)
570 			{
571 				if(map_flags & DXGI_MAP_WRITE)
572 					d3d_map = D3D11_MAP_READ_WRITE;
573 				else
574 					d3d_map = D3D11_MAP_READ;
575 			}
576 			else
577 				d3d_map = D3D11_MAP_WRITE;
578 		}
579 		D3D11_MAPPED_SUBRESOURCE d3d_mapped;
580 		HRESULT hres = this->device->get_immediate_context()->Map(this, 0, d3d_map, 0, &d3d_mapped);
581 		out_locked_rect->pBits = (uint8_t*)d3d_mapped.pData;
582 		out_locked_rect->Pitch = d3d_mapped.RowPitch;
583 		return hres;
584 	}
585 
586 	virtual HRESULT STDMETHODCALLTYPE Unmap(void)
587 	{
588 		this->device->get_immediate_context()->Unmap(this, 0);
589 		return S_OK;
590 	}
591 
592 	virtual HRESULT STDMETHODCALLTYPE GetDevice(
593 		REFIID riid,
594 		void **out_parent)
595 	{
596 		if(!device)
597 			return E_NOINTERFACE;
598 		return device->QueryInterface(riid, out_parent);
599 	}
600 };
601 
602 template<typename Base, typename Desc, typename Object>
603 struct GalliumD3D11View : public GalliumD3D11DescribedObject<Base, Desc, Object>
604 {
605 	GalliumD3D11Resource<>* resource;
606 	GalliumD3D11View(GalliumD3D11Screen* device, GalliumD3D11Resource<>* resource, Object* object, const Desc& desc)
607 	: GalliumD3D11DescribedObject<Base, Desc, Object>(device, object, desc), resource(resource)
608 	{
609 		resource->AddRef();
610 	}
611 
612 	~GalliumD3D11View()
613 	{
614 		resource->Release();
615 	}
616 
617 	virtual void STDMETHODCALLTYPE GetResource(ID3D11Resource** out_resource)
618 	{
619 		resource->AddRef();
620 		*out_resource = resource;
621 	}
622 };
623 
624 typedef GalliumD3D11View<ID3D11DepthStencilView, D3D11_DEPTH_STENCIL_VIEW_DESC, struct pipe_surface> GalliumD3D11DepthStencilView;
625 typedef GalliumD3D11View<ID3D11RenderTargetView, D3D11_RENDER_TARGET_VIEW_DESC, struct pipe_surface> GalliumD3D11RenderTargetView;
626 
627 #if API >= 11
628 typedef GalliumD3D11View<ID3D11ShaderResourceView, D3D11_SHADER_RESOURCE_VIEW_DESC, struct pipe_sampler_view> GalliumD3D11ShaderResourceView;
629 #else
630 typedef GalliumD3D10View<ID3D10ShaderResourceView1, D3D10_SHADER_RESOURCE_VIEW_DESC1, struct pipe_sampler_view> GalliumD3D10ShaderResourceViewBase;
631 
632 struct GalliumD3D10ShaderResourceView : public GalliumD3D10ShaderResourceViewBase
633 {
634 	GalliumD3D10ShaderResourceView(GalliumD3D10Screen* device, GalliumD3D10Resource<>* resource, struct pipe_sampler_view* view, const D3D10_SHADER_RESOURCE_VIEW_DESC1& desc)
635 	: GalliumD3D10ShaderResourceViewBase(device, resource, view, desc)
636 	{}
637 
638 	virtual void STDMETHODCALLTYPE GetDesc1(D3D10_SHADER_RESOURCE_VIEW_DESC1 *out_desc)
639 	{
640 		memcpy(out_desc, &desc, sizeof(*out_desc));
641 	}
642 
643 	virtual void STDMETHODCALLTYPE GetDesc(D3D10_SHADER_RESOURCE_VIEW_DESC *out_desc)
644 	{
645 		memcpy(out_desc, &desc, sizeof(*out_desc));
646 	}
647 };
648 #endif
649 
650 template<typename Base = ID3D11Asynchronous>
651 struct GalliumD3D11Asynchronous : public GalliumD3D11DeviceChild<Base>
652 {
653 	struct pipe_query* query;
654 	unsigned data_size;
655 
656 	GalliumD3D11Asynchronous(GalliumD3D11Screen* device, struct pipe_query* query, unsigned data_size)
657 	: GalliumD3D11DeviceChild<Base>(device), query(query), data_size(data_size)
658 	{}
659 
660 	~GalliumD3D11Asynchronous()
661 	{
662 		this->device->immediate_pipe->destroy_query(this->device->immediate_pipe, query);
663 	}
664 
665 	virtual unsigned STDMETHODCALLTYPE GetDataSize()
666 	{
667 		return data_size;
668 	}
669 
670 #if API < 11
671 	virtual void STDMETHODCALLTYPE Begin()
672 	{
673 		this->device->Begin(this);
674 	}
675 
676 	virtual void STDMETHODCALLTYPE End()
677 	{
678 		this->device->End(this);
679 	}
680 
681 	virtual HRESULT STDMETHODCALLTYPE GetData(
682 		void * out_data,
683 		unsigned data_size,
684 		unsigned get_data_flags)
685 	{
686 		return this->device->GetData(this, out_data, data_size, get_data_flags);
687 	}
688 #endif
689 };
690 
691 template<typename Base = ID3D11Asynchronous>
692 struct GalliumD3D11QueryOrPredicate : public GalliumD3D11Asynchronous<Base>
693 {
694 	D3D11_QUERY_DESC desc;
695 	GalliumD3D11QueryOrPredicate(GalliumD3D11Screen* device, struct pipe_query* query, unsigned data_size, const D3D11_QUERY_DESC& desc)
696 	: GalliumD3D11Asynchronous<Base>(device, query, data_size), desc(desc)
697 	{}
698 
699 	virtual void STDMETHODCALLTYPE GetDesc(
700 		D3D11_QUERY_DESC *out_desc)
701 	{
702 		*out_desc = desc;
703 	}
704 };
705 
706 struct GalliumD3D11Query : public GalliumD3D11QueryOrPredicate<ID3D11Query>
707 {
708 	GalliumD3D11Query(GalliumD3D11Screen* device, struct pipe_query* query, unsigned data_size, const D3D11_QUERY_DESC& desc)
709 	: GalliumD3D11QueryOrPredicate<ID3D11Query>(device, query, data_size, desc)
710 	{}
711 };
712 
713 struct GalliumD3D11Predicate : public GalliumD3D11QueryOrPredicate<ID3D11Predicate>
714 {
715 	GalliumD3D11Predicate(GalliumD3D11Screen* device, struct pipe_query* query, unsigned data_size, const D3D11_QUERY_DESC& desc)
716 	: GalliumD3D11QueryOrPredicate<ID3D11Predicate>(device, query, data_size, desc)
717 	{}
718 
719 	~GalliumD3D11Predicate()
720 	{
721 		DX10_ONLY(device->UnbindPredicate(this));
722 	}
723 };
724 
725 struct GalliumD3D11Counter : public GalliumD3D11Asynchronous<ID3D11Counter>
726 {
727 	D3D11_COUNTER_DESC desc;
728 	GalliumD3D11Counter(GalliumD3D11Screen* device, struct pipe_query* query, unsigned data_size, const D3D11_COUNTER_DESC& desc)
729 	: GalliumD3D11Asynchronous<ID3D11Counter>(device, query, data_size), desc(desc)
730 	{}
731 
732 	virtual void STDMETHODCALLTYPE GetDesc(
733 		D3D11_COUNTER_DESC *out_desc)
734 	{
735 		*out_desc = desc;
736 	}
737 };
738