summaryrefslogtreecommitdiff
path: root/src/gallium/state_trackers/d3d1x/gd3d11/d3d11.cpp
blob: 42678fab4d091033e82b74dac891c125cb8aacb6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
/**************************************************************************
 *
 * Copyright 2010 Luca Barbieri
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial
 * portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 **************************************************************************/

#include "d3d1x_private.h"

extern "C"
{
#include "util/u_gen_mipmap.h"
#include "tgsi/tgsi_ureg.h"
#include "tgsi/tgsi_dump.h"
#include "cso_cache/cso_context.h"
}


// the perl script will change this to 10 for d3d10, and also do s/D3D11/D3D10 in the whole file
#define API 11

#if API >= 11
#define DX10_ONLY(x)
#else
#define DX10_ONLY(x) x
#endif

typedef D3D10_MAPPED_TEXTURE3D D3D10_MAPPED_SUBRESOURCE;

// used to make QueryInterface know the IIDs of the interface and its ancestors
COM_INTERFACE(ID3D11DeviceChild, IUnknown)
COM_INTERFACE(ID3D11InputLayout, ID3D11DeviceChild)
COM_INTERFACE(ID3D11DepthStencilState, ID3D11DeviceChild)
COM_INTERFACE(ID3D11BlendState, ID3D11DeviceChild)
COM_INTERFACE(ID3D11RasterizerState, ID3D11DeviceChild)
COM_INTERFACE(ID3D11SamplerState, ID3D11DeviceChild)
COM_INTERFACE(ID3D11Resource, ID3D11DeviceChild)
COM_INTERFACE(ID3D11Buffer, ID3D11Resource)
COM_INTERFACE(ID3D11Texture1D, ID3D11Resource)
COM_INTERFACE(ID3D11Texture2D, ID3D11Resource)
COM_INTERFACE(ID3D11Texture3D, ID3D11Resource)
COM_INTERFACE(ID3D11View, ID3D11DeviceChild)
COM_INTERFACE(ID3D11ShaderResourceView, ID3D11View)
COM_INTERFACE(ID3D11RenderTargetView, ID3D11View)
COM_INTERFACE(ID3D11DepthStencilView, ID3D11View)
COM_INTERFACE(ID3D11VertexShader, ID3D11DeviceChild)
COM_INTERFACE(ID3D11GeometryShader, ID3D11DeviceChild)
COM_INTERFACE(ID3D11PixelShader, ID3D11DeviceChild)
COM_INTERFACE(ID3D11Asynchronous, ID3D11DeviceChild)
COM_INTERFACE(ID3D11Query, ID3D11Asynchronous)
COM_INTERFACE(ID3D11Predicate, ID3D11Query)
COM_INTERFACE(ID3D11Counter, ID3D11Asynchronous)
COM_INTERFACE(ID3D11Device, IUnknown)

#if API >= 11
COM_INTERFACE(ID3D11UnorderedAccessView, ID3D11View)
COM_INTERFACE(ID3D11HullShader, ID3D11DeviceChild)
COM_INTERFACE(ID3D11DomainShader, ID3D11DeviceChild)
COM_INTERFACE(ID3D11ComputeShader, ID3D11DeviceChild)
COM_INTERFACE(ID3D11ClassInstance, ID3D11DeviceChild)
COM_INTERFACE(ID3D11ClassLinkage, ID3D11DeviceChild)
COM_INTERFACE(ID3D11CommandList, ID3D11DeviceChild)
COM_INTERFACE(ID3D11DeviceContext, ID3D11DeviceChild)
#else
COM_INTERFACE(ID3D10BlendState1, ID3D10BlendState)
COM_INTERFACE(ID3D10ShaderResourceView1, ID3D10ShaderResourceView)
COM_INTERFACE(ID3D10Device1, ID3D10Device)
#endif

struct GalliumD3D11Screen;

#if API >= 11
static ID3D11DeviceContext* GalliumD3D11ImmediateDeviceContext_Create(GalliumD3D11Screen* device, struct pipe_context* pipe, bool owns_pipe);
static void GalliumD3D11ImmediateDeviceContext_RestoreGalliumState(ID3D11DeviceContext* context);
static void GalliumD3D11ImmediateDeviceContext_RestoreGalliumStateBlitOnly(ID3D11DeviceContext* context);
static void GalliumD3D11ImmediateDeviceContext_Destroy(ID3D11DeviceContext* device);
#endif

static inline pipe_box d3d11_to_pipe_box(struct pipe_resource* resource, unsigned level, const D3D11_BOX* pBox)
{
	pipe_box box;
	if(pBox)
	{
		box.x = pBox->left;
		box.y = pBox->top;
		box.z = pBox->front;
		box.width = pBox->right - pBox->left;
		box.height = pBox->bottom - pBox->top;
		box.depth = pBox->back - pBox->front;
	}
	else
	{
		box.x = box.y = box.z = 0;
		box.width = u_minify(resource->width0, level);
		box.height = u_minify(resource->height0, level);
		box.depth = u_minify(resource->depth0, level);
	}
	return box;
}

