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