e1ef7b807beffacbeac8643912db7fad42a209fd
[mesa.git] / 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 bool depth_clamp;
214
215 GalliumD3D11RasterizerState(GalliumD3D11Screen* device, void* object, const D3D11_RASTERIZER_DESC& desc, bool depth_clamp)
216 : GalliumD3D11RasterizerStateBase(device, object, desc), depth_clamp(depth_clamp)
217 {}
218 };
219
220 template<typename Base = ID3D11DeviceChild>
221 struct GalliumD3D11Shader : public GalliumD3D11Object<Base>
222 {
223 GalliumD3D11Shader(GalliumD3D11Screen* device, void* object)
224 : GalliumD3D11Object<Base>(device, object)
225 {}
226 };
227
228 typedef GalliumD3D11Shader<ID3D11VertexShader> GalliumD3D11VertexShader;
229 typedef GalliumD3D11Shader<ID3D11GeometryShader> GalliumD3D11GeometryShader;
230 typedef GalliumD3D11Shader<ID3D11PixelShader> GalliumD3D11PixelShader;
231
232 #if API >= 11
233 /*
234 typedef GalliumD3D11Shader<ID3D11HullShader> GalliumD3D11HullShader;
235 typedef GalliumD3D11Shader<ID3D11DomainShader> GalliumD3D11DomainShader;
236 typedef GalliumD3D11Shader<ID3D11ComputeShader> GalliumD3D11ComputeShader;
237 */
238 #endif
239
240 template<typename Base = ID3D11Resource>
241 struct GalliumD3D11ResourceBase : public GalliumD3D11DeviceChild<Base>
242 {
243 unsigned eviction_priority;
244
245 virtual void STDMETHODCALLTYPE SetEvictionPriority(
246 unsigned new_eviction_priority
247 )
248 {
249 eviction_priority = new_eviction_priority;
250 }
251
252 virtual unsigned STDMETHODCALLTYPE GetEvictionPriority()
253 {
254 return eviction_priority;
255 }
256 };
257
258 template<typename Real>
259 struct GalliumDXGIResource : public IDXGIResource
260 {
261 virtual HRESULT STDMETHODCALLTYPE SetEvictionPriority(
262 unsigned new_eviction_priority
263 )
264 {
265 static_cast<Real*>(this)->eviction_priority = new_eviction_priority;
266 return S_OK;
267 }
268
269 virtual HRESULT STDMETHODCALLTYPE GetEvictionPriority(unsigned* out_eviction_priority)
270 {
271 *out_eviction_priority = static_cast<Real*>(this)->eviction_priority;
272 return S_OK;
273 }
274
275 virtual HRESULT STDMETHODCALLTYPE GetDevice(
276 REFIID riid,
277 void **out_parent)
278 {
279 if(!static_cast<Real*>(this)->device)
280 return E_NOINTERFACE;
281 return static_cast<Real*>(this)->device->QueryInterface(riid, out_parent);
282 }
283
284 virtual HRESULT STDMETHODCALLTYPE GetParent(
285 REFIID riid,
286 void **out_parent)
287 {
288 if(!static_cast<Real*>(this)->device)
289 return E_NOINTERFACE;
290 return static_cast<Real*>(this)->device->QueryInterface(riid, out_parent);
291 }
292 };
293
294 template<typename T>
295 struct com_traits<GalliumDXGIResource<T> > : public com_traits<IDXGIResource>
296 {};
297
298 template<typename Base = ID3D11Resource>
299 struct GalliumD3D11Resource
300 : public GalliumMultiComObject<
301 GalliumMultiPrivateDataComObject<
302 GalliumD3D11ResourceBase<Base>,
303 GalliumDXGIResource<GalliumD3D11Resource<Base> >
304 >,
305 IGalliumResource
306 >
307 {
308 struct pipe_resource* resource;
309 std::unordered_map<unsigned, pipe_transfer*> transfers;
310 float min_lod;
311 DXGI_USAGE dxgi_usage;
312
313 GalliumD3D11Resource(GalliumD3D11Screen* device = 0, struct pipe_resource* resource = 0, unsigned dxgi_usage = 0)
314 : resource(resource), min_lod(0), dxgi_usage(dxgi_usage)
315 {
316 this->device = device;
317 if(device)
318 device->AddRef();
319 this->eviction_priority = 0;
320 }
321
322 ~GalliumD3D11Resource()
323 {
324 pipe_resource_reference(&resource, 0);
325 }
326
327 virtual HRESULT STDMETHODCALLTYPE GetUsage(
328 DXGI_USAGE *out_usage
329 )
330 {
331 *out_usage = this->dxgi_usage;
332 return S_OK;
333 }
334
335 virtual HRESULT STDMETHODCALLTYPE GetSharedHandle(HANDLE *out_shared_handle)
336 {
337 return E_NOTIMPL;
338 }
339
340 virtual struct pipe_resource* STDMETHODCALLTYPE GetGalliumResource()
341 {
342 return resource;
343 }
344 };
345
346 template<typename Base, typename Desc, D3D11_RESOURCE_DIMENSION Dim>
347 struct GalliumD3D11TypedResource : public GalliumD3D11Resource<Base>
348 {
349 Desc desc;
350 GalliumD3D11TypedResource() {}
351 GalliumD3D11TypedResource(GalliumD3D11Screen* device, struct pipe_resource* resource, const Desc& desc, unsigned dxgi_usage)
352 : GalliumD3D11Resource<Base>(device, resource, dxgi_usage), desc(desc)
353 {}
354 virtual void STDMETHODCALLTYPE GetType(
355 D3D11_RESOURCE_DIMENSION *out_resource_dimension)
356 {
357 *out_resource_dimension = Dim;
358 }
359 virtual void STDMETHODCALLTYPE GetDesc(Desc *out_desc)
360 {
361 memcpy(out_desc, &desc, sizeof(desc));
362 }
363 };
364
365 typedef GalliumD3D11TypedResource<ID3D11Texture1D, D3D11_TEXTURE1D_DESC, D3D11_RESOURCE_DIMENSION_TEXTURE1D> GalliumD3D11Texture1DBase;
366 typedef GalliumD3D11TypedResource<ID3D11Texture2D, D3D11_TEXTURE2D_DESC, D3D11_RESOURCE_DIMENSION_TEXTURE2D> GalliumD3D11Texture2DBase;
367 typedef GalliumD3D11TypedResource<ID3D11Texture3D, D3D11_TEXTURE3D_DESC, D3D11_RESOURCE_DIMENSION_TEXTURE3D> GalliumD3D11Texture3DBase;
368 typedef GalliumD3D11TypedResource<ID3D11Buffer, D3D11_BUFFER_DESC, D3D11_RESOURCE_DIMENSION_BUFFER> GalliumD3D11BufferBase;
369
370 #if API >= 11
371 typedef GalliumD3D11Texture1DBase GalliumD3D11Texture1D;
372 typedef GalliumD3D11Texture2DBase GalliumD3D11Texture2D;
373 typedef GalliumD3D11Texture3DBase GalliumD3D11Texture3D;
374
375 struct GalliumD3D11Buffer : public GalliumD3D11BufferBase
376 {
377 struct pipe_stream_output_target* so_target;
378
379 GalliumD3D11Buffer(GalliumD3D11Screen* device, struct pipe_resource* resource, const D3D11_BUFFER_DESC& desc, unsigned dxgi_usage)
380 : GalliumD3D11BufferBase(device, resource, desc, dxgi_usage), so_target(0)
381 {
382 }
383
384 ~GalliumD3D11Buffer()
385 {
386 if(so_target)
387 pipe_so_target_reference(&so_target, NULL);
388 }
389 };
390 #else
391 struct GalliumD3D10Buffer : public GalliumD3D10BufferBase
392 {
393 struct pipe_stream_output_target *so_target;
394
395 GalliumD3D10Buffer(GalliumD3D10Screen* device, struct pipe_resource* resource, const D3D10_BUFFER_DESC& desc, unsigned dxgi_usage)
396 : GalliumD3D10BufferBase(device, resource, desc, dxgi_usage)
397 {
398 }
399
400 ~GalliumD3D10Buffer()
401 {
402 if(so_target)
403 pipe_so_target_reference(&so_target, NULL);
404
405 device->UnbindBuffer(this);
406 }
407
408 virtual HRESULT STDMETHODCALLTYPE Map(
409 D3D10_MAP map_type,
410 unsigned map_flags,
411 void **out_data)
412 {
413 D3D10_MAPPED_SUBRESOURCE msr;
414 HRESULT hr = device->Map(this, 0, map_type, map_flags, &msr);
415 if(!SUCCEEDED(hr))
416 return hr;
417 *out_data = msr.pData;
418 return S_OK;
419 }
420
421 virtual void STDMETHODCALLTYPE Unmap()
422 {
423 device->Unmap(this, 0);
424 }
425 };
426
427 struct GalliumD3D10Texture1D : public GalliumD3D10Texture1DBase
428 {
429 GalliumD3D10Texture1D(GalliumD3D10Screen* device, struct pipe_resource* resource, const D3D10_TEXTURE1D_DESC& desc, unsigned dxgi_usage)
430 : GalliumD3D10Texture1DBase(device, resource, desc, dxgi_usage)
431 {}
432
433 virtual HRESULT STDMETHODCALLTYPE Map(
434 unsigned subresource,
435 D3D10_MAP map_type,
436 unsigned map_flags,
437 void **out_data)
438 {
439 D3D10_MAPPED_SUBRESOURCE msr;
440 HRESULT hr = device->Map(this, subresource, map_type, map_flags, &msr);
441 if(!SUCCEEDED(hr))
442 return hr;
443 *out_data = msr.pData;
444 return S_OK;
445 }
446
447 virtual void STDMETHODCALLTYPE Unmap(
448 unsigned subresource
449 )
450 {
451 device->Unmap(this, subresource);
452 }
453 };
454
455 struct GalliumD3D10Texture2D : public GalliumD3D10Texture2DBase
456 {
457 GalliumD3D10Texture2D() {}
458 GalliumD3D10Texture2D(GalliumD3D10Screen* device, struct pipe_resource* resource, const D3D10_TEXTURE2D_DESC& desc, unsigned dxgi_usage)
459 : GalliumD3D10Texture2DBase(device, resource, desc, dxgi_usage)
460 {}
461
462 virtual HRESULT STDMETHODCALLTYPE Map(
463 unsigned subresource,
464 D3D10_MAP map_type,
465 unsigned map_flags,
466 D3D10_MAPPED_TEXTURE2D *out_mapped_subresource)
467 {
468 D3D10_MAPPED_SUBRESOURCE msr;
469 HRESULT hr = device->Map(this, subresource, map_type, map_flags, &msr);
470 if(!SUCCEEDED(hr))
471 return hr;
472 out_mapped_subresource->pData = msr.pData;
473 out_mapped_subresource->RowPitch = msr.RowPitch;
474 return S_OK;
475 }
476
477 virtual void STDMETHODCALLTYPE Unmap(
478 unsigned subresource
479 )
480 {
481 device->Unmap(this, subresource);
482 }
483 };
484
485
486 struct GalliumD3D10Texture3D : public GalliumD3D10Texture3DBase
487 {
488 GalliumD3D10Texture3D(GalliumD3D10Screen* device, struct pipe_resource* resource, const D3D10_TEXTURE3D_DESC& desc, unsigned dxgi_usage)
489 : GalliumD3D10Texture3DBase(device, resource, desc, dxgi_usage)
490 {}
491
492 virtual HRESULT STDMETHODCALLTYPE Map(
493 unsigned subresource,
494 D3D10_MAP map_type,
495 unsigned map_flags,
496 D3D10_MAPPED_TEXTURE3D *out_mapped_subresource)
497 {
498 D3D10_MAPPED_SUBRESOURCE msr;
499 HRESULT hr = device->Map(this, subresource, map_type, map_flags, &msr);
500 if(!SUCCEEDED(hr))
501 return hr;
502 out_mapped_subresource->pData = msr.pData;
503 out_mapped_subresource->RowPitch = msr.RowPitch;
504 out_mapped_subresource->DepthPitch = msr.DepthPitch;
505 return S_OK;
506 }
507
508 virtual void STDMETHODCALLTYPE Unmap(
509 unsigned subresource
510 )
511 {
512 device->Unmap(this, subresource);
513 }
514 };
515 #endif
516
517 struct GalliumD3D11Surface : public GalliumMultiPrivateDataComObject<GalliumD3D11Texture2D, IDXGISurface1>
518 {
519 GalliumD3D11Surface(GalliumD3D11Screen* device, struct pipe_resource* resource, const D3D11_TEXTURE2D_DESC& desc, unsigned dxgi_usage)
520 {
521 this->device = device;
522 this->device->AddRef();
523 this->resource = resource;
524 this->desc = desc;
525 this->dxgi_usage = dxgi_usage;
526 }
527
528 virtual HRESULT STDMETHODCALLTYPE GetDesc(
529 DXGI_SURFACE_DESC *out_desc)
530 {
531 out_desc->Format = this->desc.Format;
532 out_desc->Width = this->desc.Width;
533 out_desc->Height = this->desc.Height;
534 out_desc->SampleDesc = this->desc.SampleDesc;
535 return S_OK;
536 }
537
538 virtual HRESULT STDMETHODCALLTYPE GetParent(
539 REFIID riid,
540 void **out_parent)
541 {
542 if(!device)
543 return E_NOINTERFACE;
544 return device->QueryInterface(riid, out_parent);
545 }
546
547 /* TODO: somehow implement these */
548 virtual HRESULT STDMETHODCALLTYPE GetDC(
549 BOOL discard,
550 HDC *out_hdc)
551 {
552 *out_hdc = 0;
553 return E_NOTIMPL;
554 }
555
556 virtual HRESULT STDMETHODCALLTYPE ReleaseDC(
557 RECT *out_dirty_rect)
558 {
559 return E_NOTIMPL;
560 }
561
562 virtual HRESULT STDMETHODCALLTYPE Map(
563 DXGI_MAPPED_RECT *out_locked_rect,
564 unsigned map_flags)
565 {
566 D3D11_MAP d3d_map;
567 if(map_flags & DXGI_MAP_DISCARD)
568 d3d_map = D3D11_MAP_WRITE_DISCARD;
569 else
570 {
571 if(map_flags & DXGI_MAP_READ)
572 {
573 if(map_flags & DXGI_MAP_WRITE)
574 d3d_map = D3D11_MAP_READ_WRITE;
575 else
576 d3d_map = D3D11_MAP_READ;
577 }
578 else
579 d3d_map = D3D11_MAP_WRITE;
580 }
581 D3D11_MAPPED_SUBRESOURCE d3d_mapped;
582 HRESULT hres = this->device->get_immediate_context()->Map(this, 0, d3d_map, 0, &d3d_mapped);
583 out_locked_rect->pBits = (uint8_t*)d3d_mapped.pData;
584 out_locked_rect->Pitch = d3d_mapped.RowPitch;
585 return hres;
586 }
587
588 virtual HRESULT STDMETHODCALLTYPE Unmap(void)
589 {
590 this->device->get_immediate_context()->Unmap(this, 0);
591 return S_OK;
592 }
593
594 virtual HRESULT STDMETHODCALLTYPE GetDevice(
595 REFIID riid,
596 void **out_parent)
597 {
598 if(!device)
599 return E_NOINTERFACE;
600 return device->QueryInterface(riid, out_parent);
601 }
602 };
603
604 template<typename Base, typename Desc, typename Object>
605 struct GalliumD3D11View : public GalliumD3D11DescribedObject<Base, Desc, Object>
606 {
607 GalliumD3D11Resource<>* resource;
608 GalliumD3D11View(GalliumD3D11Screen* device, GalliumD3D11Resource<>* resource, Object* object, const Desc& desc)
609 : GalliumD3D11DescribedObject<Base, Desc, Object>(device, object, desc), resource(resource)
610 {
611 resource->AddRef();
612 }
613
614 ~GalliumD3D11View()
615 {
616 resource->Release();
617 }
618
619 virtual void STDMETHODCALLTYPE GetResource(ID3D11Resource** out_resource)
620 {
621 resource->AddRef();
622 *out_resource = resource;
623 }
624 };
625
626 typedef GalliumD3D11View<ID3D11DepthStencilView, D3D11_DEPTH_STENCIL_VIEW_DESC, struct pipe_surface> GalliumD3D11DepthStencilView;
627 typedef GalliumD3D11View<ID3D11RenderTargetView, D3D11_RENDER_TARGET_VIEW_DESC, struct pipe_surface> GalliumD3D11RenderTargetView;
628
629 #if API >= 11
630 typedef GalliumD3D11View<ID3D11ShaderResourceView, D3D11_SHADER_RESOURCE_VIEW_DESC, struct pipe_sampler_view> GalliumD3D11ShaderResourceView;
631 #else
632 typedef GalliumD3D10View<ID3D10ShaderResourceView1, D3D10_SHADER_RESOURCE_VIEW_DESC1, struct pipe_sampler_view> GalliumD3D10ShaderResourceViewBase;
633
634 struct GalliumD3D10ShaderResourceView : public GalliumD3D10ShaderResourceViewBase
635 {
636 GalliumD3D10ShaderResourceView(GalliumD3D10Screen* device, GalliumD3D10Resource<>* resource, struct pipe_sampler_view* view, const D3D10_SHADER_RESOURCE_VIEW_DESC1& desc)
637 : GalliumD3D10ShaderResourceViewBase(device, resource, view, desc)
638 {}
639
640 virtual void STDMETHODCALLTYPE GetDesc1(D3D10_SHADER_RESOURCE_VIEW_DESC1 *out_desc)
641 {
642 memcpy(out_desc, &desc, sizeof(*out_desc));
643 }
644
645 virtual void STDMETHODCALLTYPE GetDesc(D3D10_SHADER_RESOURCE_VIEW_DESC *out_desc)
646 {
647 memcpy(out_desc, &desc, sizeof(*out_desc));
648 }
649 };
650 #endif
651
652 template<typename Base = ID3D11Asynchronous>
653 struct GalliumD3D11Asynchronous : public GalliumD3D11DeviceChild<Base>
654 {
655 struct pipe_query* query;
656 unsigned data_size;
657
658 GalliumD3D11Asynchronous(GalliumD3D11Screen* device, struct pipe_query* query, unsigned data_size)
659 : GalliumD3D11DeviceChild<Base>(device), query(query), data_size(data_size)
660 {}
661
662 ~GalliumD3D11Asynchronous()
663 {
664 this->device->immediate_pipe->destroy_query(this->device->immediate_pipe, query);
665 }
666
667 virtual unsigned STDMETHODCALLTYPE GetDataSize()
668 {
669 return data_size;
670 }
671
672 #if API < 11
673 virtual void STDMETHODCALLTYPE Begin()
674 {
675 this->device->Begin(this);
676 }
677
678 virtual void STDMETHODCALLTYPE End()
679 {
680 this->device->End(this);
681 }
682
683 virtual HRESULT STDMETHODCALLTYPE GetData(
684 void * out_data,
685 unsigned data_size,
686 unsigned get_data_flags)
687 {
688 return this->device->GetData(this, out_data, data_size, get_data_flags);
689 }
690 #endif
691 };
692
693 template<typename Base = ID3D11Asynchronous>
694 struct GalliumD3D11QueryOrPredicate : public GalliumD3D11Asynchronous<Base>
695 {
696 D3D11_QUERY_DESC desc;
697 GalliumD3D11QueryOrPredicate(GalliumD3D11Screen* device, struct pipe_query* query, unsigned data_size, const D3D11_QUERY_DESC& desc)
698 : GalliumD3D11Asynchronous<Base>(device, query, data_size), desc(desc)
699 {}
700
701 virtual void STDMETHODCALLTYPE GetDesc(
702 D3D11_QUERY_DESC *out_desc)
703 {
704 *out_desc = desc;
705 }
706 };
707
708 struct GalliumD3D11Query : public GalliumD3D11QueryOrPredicate<ID3D11Query>
709 {
710 GalliumD3D11Query(GalliumD3D11Screen* device, struct pipe_query* query, unsigned data_size, const D3D11_QUERY_DESC& desc)
711 : GalliumD3D11QueryOrPredicate<ID3D11Query>(device, query, data_size, desc)
712 {}
713 };
714
715 struct GalliumD3D11Predicate : public GalliumD3D11QueryOrPredicate<ID3D11Predicate>
716 {
717 GalliumD3D11Predicate(GalliumD3D11Screen* device, struct pipe_query* query, unsigned data_size, const D3D11_QUERY_DESC& desc)
718 : GalliumD3D11QueryOrPredicate<ID3D11Predicate>(device, query, data_size, desc)
719 {}
720
721 ~GalliumD3D11Predicate()
722 {
723 DX10_ONLY(device->UnbindPredicate(this));
724 }
725 };
726
727 struct GalliumD3D11Counter : public GalliumD3D11Asynchronous<ID3D11Counter>
728 {
729 D3D11_COUNTER_DESC desc;
730 GalliumD3D11Counter(GalliumD3D11Screen* device, struct pipe_query* query, unsigned data_size, const D3D11_COUNTER_DESC& desc)
731 : GalliumD3D11Asynchronous<ID3D11Counter>(device, query, data_size), desc(desc)
732 {}
733
734 virtual void STDMETHODCALLTYPE GetDesc(
735 D3D11_COUNTER_DESC *out_desc)
736 {
737 *out_desc = desc;
738 }
739 };