Home | History | Annotate | Download | only in gd3d11
      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
     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 	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 	 */
     57 	inline ULONG add_ref()
     58 	{
     59 		return GalliumPrivateDataComObject<Base, dual_refcnt_t>::add_ref();
     60 	}
     61 
     62 	inline ULONG release()
     63 	{
     64 		return GalliumPrivateDataComObject<Base, dual_refcnt_t>::release();
     65 	}
     66 
     67 	virtual ULONG STDMETHODCALLTYPE AddRef()
     68 	{
     69 		return add_ref();
     70 	}
     71 
     72 	virtual ULONG STDMETHODCALLTYPE Release()
     73 	{
     74 		return release();
     75 	}
     76 
     77 	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;
     90 	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;
    140 	GalliumD3D11DescribedObject(GalliumD3D11Screen* device, Object* object, const Desc& desc)
    141 	: GalliumD3D11Object<Base, Object>(device, object), desc(desc)
    142 	{}
    143 
    144 	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 {
    162 	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 
    182 	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 
    200 	GalliumD3D10BlendState(GalliumD3D10Screen* device, void* object, const D3D10_BLEND_DESC1& desc)
    201 	: GalliumD3D10BlendStateBase(device, object, convert_to_d3d10(desc)), desc1(desc1)
    202 	{}
    203 
    204 	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 {
    213 	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 {
    221 	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 
    243 	virtual void STDMETHODCALLTYPE SetEvictionPriority(
    244 		unsigned new_eviction_priority
    245 	)
    246 	{
    247 		eviction_priority = new_eviction_priority;
    248 	}
    249 
    250 	virtual unsigned STDMETHODCALLTYPE GetEvictionPriority()
    251 	{
    252 		return eviction_priority;
    253 	}
    254 };
    255 
    256 template<typename Real>
    257 struct GalliumDXGIResource : public IDXGIResource
    258 {
    259 	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 
    267 	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 
    273 	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 
    282 	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