Tizen 2.1 base
[sdk/emulator/qemu.git] / gl / mesa / src / gallium / state_trackers / d3d1x / gd3d11 / d3d11_objects.h
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 };