d3d11.cpp revision 92617aeac109481258f0c3863d09c1b8903d438b
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#include "d3d1x_private.h"
28
29extern "C"
30{
31#include "util/u_gen_mipmap.h"
32#include "tgsi/tgsi_ureg.h"
33#include "cso_cache/cso_context.h"
34}
35
36
37// the perl script will change this to 10 for d3d10, and also do s/D3D11/D3D10 in the whole file
38#define API 11
39
40#if API >= 11
41#define DX10_ONLY(x)
42#else
43#define DX10_ONLY(x) x
44#endif
45
46typedef D3D10_MAPPED_TEXTURE3D D3D10_MAPPED_SUBRESOURCE;
47
48// used to make QueryInterface know the IIDs of the interface and its ancestors
49COM_INTERFACE(ID3D11DeviceChild, IUnknown)
50COM_INTERFACE(ID3D11InputLayout, ID3D11DeviceChild)
51COM_INTERFACE(ID3D11DepthStencilState, ID3D11DeviceChild)
52COM_INTERFACE(ID3D11BlendState, ID3D11DeviceChild)
53COM_INTERFACE(ID3D11RasterizerState, ID3D11DeviceChild)
54COM_INTERFACE(ID3D11SamplerState, ID3D11DeviceChild)
55COM_INTERFACE(ID3D11Resource, ID3D11DeviceChild)
56COM_INTERFACE(ID3D11Buffer, ID3D11Resource)
57COM_INTERFACE(ID3D11Texture1D, ID3D11Resource)
58COM_INTERFACE(ID3D11Texture2D, ID3D11Resource)
59COM_INTERFACE(ID3D11Texture3D, ID3D11Resource)
60COM_INTERFACE(ID3D11View, ID3D11DeviceChild)
61COM_INTERFACE(ID3D11ShaderResourceView, ID3D11View)
62COM_INTERFACE(ID3D11RenderTargetView, ID3D11View)
63COM_INTERFACE(ID3D11DepthStencilView, ID3D11View)
64COM_INTERFACE(ID3D11VertexShader, ID3D11DeviceChild)
65COM_INTERFACE(ID3D11GeometryShader, ID3D11DeviceChild)
66COM_INTERFACE(ID3D11PixelShader, ID3D11DeviceChild)
67COM_INTERFACE(ID3D11Asynchronous, ID3D11DeviceChild)
68COM_INTERFACE(ID3D11Query, ID3D11Asynchronous)
69COM_INTERFACE(ID3D11Predicate, ID3D11Query)
70COM_INTERFACE(ID3D11Counter, ID3D11Asynchronous)
71COM_INTERFACE(ID3D11Device, IUnknown)
72
73#if API >= 11
74COM_INTERFACE(ID3D11UnorderedAccessView, ID3D11View)
75COM_INTERFACE(ID3D11HullShader, ID3D11DeviceChild)
76COM_INTERFACE(ID3D11DomainShader, ID3D11DeviceChild)
77COM_INTERFACE(ID3D11ComputeShader, ID3D11DeviceChild)
78COM_INTERFACE(ID3D11ClassInstance, ID3D11DeviceChild)
79COM_INTERFACE(ID3D11ClassLinkage, ID3D11DeviceChild)
80COM_INTERFACE(ID3D11CommandList, ID3D11DeviceChild)
81COM_INTERFACE(ID3D11DeviceContext, ID3D11DeviceChild)
82#else
83COM_INTERFACE(ID3D10BlendState1, ID3D10BlendState)
84COM_INTERFACE(ID3D10ShaderResourceView1, ID3D10ShaderResourceView)
85COM_INTERFACE(ID3D10Device1, ID3D10Device)
86#endif
87
88struct GalliumD3D11Screen;
89
90#if API >= 11
91static ID3D11DeviceContext* GalliumD3D11ImmediateDeviceContext_Create(GalliumD3D11Screen* device, struct pipe_context* pipe, bool owns_pipe);
92static void GalliumD3D11ImmediateDeviceContext_RestoreGalliumState(ID3D11DeviceContext* context);
93static void GalliumD3D11ImmediateDeviceContext_RestoreGalliumStateBlitOnly(ID3D11DeviceContext* context);
94static void GalliumD3D11ImmediateDeviceContext_Destroy(ID3D11DeviceContext* device);
95#endif
96
97static inline pipe_box d3d11_to_pipe_box(struct pipe_resource* resource, unsigned level, const D3D11_BOX* pBox)
98{
99	pipe_box box;
100	if(pBox)
101	{
102		box.x = pBox->left;
103		box.y = pBox->top;
104		box.z = pBox->front;
105		box.width = pBox->right - pBox->left;
106		box.height = pBox->bottom - pBox->top;
107		box.depth = pBox->back - pBox->front;
108	}
109	else
110	{
111		box.x = box.y = box.z = 0;
112		box.width = u_minify(resource->width0, level);
113		box.height = u_minify(resource->height0, level);
114		box.depth = u_minify(resource->depth0, level);
115	}
116	return box;
117}
118
119struct GalliumD3D11Caps
120{
121	bool so;
122	bool gs;
123	bool queries;
124	bool render_condition;
125	unsigned constant_buffers[D3D11_STAGES];
126	unsigned stages;
127};
128
129// used to avoid needing to have forward declarations of functions
130// this is called "screen" because in the D3D10 case it's only part of the device
131struct GalliumD3D11Screen
132	: public GalliumDXGIDevice<
133		GalliumMultiComObject<
134#if API >= 11
135			GalliumPrivateDataComObject<ID3D11Device>,
136#else
137			GalliumPrivateDataComObject<ID3D10Device1>,
138#endif
139			IGalliumDevice
140		>
141	>
142{
143	pipe_screen* screen;
144	pipe_context* immediate_pipe;
145	GalliumD3D11Caps screen_caps;
146
147#if API >= 11
148	ID3D11DeviceContext* immediate_context;
149	ID3D11DeviceContext* get_immediate_context()
150	{
151		return immediate_context;
152	}
153#else
154	GalliumD3D11Screen* get_immediate_context()
155	{
156		return this;
157	}
158#endif
159
160
161	GalliumD3D11Screen(pipe_screen* screen, struct pipe_context* immediate_pipe, IDXGIAdapter* adapter)
162	: GalliumDXGIDevice(adapter), screen(screen), immediate_pipe(immediate_pipe)
163	{
164	}
165
166#if API < 11
167	// we use a D3D11-like API internally
168	virtual HRESULT STDMETHODCALLTYPE Map(
169			__in  ID3D11Resource *pResource,
170			__in  unsigned Subresource,
171			__in  D3D11_MAP MapType,
172			__in  unsigned MapFlags,
173			__out  D3D11_MAPPED_SUBRESOURCE *pMappedResource) = 0;
174	virtual void STDMETHODCALLTYPE Unmap(
175			__in  ID3D11Resource *pResource,
176			__in  unsigned Subresource) = 0;
177	virtual void STDMETHODCALLTYPE Begin(
178		__in  ID3D11Asynchronous *pAsync) = 0;
179	virtual void STDMETHODCALLTYPE End(
180		__in  ID3D11Asynchronous *pAsync) = 0;
181	virtual HRESULT STDMETHODCALLTYPE GetData(
182		__in  ID3D11Asynchronous *pAsync,
183		__out_bcount_opt(DataSize)  void *pData,
184		__in  unsigned DataSize,
185		__in  unsigned GetDataFlags) = 0;
186
187	// TODO: maybe we should use function overloading, but that might risk silent errors,
188	// and cannot be exported to a C interface
189	virtual void UnbindBlendState(ID3D11BlendState* state) = 0;
190	virtual void UnbindRasterizerState(ID3D11RasterizerState* state) = 0;
191	virtual void UnbindDepthStencilState(ID3D11DepthStencilState* state) = 0;
192	virtual void UnbindInputLayout(ID3D11InputLayout* state) = 0;
193	virtual void UnbindPixelShader(ID3D11PixelShader* state) = 0;
194	virtual void UnbindVertexShader(ID3D11VertexShader* state) = 0;
195	virtual void UnbindGeometryShader(ID3D11GeometryShader* state) = 0;
196	virtual void UnbindPredicate(ID3D11Predicate* predicate) = 0;
197	virtual void UnbindSamplerState(ID3D11SamplerState* state) = 0;
198	virtual void UnbindBuffer(ID3D11Buffer* buffer) = 0;
199	virtual void UnbindDepthStencilView(ID3D11DepthStencilView* view) = 0;
200	virtual void UnbindRenderTargetView(ID3D11RenderTargetView* view) = 0;
201	virtual void UnbindShaderResourceView(ID3D11ShaderResourceView* view) = 0;
202
203	void UnbindBlendState1(ID3D11BlendState1* state)
204	{
205		UnbindBlendState(state);
206	}
207	void UnbindShaderResourceView1(ID3D11ShaderResourceView1* view)
208	{
209		UnbindShaderResourceView(view);
210	}
211#endif
212};
213
214#include "d3d11_objects.h"
215#include "d3d11_screen.h"
216#include "d3d11_context.h"
217
218#if API >= 11
219HRESULT STDMETHODCALLTYPE GalliumD3D11DeviceCreate(struct pipe_screen* screen, struct pipe_context* context, BOOL owns_context, unsigned creation_flags, IDXGIAdapter* adapter, ID3D11Device** ppDevice)
220{
221	if(creation_flags & D3D11_CREATE_DEVICE_SINGLETHREADED)
222		*ppDevice = new GalliumD3D11ScreenImpl<false>(screen, context, owns_context, creation_flags, adapter);
223	else
224		*ppDevice = new GalliumD3D11ScreenImpl<true>(screen, context, owns_context, creation_flags, adapter);
225	return S_OK;
226}
227#else
228HRESULT STDMETHODCALLTYPE GalliumD3D10DeviceCreate1(struct pipe_screen* screen, struct pipe_context* context, BOOL owns_context, unsigned creation_flags, IDXGIAdapter* adapter, ID3D10Device1** ppDevice)
229{
230	if(creation_flags & D3D10_CREATE_DEVICE_SINGLETHREADED)
231		*ppDevice = new GalliumD3D10Device<false>(screen, context, owns_context, creation_flags, adapter);
232	else
233		*ppDevice = new GalliumD3D10Device<true>(screen, context, owns_context, creation_flags, adapter);
234	return S_OK;
235}
236#endif
237