struct GalliumD3D11Caps
{
	bool so;
	bool gs;
	bool queries;
	bool render_condition;
	unsigned constant_buffers[D3D11_STAGES];
	unsigned stages;
};

typedef GalliumDXGIDevice<
	GalliumMultiComObject<
#if API >= 11
		GalliumPrivateDataComObject<ID3D11Device>,
#else
		GalliumPrivateDataComObject<ID3D10Device1>,
#endif
		IGalliumDevice
	>
> GalliumD3D11ScreenBase;

// used to avoid needing to have forward declarations of functions
// this is called "screen" because in the D3D10 case it's only part of the device
struct GalliumD3D11Screen : public GalliumD3D11ScreenBase
{

	pipe_screen* screen;
	pipe_context* immediate_pipe;
	GalliumD3D11Caps screen_caps;

#if API >= 11
	ID3D11DeviceContext* immediate_context;
	ID3D11DeviceContext* get_immediate_context()
	{
		return immediate_context;
	}
#else
	GalliumD3D11Screen* get_immediate_context()
	{
		return this;
	}
#endif


	GalliumD3D11Screen(pipe_screen* screen, struct pipe_context* immediate_pipe, IDXGIAdapter* adapter)
	: GalliumD3D11ScreenBase(adapter), screen(screen), immediate_pipe(immediate_pipe)
	{
	}

#if API < 11
	// we use a D3D11-like API internally
	virtual HRESULT STDMETHODCALLTYPE Map(
			ID3D11Resource *pResource,
			unsigned Subresource,
			D3D11_MAP MapType,
			unsigned MapFlags,
			D3D11_MAPPED_SUBRESOURCE *pMappedResource) = 0;
	virtual void STDMETHODCALLTYPE Unmap(
			ID3D11Resource *pResource,
			unsigned Subresource) = 0;
	virtual void STDMETHODCALLTYPE Begin(
		ID3D11Asynchronous *pAsync) = 0;
	virtual void STDMETHODCALLTYPE End(
		ID3D11Asynchronous *pAsync) = 0;
	virtual HRESULT STDMETHODCALLTYPE GetData(
		ID3D11Asynchronous *pAsync,
		void *pData,
		unsigned DataSize,
		unsigned GetDataFlags) = 0;

	// TODO: maybe we should use function overloading, but that might risk silent errors,
	// and cannot be exported to a C interface
	virtual void UnbindBlendState(ID3D11BlendState* state) = 0;
	virtual void UnbindRasterizerState(ID3D11RasterizerState* state) = 0;
	virtual void UnbindDepthStencilState(ID3D11DepthStencilState* state) = 0;
	virtual void UnbindInputLayout(ID3D11InputLayout* state) = 0;
	virtual void UnbindPixelShader(ID3D11PixelShader* state) = 0;
	virtual void UnbindVertexShader(ID3D11VertexShader* state) = 0;
	virtual void UnbindGeometryShader(ID3D11GeometryShader* state) = 0;
	virtual void UnbindPredicate(ID3D11Predicate* predicate) = 0;
	virtual void UnbindSamplerState(ID3D11SamplerState* state) = 0;
	virtual void UnbindBuffer(ID3D11Buffer* buffer) = 0;
	virtual void UnbindDepthStencilView(ID3D11DepthStencilView* view) = 0;
	virtual void UnbindRenderTargetView(ID3D11RenderTargetView* view) = 0;
	virtual void UnbindShaderResourceView(ID3D11ShaderResourceView* view) = 0;

	void UnbindBlendState1(ID3D11BlendState1* state)
	{
		UnbindBlendState(state);
	}
	void UnbindShaderResourceView1(ID3D11ShaderResourceView1* view)
	{
		UnbindShaderResourceView(view);
	}
#endif
};

#include "d3d11_objects.h"
#include "d3d11_screen.h"
#include "d3d11_context.h"
#include "d3d11_misc.h"

#if API >= 11
HRESULT STDMETHODCALLTYPE GalliumD3D11DeviceCreate(struct pipe_screen* screen, struct pipe_context* context, BOOL owns_context, unsigned creation_flags, IDXGIAdapter* adapter, ID3D11Device** ppDevice)
{
	if(creation_flags & D3D11_CREATE_DEVICE_SINGLETHREADED)
		*ppDevice = new GalliumD3D11ScreenImpl<false>(screen, context, owns_context, creation_flags, adapter);
	else
		*ppDevice = new GalliumD3D11ScreenImpl<true>(screen, context, owns_context, creation_flags, adapter);
	return S_OK;
}
#else
HRESULT STDMETHODCALLTYPE GalliumD3D10DeviceCreate1(struct pipe_screen* screen, struct pipe_context* context, BOOL owns_context, unsigned creation_flags, IDXGIAdapter* adapter, ID3D10Device1** ppDevice)
{
	if(creation_flags & D3D10_CREATE_DEVICE_SINGLETHREADED)
		*ppDevice = new GalliumD3D10Device<false>(screen, context, owns_context, creation_flags, adapter);
	else
		*ppDevice = new GalliumD3D10Device<true>(screen, context, owns_context, creation_flags, adapter);
	return S_OK;
}
#endif