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 #ifndef D3D1XSTUTIL_H_
28 #define D3D1XSTUTIL_H_
29 
30 #ifdef _MSC_VER
31 #include <unordered_map>
32 #include <unordered_set>
33 #else
34 #include <tr1/unordered_map>
35 #include <tr1/unordered_set>
36 namespace std
37 {
38 	using namespace tr1;
39 }
40 #endif
41 #include <map>
42 #include <utility>
43 
44 #define WIN32_LEAN_AND_MEAN
45 #include <objbase.h>
46 
47 #include "galliumdxgi.h"
48 #include <d3dcommon.h>
49 
50 extern "C"
51 {
52 #include "util/u_atomic.h"
53 #include "pipe/p_format.h"
54 #include "os/os_thread.h"
55 }
56 
57 #include <assert.h>
58 #ifdef min
59 #undef min
60 #endif
61 #ifdef max
62 #undef max
63 #endif
64 
65 #define D3D_PRIMITIVE_TOPOLOGY_COUNT 65
66 extern unsigned d3d_to_pipe_prim[D3D_PRIMITIVE_TOPOLOGY_COUNT];
67 
68 #define D3D_PRIMITIVE_COUNT 40
69 extern unsigned d3d_to_pipe_prim_type[D3D_PRIMITIVE_COUNT];
70 
71 /* NOTE: this _depends_ on the vtable layout of the C++ compiler to be
72  * binary compatible with Windows.
73  * Furthermore some absurd vtable layout likely won't work at all, since
74  * we perform some casts which are probably not safe by the C++ standard.
75  *
76  * In particular, the GNU/Linux/Itanium/clang ABI and Microsoft ABIs will work,
77  * but others may not.
78  * If in doubt, just switch to the latest version of a widely used C++ compiler.
79  *
80  * DESIGN of the Gallium COM implementation
81  *
82  * This state tracker uses somewhat unusual C++ coding patterns,
83  * to implement the COM interfaces required by Direct3D.
84  *
85  * While it may seem complicated, the effect is that the result
86  * generally behaves as intuitively as possible: in particular pointer
87  * casts very rarely change the pointer value (only for secondary
88  * DXGI/Gallium interfaces)
89  *
90  * Implementing COM is on first sight very easy: after all, it just
91  * consists of a reference count, and a dynamic_cast<> equivalent.
92  *
93  * However, implementing objects with multiple interfaces is actually
94  * quite tricky.
95  * The issue is that the interface pointers can't be equal, since this
96  * would place incompatible constraints on the vtable layout and thus
97  * multiple inheritance (and the subobjects the C++ compiler creates
98  * with it) must be correctly used.
99  *
100  * Furthermore, we must have a single reference count, which means
101  * that a naive implementation won't work, and it's necessary to either
102  * use virtual inheritance, or the "mixin inheritance" model we use.
103  *
104  * This solution aims to achieve the following object layout:
105  * 0: pointer to vtable for primary interface
106  * 1: reference count
107  * ... main class
108  * ... vtable pointers for secondary interfaces
109  * ... implementation of subclasses assuming secondary interfaces
110  *
111  * This allows us to cast pointers by just reinterpreting the value in
112  * almost all cases.
113  *
114  * To achieve this, *all* non-leaf classes must have their parent
115  * or the base COM interface as a template parameter, since derived
116  * classes may need to change that to support an interface derived
117  * from the one implemented by the superclass.
118  *
119  * Note however, that you can cast without regard to the template
120  * parameter, because only the vtable layout depends on it, since
121  * interfaces have no data members.
122  *
123  * For this to work, DON'T USE VIRTUAL FUNCTIONS except to implement
124  * interfaces, since the vtable layouts would otherwise be mismatched.
125  * An exception are virtual functions called only from other virtual functions,
126  * which is currently only used for the virtual destructor.
127  *
128  * The base class is GalliumComObject<IFoo>, which implements the
129  * IUnknown interface, and inherits IFoo.
130  *
131  * To support multiple inheritance, we insert GalliumMultiComObject,
132  * which redirects the secondary interfaces to the GalliumComObject
133  * superclass.
134  *
135  * Gallium(Multi)PrivateDataComObject is like ComObject but also
136  * implements the Get/SetPrivateData functions present on several
137  * D3D/DXGI interfaces.
138  *
139  * Example class hierarchy:
140  *
141  * IUnknown
142  * (pure interface)
143  * |
144  * V
145  * IAnimal
146  * (pure interface)
147  * |
148  * V
149  * IDuck
150  * (pure interface)
151  * |
152  * V
153  * GalliumComObject<IDuck>
154  * (non-instantiable, only implements IUnknown)
155  * |
156  * V
157  * GalliumAnimal<IDuck>
158  * (non-instantiable, only implements IAnimal)
159  * |
160  * V
161  * GalliumDuck
162  * (concrete)
163  * |
164  * V
165  * GalliumMultiComObject<GalliumDuck, IWheeledVehicle> <- IWheeledVehicle <- IVehicle <- IUnknown (second version)
166  * (non-instantiable, only implements IDuck and the IUnknown of IWheeledVehicle)
167  * |
168  * V
169  * GalliumDuckOnWheels
170  * (concrete)
171  *
172  * This will produce the desired layout.
173  * Note that GalliumAnimal<IFoo>* is safely castable to GalliumAnimal<IBar>*
174  * by reinterpreting, as long as non-interface virtual functions are not used,
175  * and that you only call interface functions for the superinterface of IBar
176  * that the object actually implements.
177  *
178  * Instead, if GalliumDuck where to inherit both from GalliumAnimal
179  * and IDuck, then (IDuck*)gallium_duck and (IAnimal*)gallium_duck would
180  * have different pointer values, which the "base class as template parameter"
181  * trick avoids.
182  *
183  * The price we pay is that you MUST NOT have virtual functions other than those
184  * implementing interfaces (except for leaf classes) since the position of these
185  * would depend on the base interface.
186  * As mentioned above, virtual functions only called from interface functions
187  * are an exception, currently used only for the virtual destructor.
188  * If you want virtual functions anyway , put them in a separate interface class,
189  * multiply inherit from that and cast the pointer to that interface.
190  *
191  * You CAN however have virtual functions on any class which does not specify
192  * his base as a template parameter, or where you don't need to change the
193  * template base interface parameter by casting.
194  *
195  * --- The magic QueryInterface "delete this" trick ---
196  *
197  * When the reference count drops to 0, we must delete the class.
198  * The problem is, that we must call the right virtual destructor (i.e. on the right class).
199  * However, we would like to be able to call release() and nonatomic_release()
200  * non-virtually for performance (also, the latter cannot be called virtually at all, since
201  * IUnknown does not offer it).
202  *
203  * The naive solution would be to just add a virtual destructor and rely on it.
204  * However, this doesn't work due to the fact that as described above we perform casets
205  * with are unsafe regarding vtable layout.
206  * In particular, consider the case where we try to delete GalliumComObject<ID3D11Texture2D>
207  * with a pointer to GalliumComObject<ID3D11Resource>.
208  * Since we think that this is a GalliumComObject<ID3D11Resource>, we'll look for the
209  * destructor in the vtable slot immediately after the ID3D11Resource vtable, but this is
210  * actually an ID3D11Texture2D function implemented by the object!
211  *
212  * So, we must put the destructor somewhere else.
213  * We could add it as a data member, but it would be awkward and it would bloat the
214  * class.
215  * Thus, we use this trick: we reuse the vtable slot for QueryInterface, which is always at the
216  * same position.
217  * To do so, we define a special value for the first pointer argument, that triggers a
218  * "delete this".
219  * In addition to that, we add a virtual destructor to GalliumComObject.
220  * That virtual destructor will be called by QueryInterface, and since that is a virtual
221  * function, it will know the correct place for the virtual destructor.
222  *
223  * QueryInterface is already slow due to the need to compare several GUIDs, so the
224  * additional pointer test should not be significant.
225  *
226  * Of course the ideal solution would be telling the C++ compiler to put the
227  * destructor it in a negative vtable slot, but unfortunately GCC doesn't support that
228  * yet, and this method is almost as good as that.
229  */
230 
231 template<typename T>
232 struct com_traits;
233 
234 #define COM_INTERFACE(intf, base) \
235 template<> \
236 struct com_traits<intf> \
237 { \
238 	static REFIID iid() {return IID_##intf;} \
239 	static inline bool is_self_or_ancestor(REFIID riid) {return riid == iid() || com_traits<base>::is_self_or_ancestor(riid);} \
240 };
241 
242 template<>
243 struct com_traits<IUnknown>
244 {
245 	static REFIID iid() {return IID_IUnknown;}
246 	static inline bool is_self_or_ancestor(REFIID riid) {return riid == iid();}
247 };
248 
249 #ifndef _MSC_VER
250 #define __uuidof(T) (com_traits<T>::iid())
251 #endif
252 
253 struct refcnt_t
254 {
255 	uint32_t refcnt;
256 
257 	refcnt_t(unsigned v = 1)
258 	: refcnt(v)
259 	{}
260 
261 	unsigned add_ref()
262 	{
263 		p_atomic_inc((int32_t*)&refcnt);
264 		return refcnt;
265 	}
266 
267 	unsigned release()
268 	{
269 		if(p_atomic_dec_zero((int32_t*)&refcnt))
270 			return 0;
271 		return refcnt;
272 	}
273 
274 	void nonatomic_add_ref()
275 	{
276 		p_atomic_inc((int32_t*)&refcnt);
277 	}
278 
279 	unsigned nonatomic_release()
280 	{
281 		if(p_atomic_dec_zero((int32_t*)&refcnt))
282 			return 0;
283 		else
284 			return 1;
285 	}
286 };
287 
288 #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)
289 /* this should be safe because atomic ops are full memory barriers, and thus a sequence that does:
290  * ++one_refcnt;
291  * --other_refcnt;
292  * should never be reorderable (as seen from another CPU) to:
293  * --other_refcnt
294  * ++one_refcnt
295  *
296  * since one of the ops is atomic.
297  * If this weren't the case, a CPU could incorrectly destroy an object manipulated in that way by another one.
298  */
299 struct dual_refcnt_t
300 {
301 	union
302 	{
303 		uint64_t refcnt;
304 		struct
305 		{
306 			uint32_t atomic_refcnt;
307 			uint32_t nonatomic_refcnt;
308 		};
309 	};
310 
311 	dual_refcnt_t(unsigned v = 1)
312 	{
313 		atomic_refcnt = v;
314 		nonatomic_refcnt = 0;
315 	}
316 
317 	bool is_zero()
318 	{
319 		if(sizeof(void*) == 8)
320 			return *(volatile uint64_t*)&refcnt == 0ULL;
321 		else
322 		{
323 			uint64_t v;
324 			do
325 			{
326 				v = refcnt;
327 			}
328 			while(!__sync_bool_compare_and_swap(&refcnt, v, v));
329 			return v == 0ULL;
330 		}
331 	}
332 
333 	unsigned add_ref()
334 	{
335 		//printf("%p add_ref at %u %u\n", this, atomic_refcnt, nonatomic_refcnt);
336 		p_atomic_inc((int32_t*)&atomic_refcnt);
337 		return atomic_refcnt + nonatomic_refcnt;
338 	}
339 
340 	unsigned release()
341 	{
342 		//printf("%p release at %u %u\n", this, atomic_refcnt, nonatomic_refcnt);
343 		if(p_atomic_dec_zero((int32_t*)&atomic_refcnt) && !nonatomic_refcnt && is_zero())
344 			return 0;
345 		unsigned v = atomic_refcnt + nonatomic_refcnt;
346 		return v ? v : 1;
347 	}
348 
349 	void nonatomic_add_ref()
350 	{
351 		//printf("%p nonatomic_add_ref at %u %u\n", this, atomic_refcnt, nonatomic_refcnt);
352 		++nonatomic_refcnt;
353 	}
354 
355 	unsigned nonatomic_release()
356 	{
357 		//printf("%p nonatomic_release at %u %u\n", this, atomic_refcnt, nonatomic_refcnt);
358 		if(!--nonatomic_refcnt)
359 		{
360 			__sync_synchronize();
361 			if(!atomic_refcnt && is_zero())
362 				return 0;
363 		}
364 		return 1;
365 	}
366 };
367 #else
368 // this will result in atomic operations being used while they could have been avoided
369 #ifdef __i386__
370 #warning Compile for 586+ using GCC to improve the performance of the Direct3D 10/11 state tracker
371 #endif
372 typedef refcnt_t dual_refcnt_t;
373 #endif
374 
375 #define IID_MAGIC_DELETE_THIS (*(const IID*)((intptr_t)-(int)(sizeof(IID) - 1)))
376 
377 template<typename Base = IUnknown, typename RefCnt = refcnt_t>
378 struct GalliumComObject : public Base
379 {
380 	RefCnt refcnt;
381 
382 	GalliumComObject()
383 	{}
384 
385 	/* DO NOT CALL this from externally called non-virtual functions in derived classes, since
386 	 * the vtable position depends on the COM interface being implemented
387 	 */
388 	virtual ~GalliumComObject()
389 	{}
390 
391 	inline ULONG add_ref()
392 	{
393 		return refcnt.add_ref();
394 	}
395 
396 	inline ULONG release()
397 	{
398 		ULONG v = refcnt.release();
399 		if(!v)
400 		{
401 			/* this will call execute "delete this", using the correct vtable slot for the destructor */
402 			/* see the initial comment for an explaination of this magic trick */
403 			this->QueryInterface(IID_MAGIC_DELETE_THIS, 0);
404 			return 0;
405 		}
406 		return v;
407 	}
408 
409 	inline void nonatomic_add_ref()
410 	{
411 		refcnt.nonatomic_add_ref();
412 	}
413 
414 	inline void nonatomic_release()
415 	{
416 		if(!refcnt.nonatomic_release())
417 		{
418 			/* this will execute "delete this", using the correct vtable slot for the destructor */
419 			/* see the initial comment for an explaination of this magic trick */
420 			this->QueryInterface(IID_MAGIC_DELETE_THIS, 0);
421 		}
422 	}
423 
424 	inline HRESULT query_interface(REFIID riid, void **ppvObject)
425 	{
426 		if(com_traits<Base>::is_self_or_ancestor(riid))
427 		{
428 			// must be the virtual AddRef, since it is overridden by some classes
429 			this->AddRef();
430 			*ppvObject = this;
431 			return S_OK;
432 		}
433 		else
434 			return E_NOINTERFACE;
435 	}
436 
437 	virtual ULONG STDMETHODCALLTYPE AddRef()
438 	{
439 		return add_ref();
440 	}
441 
442 	virtual ULONG STDMETHODCALLTYPE Release()
443 	{
444 		return release();
445 	}
446 
447 	virtual HRESULT STDMETHODCALLTYPE QueryInterface(
448 		REFIID riid,
449 		void **ppvObject)
450 	{
451 		/* see the initial comment for an explaination of this magic trick */
452 		if(&riid == &IID_MAGIC_DELETE_THIS)
453 		{
454 			delete this;
455 			return 0;
456 		}
457 		if(!this)
458 			return E_INVALIDARG;
459 		if(!ppvObject)
460 			return E_POINTER;
461 		return query_interface(riid, ppvObject);
462 	}
463 };
464 
465 template<typename BaseClass, typename SecondaryInterface>
466 struct GalliumMultiComObject : public BaseClass, SecondaryInterface
467 {
468 	// we could avoid this duplication, but the increased complexity to do so isn't worth it
469 	virtual ULONG STDMETHODCALLTYPE AddRef()
470 	{
471 		return BaseClass::add_ref();
472 	}
473 
474 	virtual ULONG STDMETHODCALLTYPE Release()
475 	{
476 		return BaseClass::release();
477 	}
478 
479 	inline HRESULT query_interface(REFIID riid, void **ppvObject)
480 	{
481 		HRESULT hr = BaseClass::query_interface(riid, ppvObject);
482 		if(SUCCEEDED(hr))
483 			return hr;
484 		if(com_traits<SecondaryInterface>::is_self_or_ancestor(riid))
485 		{
486 			// must be the virtual AddRef, since it is overridden by some classes
487 			this->AddRef();
488 			*ppvObject = (SecondaryInterface*)this;
489 			return S_OK;
490 		}
491 		else
492 			return E_NOINTERFACE;
493 	}
494 
495 	virtual HRESULT STDMETHODCALLTYPE QueryInterface(
496 		REFIID riid,
497 		void **ppvObject)
498 	{
499 		/* see the initial comment for an explaination of this magic trick */
500 		if(&riid == &IID_MAGIC_DELETE_THIS)
501 		{
502 			delete this;
503 			return 0;
504 		}
505 		if(!this)
506 			return E_INVALIDARG;
507 		if(!ppvObject)
508 			return E_POINTER;
509 		return query_interface(riid, ppvObject);
510 	}
511 };
512 
513 template<typename T, typename Traits>
514 struct refcnt_ptr
515 {
516 	T* p;
517 
518 	refcnt_ptr()
519 	: p(0)
520 	{}
521 
522 	void add_ref() {Traits::add_ref(p);}
523 	void release() {Traits::release(p);}
524 
525 	template<typename U, typename UTraits>
526 	refcnt_ptr(const refcnt_ptr<U, UTraits>& c)
527 	{
528 		*this = static_cast<U*>(c.ref());
529 	}
530 
531 	~refcnt_ptr()
532 	{
533 		release();
534 	}
535 
536 	void reset(T* q)
537 	{
538 		release();
539 		p = q;
540 	}
541 
542 	template<typename U, typename UTraits>
543 	refcnt_ptr& operator =(const refcnt_ptr<U, UTraits>& q)
544 	{
545 		return *this = q.p;
546 	}
547 
548 	template<typename U>
549 	refcnt_ptr& operator =(U* q)
550 	{
551 		release();
552 		p = static_cast<T*>(q);
553 		add_ref();
554 		return *this;
555 	}
556 
557 	T* ref()
558 	{
559 		add_ref();
560 		return p;
561 	}
562 
563 	T* steal()
564 	{
565 		T* ret = p;
566 		p = 0;
567 		return ret;
568 	}
569 
570 	T* operator ->()
571 	{
572 		return p;
573 	}
574 
575 	const T* operator ->() const
576 	{
577 		return p;
578 	}
579 
580 	T** operator &()
581 	{
582 		assert(!p);
583 		return &p;
584 	}
585 
586 	bool operator !() const
587 	{
588 		return !p;
589 	}
590 
591 	typedef T* refcnt_ptr::*unspecified_bool_type;
592 
593 	operator unspecified_bool_type() const
594 	{
595 		return p ? &refcnt_ptr::p : 0;
596 	}
597 };
598 
599 struct simple_ptr_traits
600 {
601 	static void add_ref(void* p) {}
602 	static void release(void* p) {}
603 };
604 
605 struct com_ptr_traits
606 {
607 	static void add_ref(void* p)
608 	{
609 		if(p)
610 			((IUnknown*)p)->AddRef();
611 	}
612 
613 	static void release(void* p)
614 	{
615 		if(p)
616 			((IUnknown*)p)->Release();
617 	}
618 };
619 
620 template<typename T>
621 struct ComPtr : public refcnt_ptr<T, com_ptr_traits>
622 {
623 	template<typename U, typename UTraits>
624 	ComPtr& operator =(const refcnt_ptr<U, UTraits>& q)
625 	{
626 		return *this = q.p;
627 	}
628 
629 	template<typename U>
630 	ComPtr& operator =(U* q)
631 	{
632 		this->release();
633 		this->p = static_cast<T*>(q);
634 		this->add_ref();
635 		return *this;
636 	}
637 };
638 
639 template<typename T, typename TTraits, typename U, typename UTraits>
640 bool operator ==(const refcnt_ptr<T, TTraits>& a, const refcnt_ptr<U, UTraits>& b)
641 {
642 	return a.p == b.p;
643 }
644 
645 template<typename T, typename TTraits, typename U>
646 bool operator ==(const refcnt_ptr<T, TTraits>& a, U* b)
647 {
648 	return a.p == b;
649 }
650 
651 template<typename T, typename TTraits, typename U>
652 bool operator ==(U* b, const refcnt_ptr<T, TTraits>& a)
653 {
654 	return a.p == b;
655 }
656 
657 template<typename T, typename TTraits, typename U, typename UTraits>
658 bool operator !=(const refcnt_ptr<T, TTraits>& a, const refcnt_ptr<U, UTraits>& b)
659 {
660 	return a.p != b.p;
661 }
662 
663 template<typename T, typename TTraits, typename U>
664 bool operator !=(const refcnt_ptr<T, TTraits>& a, U* b)
665 {
666 	return a.p != b;
667 }
668 
669 template<typename T, typename TTraits, typename U>
670 bool operator !=(U* b, const refcnt_ptr<T, TTraits>& a)
671 {
672 	return a.p != b;
673 }
674 
675 template<bool threadsafe>
676 struct maybe_mutex_t;
677 
678 template<>
679 struct maybe_mutex_t<true>
680 {
681 	pipe_mutex mutex;
682 
683 	maybe_mutex_t()
684 	{
685 		pipe_mutex_init(mutex);
686 	}
687 
688 	void lock()
689 	{
690 		pipe_mutex_lock(mutex);
691 	}
692 
693 	void unlock()
694 	{
695 		pipe_mutex_unlock(mutex);
696 	}
697 };
698 
699 template<>
700 struct maybe_mutex_t<false>
701 {
702 	void lock()
703 	{
704 	}
705 
706 	void unlock()
707 	{
708 	}
709 };
710 
711 typedef maybe_mutex_t<true> mutex_t;
712 
713 template<typename T>
714 struct lock_t
715 {
716 	T& mutex;
717 	lock_t(T& mutex)
718 	: mutex(mutex)
719 	{
720 		mutex.lock();
721 	}
722 
723 	~lock_t()
724 	{
725 		mutex.unlock();
726 	}
727 };
728 
729 struct c_string
730 {
731 	const char* p;
732 	c_string(const char* p)
733 	: p(p)
734 	{}
735 
736 	operator const char*() const
737 	{
738 		return p;
739 	}
740 };
741 
742 static inline bool operator ==(const c_string& a, const c_string& b)
743 {
744 	return !strcmp(a.p, b.p);
745 }
746 
747 static inline bool operator !=(const c_string& a, const c_string& b)
748 {
749 	return strcmp(a.p, b.p);
750 }
751 
752 static inline size_t raw_hash(const char* p, size_t size)
753 {
754 	size_t res;
755 	if(sizeof(size_t) >= 8)
756 		res = (size_t)14695981039346656037ULL;
757 	else
758 		res = (size_t)2166136261UL;
759 	const char* end = p + size;
760 	for(; p != end; ++p)
761 	{
762 		res ^= (size_t)*p;
763 		if(sizeof(size_t) >= 8)
764 			res *= (size_t)1099511628211ULL;
765 		else
766 			res *= (size_t)16777619UL;
767 	}
768 	return res;
769 };
770 
771 template<typename T>
772 static inline size_t raw_hash(const T& t)
773 {
774 	return raw_hash((const char*)&t, sizeof(t));
775 }
776 
777 // TODO: only tested with the gcc libstdc++, might not work elsewhere
778 namespace std
779 {
780 #ifndef _MSC_VER
781 	namespace tr1
782 	{
783 #endif
784 		template<>
785 		struct hash<GUID> : public std::unary_function<GUID, size_t>
786 		{
787 			inline size_t operator()(GUID __val) const;
788 		};
789 
790 		inline size_t hash<GUID>::operator()(GUID __val) const
791 		{
792 			return raw_hash(__val);
793 		}
794 
795 		template<>
796 		struct hash<c_string> : public std::unary_function<c_string, size_t>
797 		{
798 			inline size_t operator()(c_string __val) const;
799 		};
800 
801 		inline size_t hash<c_string>::operator()(c_string __val) const
802 		{
803 			return raw_hash(__val.p, strlen(__val.p));
804 		}
805 
806 		template<typename T, typename U>
807 		struct hash<std::pair<T, U> > : public std::unary_function<std::pair<T, U>, size_t>
808 		{
809 			inline size_t operator()(std::pair<T, U> __val) const;
810 		};
811 
812 		template<typename T, typename U>
813 		inline size_t hash<std::pair<T, U> >::operator()(std::pair<T, U> __val) const
814 		{
815 			std::pair<size_t, size_t> p;
816 			p.first = hash<T>()(__val.first);
817 			p.second = hash<U>()(__val.second);
818 			return raw_hash(p);
819 		}
820 #ifndef _MSC_VER
821 	}
822 #endif
823 }
824 
825 template<typename Base, typename RefCnt = refcnt_t>
826 struct GalliumPrivateDataComObject : public GalliumComObject<Base, RefCnt>
827 {
828 	typedef std::unordered_map<GUID, std::pair<void*, unsigned> > private_data_map_t;
829 	private_data_map_t private_data_map;
830 	mutex_t private_data_mutex;
831 
832 	~GalliumPrivateDataComObject()
833 	{
834 		for(private_data_map_t::iterator i = private_data_map.begin(), e = private_data_map.end(); i != e; ++i)
835 		{
836 			if(i->second.second == ~0u)
837 				((IUnknown*)i->second.first)->Release();
838 			else
839 				free(i->second.first);
840 		}
841 	}
842 
843 	HRESULT get_private_data(
844 		REFGUID guid,
845 		UINT *pDataSize,
846 		void *pData)
847 	{
848 		lock_t<mutex_t> lock(private_data_mutex);
849 		private_data_map_t::iterator i = private_data_map.find(guid);
850 		*pDataSize = 0;
851 		if(i == private_data_map.end())
852 			return DXGI_ERROR_NOT_FOUND;
853 		if(i->second.second == ~0u)
854 		{
855 			/* TODO: is GetPrivateData on interface data supposed to do this? */
856 			if(*pDataSize < sizeof(void*))
857 				return E_INVALIDARG;
858 			if(pData)
859 			{
860 				memcpy(pData, &i->second.first, sizeof(void*));
861 				((IUnknown*)i->second.first)->AddRef();
862 			}
863 			*pDataSize = sizeof(void*);
864 		}
865 		else
866 		{
867 			unsigned size = std::min(*pDataSize, i->second.second);
868 			if(pData)
869 				memcpy(pData, i->second.first, size);
870 			*pDataSize = size;
871 		}
872 		return S_OK;
873 	}
874 
875 	HRESULT set_private_data(
876 		REFGUID guid,
877 		UINT DataSize,
878 		const void *pData)
879 	{
880 		void* p = 0;
881 
882 		if(DataSize && pData)
883 		{
884 			p = malloc(DataSize);
885 			if(!p)
886 				return E_OUTOFMEMORY;
887 		}
888 
889 		lock_t<mutex_t> lock(private_data_mutex);
890 		std::pair<void*, unsigned>& v = private_data_map[guid];
891 		if(v.first)
892 		{
893 			if(v.second == ~0u)
894 				((IUnknown*)v.first)->Release();
895 			else
896 				free(v.first);
897 		}
898 		if(DataSize && pData)
899 		{
900 			memcpy(p, pData, DataSize);
901 			v.first = p;
902 			v.second = DataSize;
903 		}
904 		else
905 			private_data_map.erase(guid);
906 		return S_OK;
907 	}
908 
909 	HRESULT set_private_data_interface(
910 		REFGUID guid,
911 		const IUnknown *pData)
912 	{
913 		lock_t<mutex_t> lock(private_data_mutex);
914 		std::pair<void*, unsigned>& v = private_data_map[guid];
915 		if(v.first)
916 		{
917 			if(v.second == ~0u)
918 				((IUnknown*)v.first)->Release();
919 			else
920 				free(v.first);
921 		}
922 		if(pData)
923 		{
924 			((IUnknown*)pData)->AddRef();
925 			v.first = (void*)pData;
926 			v.second = ~0;
927 		}
928 		else
929 			private_data_map.erase(guid);
930 		return S_OK;
931 	}
932 
933 	virtual HRESULT STDMETHODCALLTYPE GetPrivateData(
934 		REFGUID guid,
935 		UINT *pDataSize,
936 		void *pData)
937 	{
938 		return get_private_data(guid, pDataSize, pData);
939 	}
940 
941 	virtual HRESULT STDMETHODCALLTYPE SetPrivateData(
942 		REFGUID guid,
943 		UINT DataSize,
944 		const void *pData)
945 	{
946 		return set_private_data(guid, DataSize, pData);
947 	}
948 
949 	virtual HRESULT STDMETHODCALLTYPE SetPrivateDataInterface(
950 		REFGUID guid,
951 		const IUnknown *pData)
952 	{
953 		return set_private_data_interface(guid, pData);
954 	}
955 };
956 
957 template<typename BaseClass, typename SecondaryInterface>
958 struct GalliumMultiPrivateDataComObject : public GalliumMultiComObject<BaseClass, SecondaryInterface>
959 {
960 	// we could avoid this duplication, but the increased complexity to do so isn't worth it
961 	virtual HRESULT STDMETHODCALLTYPE GetPrivateData(
962 		REFGUID guid,
963 		UINT *pDataSize,
964 		void *pData)
965 	{
966 		return BaseClass::get_private_data(guid, pDataSize, pData);
967 	}
968 
969 	virtual HRESULT STDMETHODCALLTYPE SetPrivateData(
970 		REFGUID guid,
971 		UINT DataSize,
972 		const void *pData)
973 	{
974 		return BaseClass::set_private_data(guid, DataSize, pData);
975 	}
976 
977 	virtual HRESULT STDMETHODCALLTYPE SetPrivateDataInterface(
978 		REFGUID guid,
979 		const IUnknown *pData)
980 	{
981 		return BaseClass::set_private_data_interface(guid, pData);
982 	}
983 };
984 
985 #define DXGI_FORMAT_COUNT 116
986 extern pipe_format dxgi_to_pipe_format[DXGI_FORMAT_COUNT];
987 extern DXGI_FORMAT pipe_to_dxgi_format[PIPE_FORMAT_COUNT];
988 
989 void init_pipe_to_dxgi_format();
990 
991 COM_INTERFACE(IGalliumDevice, IUnknown);
992 COM_INTERFACE(IGalliumAdapter, IUnknown);
993 COM_INTERFACE(IGalliumResource, IUnknown);
994 
995 // used to make QueryInterface know the IIDs of the interface and its ancestors
996 COM_INTERFACE(IDXGIObject, IUnknown)
997 COM_INTERFACE(IDXGIDeviceSubObject, IDXGIObject)
998 COM_INTERFACE(IDXGISurface, IDXGIDeviceSubObject)
999 COM_INTERFACE(IDXGIOutput, IDXGIObject)
1000 COM_INTERFACE(IDXGIAdapter, IDXGIObject)
1001 COM_INTERFACE(IDXGISwapChain, IDXGIDeviceSubObject)
1002 COM_INTERFACE(IDXGIFactory, IDXGIObject)
1003 COM_INTERFACE(IDXGIDevice, IDXGIObject)
1004 COM_INTERFACE(IDXGIResource, IDXGIDeviceSubObject)
1005 COM_INTERFACE(IDXGISurface1, IDXGISurface)
1006 COM_INTERFACE(IDXGIDevice1, IDXGIDevice)
1007 COM_INTERFACE(IDXGIAdapter1, IDXGIAdapter)
1008 COM_INTERFACE(IDXGIFactory1, IDXGIFactory)
1009 
1010 template<typename Base>
1011 struct GalliumDXGIDevice : public GalliumMultiPrivateDataComObject<Base, IDXGIDevice1>
1012 {
1013 	ComPtr<IDXGIAdapter> adapter;
1014 	int priority;
1015 	unsigned max_latency;
1016 
1017 	GalliumDXGIDevice(IDXGIAdapter* p_adapter)
1018 	{
1019 		adapter = p_adapter;
1020 	}
1021 
1022 	virtual HRESULT STDMETHODCALLTYPE GetParent(
1023 		REFIID riid,
1024 		void **ppParent)
1025 	{
1026 		return adapter.p->QueryInterface(riid, ppParent);
1027 	}
1028 
1029 	virtual HRESULT STDMETHODCALLTYPE GetAdapter(
1030 		IDXGIAdapter **pAdapter)
1031 	{
1032 		*pAdapter = adapter.ref();
1033 		return S_OK;
1034 	}
1035 
1036 	virtual HRESULT STDMETHODCALLTYPE QueryResourceResidency(
1037 		IUnknown *const *ppResources,
1038 		DXGI_RESIDENCY *pResidencyStatus,
1039 		UINT NumResources)
1040 	{
1041 		for(unsigned i = 0; i < NumResources; ++i)
1042 			pResidencyStatus[i] = DXGI_RESIDENCY_FULLY_RESIDENT;
1043 		return S_OK;
1044 	}
1045 
1046 	virtual HRESULT STDMETHODCALLTYPE SetGPUThreadPriority(
1047 		INT Priority)
1048 	{
1049 		priority = Priority;
1050 		return S_OK;
1051 	}
1052 
1053 	virtual HRESULT STDMETHODCALLTYPE GetGPUThreadPriority(
1054 		INT *pPriority)
1055 	{
1056 		*pPriority = priority;
1057 		return S_OK;
1058 	}
1059 
1060 	HRESULT STDMETHODCALLTYPE GetMaximumFrameLatency(
1061 		UINT *pMaxLatency
1062 	)
1063 	{
1064 		*pMaxLatency = max_latency;
1065 		return S_OK;
1066 	}
1067 
1068 	virtual HRESULT STDMETHODCALLTYPE SetMaximumFrameLatency(
1069 		UINT MaxLatency)
1070 	{
1071 		max_latency = MaxLatency;
1072 		return S_OK;
1073 	}
1074 };
1075 
1076 COM_INTERFACE(ID3D10Blob, IUnknown);
1077 
1078 /* NOTE: ID3DBlob implementations may come from a Microsoft native DLL
1079  * (e.g. d3dcompiler), or perhaps even from the application itself.
1080  *
1081  * Hence, never try to access the data/size members directly, which is why they are private.
1082  * In internal code, use std::pair<void*, size_t> instead of this class.
1083  */
1084 class GalliumD3DBlob : public GalliumComObject<ID3DBlob>
1085 {
1086 	void* data;
1087 	size_t size;
1088 
1089 public:
1090 	GalliumD3DBlob(void* data, size_t size)
1091 	: data(data), size(size)
1092 	{}
1093 
1094 	~GalliumD3DBlob()
1095 	{
1096 		free(data);
1097 	}
1098 
1099 	virtual LPVOID STDMETHODCALLTYPE GetBufferPointer()
1100 	{
1101 		return data;
1102 	}
1103 
1104 	virtual SIZE_T STDMETHODCALLTYPE GetBufferSize()
1105 	{
1106 		return size;
1107 	}
1108 };
1109 
1110 #endif /* D3D1XSTUTIL_H_ */
1111