1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**************************************************************************
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2010 Luca Barbieri
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * a copy of this software and associated documentation files (the
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish,
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sublicense, and/or sell copies of the Software, and to
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions:
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * portions of the Software.
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* used to unbind things, we need 128 due to resources */
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const void* zero_data[128];
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define UPDATE_VIEWS_SHIFT (D3D11_STAGES * 0)
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define UPDATE_SAMPLERS_SHIFT (D3D11_STAGES * 1)
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define UPDATE_VERTEX_BUFFERS (1 << (D3D11_STAGES * 2))
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if API >= 11
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<typename PtrTraits>
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct GalliumD3D11DeviceContext :
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	public GalliumD3D11DeviceChild<ID3D11DeviceContext>
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<bool threadsafe>
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct GalliumD3D10Device : public GalliumD3D10ScreenImpl<threadsafe>
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	typedef simple_ptr_traits PtrTraits;
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	typedef GalliumD3D10Device GalliumD3D10DeviceContext;
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	refcnt_ptr<GalliumD3D11Shader<>, PtrTraits> shaders[D3D11_STAGES];
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	refcnt_ptr<GalliumD3D11InputLayout, PtrTraits> input_layout;
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	refcnt_ptr<GalliumD3D11Buffer, PtrTraits> index_buffer;
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	refcnt_ptr<GalliumD3D11RasterizerState, PtrTraits> rasterizer_state;
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	refcnt_ptr<GalliumD3D11DepthStencilState, PtrTraits> depth_stencil_state;
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	refcnt_ptr<GalliumD3D11BlendState, PtrTraits> blend_state;
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	refcnt_ptr<GalliumD3D11DepthStencilView, PtrTraits> depth_stencil_view;
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	refcnt_ptr<GalliumD3D11Predicate, PtrTraits> render_predicate;
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	refcnt_ptr<GalliumD3D11Buffer, PtrTraits> constant_buffers[D3D11_STAGES][D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT];
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	refcnt_ptr<GalliumD3D11ShaderResourceView, PtrTraits> shader_resource_views[D3D11_STAGES][D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT];
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	refcnt_ptr<GalliumD3D11SamplerState, PtrTraits> samplers[D3D11_STAGES][D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT];
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	refcnt_ptr<GalliumD3D11Buffer, PtrTraits> input_buffers[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	refcnt_ptr<GalliumD3D11RenderTargetView, PtrTraits> render_target_views[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT];
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	refcnt_ptr<GalliumD3D11Buffer, PtrTraits> so_buffers[D3D11_SO_BUFFER_SLOT_COUNT];
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if API >= 11
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	refcnt_ptr<ID3D11UnorderedAccessView, PtrTraits> cs_unordered_access_views[D3D11_PS_CS_UAV_REGISTER_COUNT];
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	refcnt_ptr<ID3D11UnorderedAccessView, PtrTraits> om_unordered_access_views[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT];
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	D3D11_VIEWPORT viewports[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	D3D11_RECT scissor_rects[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	D3D11_PRIMITIVE_TOPOLOGY primitive_topology;
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	DXGI_FORMAT index_format;
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned index_offset;
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	uint32_t strip_cut_index;
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	BOOL render_predicate_value;
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	float blend_color[4];
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned sample_mask;
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned stencil_ref;
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void* default_input_layout;
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void* default_rasterizer;
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void* default_depth_stencil;
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void* default_blend;
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void* default_sampler;
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void* default_shaders[D3D11_STAGES];
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	// derived state
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	int primitive_mode;
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct pipe_vertex_buffer vertex_buffers[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct pipe_stream_output_target* so_targets[D3D11_SO_BUFFER_SLOT_COUNT];
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct pipe_sampler_view* sampler_views[D3D11_STAGES][D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT];
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void* sampler_csos[D3D11_STAGES][D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT];
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned num_shader_resource_views[D3D11_STAGES];
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned num_samplers[D3D11_STAGES];
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned num_vertex_buffers;
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned num_render_target_views;
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned num_viewports;
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned num_scissor_rects;
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned num_so_targets;
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct pipe_context* pipe;
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned update_flags;
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bool owns_pipe;
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned context_flags;
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	GalliumD3D11Caps caps;
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cso_context* cso_ctx;
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	gen_mipmap_state* gen_mipmap;
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if API >= 11
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SYNCHRONIZED do {} while(0)
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	GalliumD3D11DeviceContext(GalliumD3D11Screen* device, pipe_context* pipe, bool owns_pipe, unsigned context_flags = 0)
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	: GalliumD3D11DeviceChild<ID3D11DeviceContext>(device), pipe(pipe), owns_pipe(owns_pipe), context_flags(context_flags)
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		caps = device->screen_caps;
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		init_context();
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	~GalliumD3D11DeviceContext()
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		destroy_context();
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SYNCHRONIZED lock_t<maybe_mutex_t<threadsafe> > lock_(this->mutex)
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	GalliumD3D10Device(pipe_screen* screen, pipe_context* pipe, bool owns_pipe, unsigned creation_flags, IDXGIAdapter* adapter)
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	: GalliumD3D10ScreenImpl<threadsafe>(screen, pipe, owns_pipe, creation_flags, adapter), pipe(pipe), owns_pipe(owns_pipe), context_flags(0)
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		caps = this->screen_caps;
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		init_context();
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	~GalliumD3D10Device()
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		destroy_context();
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void init_context()
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(!pipe->begin_query)
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			caps.queries = false;
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(!pipe->bind_gs_state)
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			caps.gs = false;
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			caps.stages = 2;
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		assert(!caps.so || pipe->set_stream_output_targets);
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(!pipe->set_geometry_sampler_views)
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			caps.stages_with_sampling &=~ (1 << PIPE_SHADER_GEOMETRY);
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(!pipe->set_fragment_sampler_views)
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			caps.stages_with_sampling &=~ (1 << PIPE_SHADER_FRAGMENT);
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(!pipe->set_vertex_sampler_views)
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			caps.stages_with_sampling &=~ (1 << PIPE_SHADER_VERTEX);
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		update_flags = 0;
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		// pipeline state
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		memset(viewports, 0, sizeof(viewports));
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		memset(scissor_rects, 0, sizeof(scissor_rects));
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		primitive_topology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		index_format = DXGI_FORMAT_UNKNOWN;
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		index_offset = 0;
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		strip_cut_index = 0xffffffff;
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		render_predicate_value = 0;
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		memset(blend_color, 0, sizeof(blend_color));
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		sample_mask = ~0;
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		stencil_ref = 0;
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		// derived state
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		primitive_mode = 0;
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		memset(vertex_buffers, 0, sizeof(vertex_buffers));
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		memset(so_targets, 0, sizeof(so_buffers));
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		memset(sampler_views, 0, sizeof(sampler_views));
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		memset(sampler_csos, 0, sizeof(sampler_csos));
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		memset(num_shader_resource_views, 0, sizeof(num_shader_resource_views));
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		memset(num_samplers, 0, sizeof(num_samplers));
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		num_vertex_buffers = 0;
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		num_render_target_views = 0;
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		num_viewports = 0;
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		num_scissor_rects = 0;
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		num_so_targets = 0;
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		default_input_layout = pipe->create_vertex_elements_state(pipe, 0, 0);
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct pipe_rasterizer_state rasterizerd;
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		memset(&rasterizerd, 0, sizeof(rasterizerd));
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		rasterizerd.gl_rasterization_rules = 1;
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		rasterizerd.cull_face = PIPE_FACE_BACK;
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		rasterizerd.flatshade_first = 1;
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		rasterizerd.line_width = 1.0f;
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		rasterizerd.point_size = 1.0f;
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		rasterizerd.depth_clip = TRUE;
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		default_rasterizer = pipe->create_rasterizer_state(pipe, &rasterizerd);
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct pipe_depth_stencil_alpha_state depth_stencild;
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		memset(&depth_stencild, 0, sizeof(depth_stencild));
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		depth_stencild.depth.enabled = TRUE;
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		depth_stencild.depth.writemask = 1;
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		depth_stencild.depth.func = PIPE_FUNC_LESS;
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		default_depth_stencil = pipe->create_depth_stencil_alpha_state(pipe, &depth_stencild);
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct pipe_blend_state blendd;
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		memset(&blendd, 0, sizeof(blendd));
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		blendd.rt[0].colormask = 0xf;
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		default_blend = pipe->create_blend_state(pipe, &blendd);
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct pipe_sampler_state samplerd;
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		memset(&samplerd, 0, sizeof(samplerd));
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		samplerd.normalized_coords = 1;
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		samplerd.min_img_filter = PIPE_TEX_FILTER_LINEAR;
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		samplerd.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		samplerd.min_mip_filter = PIPE_TEX_MIPFILTER_LINEAR;
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		samplerd.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		samplerd.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		samplerd.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		samplerd.border_color.f[0] = 1.0f;
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		samplerd.border_color.f[1] = 1.0f;
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		samplerd.border_color.f[2] = 1.0f;
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		samplerd.border_color.f[3] = 1.0f;
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		samplerd.min_lod = -FLT_MAX;
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		samplerd.max_lod = FLT_MAX;
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		samplerd.max_anisotropy = 1;
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		default_sampler = pipe->create_sampler_state(pipe, &samplerd);
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		memset(&samplerd, 0, sizeof(samplerd));
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		samplerd.normalized_coords = 0;
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		samplerd.min_img_filter = PIPE_TEX_FILTER_NEAREST;
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		samplerd.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		samplerd.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		samplerd.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_BORDER;
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		samplerd.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_BORDER;
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		samplerd.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_BORDER;
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		samplerd.min_lod = -FLT_MAX;
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		samplerd.max_lod = FLT_MAX;
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		samplerd.max_anisotropy = 1;
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for(unsigned s = 0; s < D3D11_STAGES; ++s)
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			for(unsigned i = 0; i < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i)
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				sampler_csos[s][i] = default_sampler;
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		// TODO: should this really be empty shaders, or should they be all-passthrough?
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		memset(default_shaders, 0, sizeof(default_shaders));
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct ureg_program *ureg;
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ureg_END(ureg);
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		default_shaders[PIPE_SHADER_FRAGMENT] = ureg_create_shader_and_destroy(ureg, pipe);
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ureg = ureg_create(TGSI_PROCESSOR_VERTEX);
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ureg_END(ureg);
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		default_shaders[PIPE_SHADER_VERTEX] = ureg_create_shader_and_destroy(ureg, pipe);
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cso_ctx = cso_create_context(pipe);
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		gen_mipmap = util_create_gen_mipmap(pipe, cso_ctx);
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		RestoreGalliumState();
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void destroy_context()
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		util_destroy_gen_mipmap(gen_mipmap);
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cso_destroy_context(cso_ctx);
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->bind_vertex_elements_state(pipe, 0);
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->delete_vertex_elements_state(pipe, default_input_layout);
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->bind_rasterizer_state(pipe, 0);
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->delete_rasterizer_state(pipe, default_rasterizer);
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->bind_depth_stencil_alpha_state(pipe, 0);
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->delete_depth_stencil_alpha_state(pipe, default_depth_stencil);
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->bind_blend_state(pipe, 0);
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->delete_blend_state(pipe, default_blend);
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->bind_fragment_sampler_states(pipe, 0, 0);
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->bind_vertex_sampler_states(pipe, 0, 0);
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(pipe->bind_geometry_sampler_states)
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			pipe->bind_geometry_sampler_states(pipe, 0, 0);
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->delete_sampler_state(pipe, default_sampler);
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->bind_fs_state(pipe, 0);
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->delete_fs_state(pipe, default_shaders[PIPE_SHADER_FRAGMENT]);
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->bind_vs_state(pipe, 0);
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->delete_vs_state(pipe, default_shaders[PIPE_SHADER_VERTEX]);
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(owns_pipe)
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			pipe->destroy(pipe);
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual unsigned STDMETHODCALLTYPE GetContextFlags(void)
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return context_flags;
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if API >= 11
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SET_SHADER_EXTRA_ARGS , \
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ID3D11ClassInstance *const *ppClassInstances, \
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned count
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define GET_SHADER_EXTRA_ARGS , \
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11ClassInstance **ppClassInstances, \
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned *out_count
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SET_SHADER_EXTRA_ARGS
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define GET_SHADER_EXTRA_ARGS
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* On Windows D3D11, SetConstantBuffers and SetShaderResources crash if passed a null pointer.
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Instead, you have to pass a pointer to nulls to unbind things.
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * We do the same.
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TODO: is D3D10 the same?
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	template<unsigned s>
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void xs_set_shader(GalliumD3D11Shader<>* shader)
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(shader != shaders[s].p)
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			shaders[s] = shader;
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			void* shader_cso = shader ? shader->object : default_shaders[s];
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			switch(s)
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			case PIPE_SHADER_VERTEX:
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				pipe->bind_vs_state(pipe, shader_cso);
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				break;
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			case PIPE_SHADER_FRAGMENT:
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				pipe->bind_fs_state(pipe, shader_cso);
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				break;
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			case PIPE_SHADER_GEOMETRY:
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				pipe->bind_gs_state(pipe, shader_cso);
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				break;
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			update_flags |= (1 << (UPDATE_SAMPLERS_SHIFT + s)) | (1 << (UPDATE_VIEWS_SHIFT + s));
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	template<unsigned s>
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void xs_set_constant_buffers(unsigned start, unsigned count, GalliumD3D11Buffer *const *constbufs)
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for(unsigned i = 0; i < count; ++i)
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if(constbufs[i] != constant_buffers[s][start + i].p)
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				constant_buffers[s][start + i] = constbufs[i];
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				if(s < caps.stages && start + i < caps.constant_buffers[s])
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					pipe_set_constant_buffer(pipe, s, start + i, constbufs[i] ? constbufs[i]->resource : NULL);
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	template<unsigned s>
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void xs_set_shader_resources(unsigned start, unsigned count, GalliumD3D11ShaderResourceView *const *srvs)
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		int last_different = -1;
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for(unsigned i = 0; i < count; ++i)
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if(shader_resource_views[s][start + i].p != srvs[i])
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				shader_resource_views[s][start + i] = srvs[i];
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				sampler_views[s][start + i] = srvs[i] ? srvs[i]->object : 0;
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				last_different = i;
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(last_different >= 0)
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			num_shader_resource_views[s] = std::max(num_shader_resource_views[s], start + last_different + 1);
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			update_flags |= 1 << (UPDATE_VIEWS_SHIFT + s);
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	template<unsigned s>
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void xs_set_samplers(unsigned start, unsigned count, GalliumD3D11SamplerState *const *samps)
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		int last_different = -1;
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for(unsigned i = 0; i < count; ++i)
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if(samplers[s][start + i].p != samps[i])
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				samplers[s][start + i] = samps[i];
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				sampler_csos[s][start + i] = samps[i] ? samps[i]->object : default_sampler;
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				last_different = i;
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(last_different >= 0)
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			num_samplers[s] = std::max(num_samplers[s], start + last_different + 1);
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			update_flags |= 1 << (UPDATE_SAMPLERS_SHIFT + s);
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define IMPLEMENT_SHADER_STAGE(XS, Stage) \
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE XS##SetShader( \
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11##Stage##Shader *pShader \
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SET_SHADER_EXTRA_ARGS) \
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{ \
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED; \
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		xs_set_shader<D3D11_STAGE_##XS>((GalliumD3D11Shader<>*)pShader); \
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} \
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE XS##GetShader(\
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11##Stage##Shader **ppShader \
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GET_SHADER_EXTRA_ARGS) \
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{ \
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED; \
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		*ppShader = (ID3D11##Stage##Shader*)shaders[D3D11_STAGE_##XS].ref(); \
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} \
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE XS##SetConstantBuffers(\
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned start, \
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned count, \
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11Buffer *const* constant_buffers) \
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{ \
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED; \
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		xs_set_constant_buffers<D3D11_STAGE_##XS>(start, count, (GalliumD3D11Buffer *const *)constant_buffers); \
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} \
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE XS##GetConstantBuffers(\
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned start, \
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned count, \
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11Buffer **out_constant_buffers) \
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{ \
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED; \
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for(unsigned i = 0; i < count; ++i) \
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			out_constant_buffers[i] = constant_buffers[D3D11_STAGE_##XS][start + i].ref(); \
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} \
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE XS##SetShaderResources(\
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned start, \
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned count, \
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11ShaderResourceView *const *new_shader_resource_views) \
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{ \
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED; \
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		xs_set_shader_resources<D3D11_STAGE_##XS>(start, count, (GalliumD3D11ShaderResourceView *const *)new_shader_resource_views); \
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} \
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE XS##GetShaderResources(\
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned start, \
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned count, \
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11ShaderResourceView **out_shader_resource_views) \
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{ \
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED; \
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for(unsigned i = 0; i < count; ++i) \
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			out_shader_resource_views[i] = shader_resource_views[D3D11_STAGE_##XS][start + i].ref(); \
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} \
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE XS##SetSamplers(\
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned start, \
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned count, \
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11SamplerState *const *new_samplers) \
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{ \
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED; \
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		xs_set_samplers<D3D11_STAGE_##XS>(start, count, (GalliumD3D11SamplerState *const *)new_samplers); \
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} \
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE XS##GetSamplers( \
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned start, \
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned count, \
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11SamplerState **out_samplers) \
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{ \
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED; \
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for(unsigned i = 0; i < count; ++i) \
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			out_samplers[i] = samplers[D3D11_STAGE_##XS][start + i].ref(); \
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DO_VS(x) x
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DO_GS(x) do {if(caps.gs) {x;}} while(0)
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DO_PS(x) x
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DO_HS(x)
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DO_DS(x)
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DO_CS(x)
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	IMPLEMENT_SHADER_STAGE(VS, Vertex)
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	IMPLEMENT_SHADER_STAGE(GS, Geometry)
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	IMPLEMENT_SHADER_STAGE(PS, Pixel)
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if API >= 11
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	IMPLEMENT_SHADER_STAGE(HS, Hull)
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	IMPLEMENT_SHADER_STAGE(DS, Domain)
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	IMPLEMENT_SHADER_STAGE(CS, Compute)
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE CSSetUnorderedAccessViews(
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned start,
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned count,
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11UnorderedAccessView *const *new_unordered_access_views,
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const unsigned *new_uav_initial_counts)
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for(unsigned i = 0; i < count; ++i)
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			cs_unordered_access_views[start + i] = new_unordered_access_views[i];
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE CSGetUnorderedAccessViews(
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned start,
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned count,
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11UnorderedAccessView **out_unordered_access_views)
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for(unsigned i = 0; i < count; ++i)
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			out_unordered_access_views[i] = cs_unordered_access_views[start + i].ref();
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	template<unsigned s>
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void update_stage()
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(update_flags & (1 << (UPDATE_VIEWS_SHIFT + s)))
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			while(num_shader_resource_views[s] && !sampler_views[s][num_shader_resource_views[s] - 1]) \
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				--num_shader_resource_views[s];
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if((1 << s) & caps.stages_with_sampling)
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				const unsigned num_views_to_bind = num_shader_resource_views[s];
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				switch(s)
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				{
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				case PIPE_SHADER_VERTEX:
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					pipe->set_vertex_sampler_views(pipe, num_views_to_bind, sampler_views[s]);
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					break;
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				case PIPE_SHADER_FRAGMENT:
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					pipe->set_fragment_sampler_views(pipe, num_views_to_bind, sampler_views[s]);
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					break;
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				case PIPE_SHADER_GEOMETRY:
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					pipe->set_geometry_sampler_views(pipe, num_views_to_bind, sampler_views[s]);
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					break;
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				}
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(update_flags & (1 << (UPDATE_SAMPLERS_SHIFT + s)))
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			while(num_samplers[s] && !sampler_csos[s][num_samplers[s] - 1])
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				--num_samplers[s];
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if((1 << s) & caps.stages_with_sampling)
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				const unsigned num_samplers_to_bind = num_samplers[s];
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				switch(s)
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				{
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				case PIPE_SHADER_VERTEX:
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					pipe->bind_vertex_sampler_states(pipe, num_samplers_to_bind, sampler_csos[s]);
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					break;
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				case PIPE_SHADER_FRAGMENT:
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					pipe->bind_fragment_sampler_states(pipe, num_samplers_to_bind, sampler_csos[s]);
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					break;
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				case PIPE_SHADER_GEOMETRY:
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					pipe->bind_geometry_sampler_states(pipe, num_samplers_to_bind, sampler_csos[s]);
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					break;
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				}
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void update_state()
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		update_stage<D3D11_STAGE_PS>();
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		update_stage<D3D11_STAGE_VS>();
548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		update_stage<D3D11_STAGE_GS>();
549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if API >= 11
550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		update_stage<D3D11_STAGE_HS>();
551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		update_stage<D3D11_STAGE_DS>();
552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		update_stage<D3D11_STAGE_CS>();
553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(update_flags & UPDATE_VERTEX_BUFFERS)
556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			while(num_vertex_buffers && !vertex_buffers[num_vertex_buffers - 1].buffer)
558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				--num_vertex_buffers;
559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			pipe->set_vertex_buffers(pipe, num_vertex_buffers, vertex_buffers);
560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		update_flags = 0;
563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE IASetInputLayout(
566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11InputLayout *new_input_layout)
567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(new_input_layout != input_layout.p)
570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			input_layout = new_input_layout;
572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			pipe->bind_vertex_elements_state(pipe, new_input_layout ? ((GalliumD3D11InputLayout*)new_input_layout)->object : default_input_layout);
573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE IAGetInputLayout(
577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11InputLayout **out_input_layout)
578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		*out_input_layout = input_layout.ref();
581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE IASetVertexBuffers(
584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned start,
585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned count,
586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11Buffer *const *new_vertex_buffers,
587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const unsigned *new_strides,
588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const unsigned *new_offsets)
589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		int last_different = -1;
592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for(unsigned i = 0; i < count; ++i)
593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			ID3D11Buffer* buffer = new_vertex_buffers[i];
595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if(buffer != input_buffers[start + i].p
596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				|| vertex_buffers[start + i].buffer_offset != new_offsets[i]
597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				|| vertex_buffers[start + i].stride != new_strides[i]
598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			)
599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{
600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				input_buffers[start + i] = buffer;
601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				vertex_buffers[start + i].buffer = buffer ? ((GalliumD3D11Buffer*)buffer)->resource : 0;
602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				vertex_buffers[start + i].buffer_offset = new_offsets[i];
603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				vertex_buffers[start + i].stride = new_strides[i];
604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				last_different = i;
605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(last_different >= 0)
608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			num_vertex_buffers = std::max(num_vertex_buffers, start + count);
610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			update_flags |= UPDATE_VERTEX_BUFFERS;
611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE IAGetVertexBuffers(
615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned start,
616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned count,
617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11Buffer **out_vertex_buffers,
618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned *out_strides,
619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned *out_offsets)
620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(out_vertex_buffers)
623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			for(unsigned i = 0; i < count; ++i)
625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				out_vertex_buffers[i] = input_buffers[start + i].ref();
626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(out_offsets)
629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			for(unsigned i = 0; i < count; ++i)
631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				out_offsets[i] = vertex_buffers[start + i].buffer_offset;
632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(out_strides)
635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			for(unsigned i = 0; i < count; ++i)
637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				out_strides[i] = vertex_buffers[start + i].stride;
638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void set_index_buffer()
642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe_index_buffer ib;
644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(!index_buffer)
645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			memset(&ib, 0, sizeof(ib));
647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		else
649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			switch(index_format) {
651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			case DXGI_FORMAT_R32_UINT:
652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				ib.index_size = 4;
653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				strip_cut_index = 0xffffffff;
654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				break;
655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			case DXGI_FORMAT_R16_UINT:
656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				ib.index_size = 2;
657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				strip_cut_index = 0xffff;
658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				break;
659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			default:
660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				ib.index_size = 1;
661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				strip_cut_index = 0xff;
662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				break;
663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			ib.offset = index_offset;
665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			ib.buffer = index_buffer ? ((GalliumD3D11Buffer*)index_buffer.p)->resource : 0;
666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->set_index_buffer(pipe, &ib);
668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE IASetIndexBuffer(
671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11Buffer *new_index_buffer,
672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		DXGI_FORMAT new_index_format,
673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned new_index_offset)
674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(index_buffer.p != new_index_buffer || index_format != new_index_format || index_offset != new_index_offset)
677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			index_buffer = new_index_buffer;
679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			index_format = new_index_format;
680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			index_offset = new_index_offset;
681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			set_index_buffer();
683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE IAGetIndexBuffer(
687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11Buffer **out_index_buffer,
688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		DXGI_FORMAT *out_index_format,
689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned *out_index_offset)
690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(out_index_buffer)
693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			*out_index_buffer = index_buffer.ref();
694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(out_index_format)
695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			*out_index_format = index_format;
696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(out_index_offset)
697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			*out_index_offset = index_offset;
698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE IASetPrimitiveTopology(
701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		D3D11_PRIMITIVE_TOPOLOGY new_primitive_topology)
702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(primitive_topology != new_primitive_topology)
705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if(new_primitive_topology < D3D_PRIMITIVE_TOPOLOGY_COUNT)
707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				primitive_mode = d3d_to_pipe_prim[new_primitive_topology];
708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			else
709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				primitive_mode = 0;
710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			primitive_topology = new_primitive_topology;
711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE IAGetPrimitiveTopology(
715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		D3D11_PRIMITIVE_TOPOLOGY *out_primitive_topology)
716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		*out_primitive_topology = primitive_topology;
719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE DrawIndexed(
722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned index_count,
723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned start_index_location,
724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		int base_vertex_location)
725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(update_flags)
728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			update_state();
729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe_draw_info info;
731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.mode = primitive_mode;
732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.indexed = TRUE;
733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.count = index_count;
734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.start = start_index_location;
735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.index_bias = base_vertex_location;
736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.min_index = 0;
737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.max_index = ~0;
738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.start_instance = 0;
739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.instance_count = 1;
740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.primitive_restart = TRUE;
741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.restart_index = strip_cut_index;
742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.count_from_stream_output = NULL;
743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->draw_vbo(pipe, &info);
745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE Draw(
748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned vertex_count,
749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned start_vertex_location)
750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(update_flags)
753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			update_state();
754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe_draw_info info;
756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.mode = primitive_mode;
757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.indexed = FALSE;
758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.count = vertex_count;
759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.start = start_vertex_location;
760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.index_bias = 0;
761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.min_index = 0;
762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.max_index = ~0;
763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.start_instance = 0;
764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.instance_count = 1;
765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.primitive_restart = FALSE;
766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.count_from_stream_output = NULL;
767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->draw_vbo(pipe, &info);
769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE DrawIndexedInstanced(
772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned index_countPerInstance,
773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned instance_count,
774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned start_index_location,
775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		int base_vertex_location,
776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned start_instance_location)
777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(update_flags)
780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			update_state();
781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe_draw_info info;
783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.mode = primitive_mode;
784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.indexed = TRUE;
785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.count = index_countPerInstance;
786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.start = start_index_location;
787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.index_bias = base_vertex_location;
788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.min_index = 0;
789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.max_index = ~0;
790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.start_instance = start_instance_location;
791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.instance_count = instance_count;
792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.primitive_restart = TRUE;
793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.restart_index = strip_cut_index;
794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.count_from_stream_output = NULL;
795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->draw_vbo(pipe, &info);
797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE DrawInstanced(
800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned vertex_countPerInstance,
801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned instance_count,
802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned start_vertex_location,
803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned start_instance_location)
804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(update_flags)
807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			update_state();
808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe_draw_info info;
810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.mode = primitive_mode;
811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.indexed = FALSE;
812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.count = vertex_countPerInstance;
813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.start = start_vertex_location;
814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.index_bias = 0;
815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.min_index = 0;
816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.max_index = ~0;
817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.start_instance = start_instance_location;
818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.instance_count = instance_count;
819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.primitive_restart = FALSE;
820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.count_from_stream_output = NULL;
821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->draw_vbo(pipe, &info);
823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE DrawAuto(void)
826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(!caps.so)
828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			return;
829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(update_flags)
832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			update_state();
833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe_draw_info info;
835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.mode = primitive_mode;
836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.indexed = FALSE;
837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.count = 0;
838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.start = 0;
839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.index_bias = 0;
840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.min_index = 0;
841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.max_index = ~0;
842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.start_instance = 0;
843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.instance_count = 1;
844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.primitive_restart = FALSE;
845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.restart_index = 0;
846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.count_from_stream_output = input_buffers[0].p->so_target;
847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->draw_vbo(pipe, &info);
849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE DrawIndexedInstancedIndirect(
852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11Buffer *buffer,
853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned aligned_byte_offset)
854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(update_flags)
857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			update_state();
858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct {
860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned count;
861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned instance_count;
862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned start;
863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned index_bias;
864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		} data;
865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe_buffer_read(pipe, ((GalliumD3D11Buffer*)buffer)->resource, aligned_byte_offset, sizeof(data), &data);
867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe_draw_info info;
869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.mode = primitive_mode;
870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.indexed = TRUE;
871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.start = data.start;
872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.count = data.count;
873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.index_bias = data.index_bias;
874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.min_index = 0;
875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.max_index = ~0;
876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.start_instance = 0;
877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.instance_count = data.instance_count;
878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.primitive_restart = TRUE;
879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.restart_index = strip_cut_index;
880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.count_from_stream_output = NULL;
881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->draw_vbo(pipe, &info);
883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE DrawInstancedIndirect(
886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11Buffer *buffer,
887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned aligned_byte_offset)
888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(update_flags)
891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			update_state();
892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct {
894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned count;
895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned instance_count;
896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned start;
897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		} data;
898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe_buffer_read(pipe, ((GalliumD3D11Buffer*)buffer)->resource, aligned_byte_offset, sizeof(data), &data);
900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe_draw_info info;
902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.mode = primitive_mode;
903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.indexed = FALSE;
904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.start = data.start;
905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.count = data.count;
906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.index_bias = 0;
907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.min_index = 0;
908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.max_index = ~0;
909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.start_instance = 0;
910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.instance_count = data.instance_count;
911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.primitive_restart = FALSE;
912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.count_from_stream_output = NULL;
913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->draw_vbo(pipe, &info);
915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if API >= 11
918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE Dispatch(
919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned thread_group_count_x,
920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned thread_group_count_y,
921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned thread_group_count_z)
922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// uncomment this when this is implemented
924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//		SYNCHRONIZED;
925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//		if(update_flags)
926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//			update_state();
927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE DispatchIndirect(
930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11Buffer *buffer,
931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned aligned_byte_offset)
932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// uncomment this when this is implemented
934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//		SYNCHRONIZED;
935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//		if(update_flags)
936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//			update_state();
937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE RSSetState(
941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11RasterizerState *new_rasterizer_state)
942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(new_rasterizer_state != rasterizer_state.p)
945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			rasterizer_state = new_rasterizer_state;
947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			pipe->bind_rasterizer_state(pipe, new_rasterizer_state ? ((GalliumD3D11RasterizerState*)new_rasterizer_state)->object : default_rasterizer);
948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE RSGetState(
952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11RasterizerState **out_rasterizer_state)
953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		*out_rasterizer_state = rasterizer_state.ref();
956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void set_viewport()
959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		// TODO: is depth correct? it seems D3D10/11 uses a [-1,1]x[-1,1]x[0,1] cube
961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe_viewport_state viewport;
962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		float half_width = viewports[0].Width * 0.5f;
963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		float half_height = viewports[0].Height * 0.5f;
964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		viewport.scale[0] = half_width;
966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		viewport.scale[1] = -half_height;
967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		viewport.scale[2] = (viewports[0].MaxDepth - viewports[0].MinDepth);
968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		viewport.scale[3] = 1.0f;
969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		viewport.translate[0] = half_width + viewports[0].TopLeftX;
970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		viewport.translate[1] = half_height + viewports[0].TopLeftY;
971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		viewport.translate[2] = viewports[0].MinDepth;
972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		viewport.translate[3] = 1.0f;
973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->set_viewport_state(pipe, &viewport);
974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE RSSetViewports(
977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned count,
978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const D3D11_VIEWPORT *new_viewports)
979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(count)
982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if(memcmp(&viewports[0], &new_viewports[0], sizeof(viewports[0])))
984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{
985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				viewports[0] = new_viewports[0];
986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				set_viewport();
987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			for(unsigned i = 1; i < count; ++i)
989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				viewports[i] = new_viewports[i];
990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		else if(num_viewports)
992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			// TODO: what should we do here?
994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			memset(&viewports[0], 0, sizeof(viewports[0]));
995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			set_viewport();
996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		num_viewports = count;
998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE RSGetViewports(
1001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned *out_count,
1002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		D3D11_VIEWPORT *out_viewports)
1003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(out_viewports)
1006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned i;
1008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			for(i = 0; i < std::min(*out_count, num_viewports); ++i)
1009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				out_viewports[i] = viewports[i];
1010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			memset(out_viewports + i, 0, (*out_count - i) * sizeof(D3D11_VIEWPORT));
1012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		*out_count = num_viewports;
1015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void set_scissor()
1018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe_scissor_state scissor;
1020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		scissor.minx = scissor_rects[0].left;
1021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		scissor.miny = scissor_rects[0].top;
1022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		scissor.maxx = scissor_rects[0].right;
1023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		scissor.maxy = scissor_rects[0].bottom;
1024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->set_scissor_state(pipe, &scissor);
1025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE RSSetScissorRects(
1028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned count,
1029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const D3D11_RECT *new_rects)
1030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(count)
1033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if(memcmp(&scissor_rects[0], &new_rects[0], sizeof(scissor_rects[0])))
1035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{
1036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				scissor_rects[0] = new_rects[0];
1037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				set_scissor();
1038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
1039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			for(unsigned i = 1; i < count; ++i)
1040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				scissor_rects[i] = new_rects[i];
1041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		else if(num_scissor_rects)
1043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			// TODO: what should we do here?
1045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			memset(&scissor_rects[0], 0, sizeof(scissor_rects[0]));
1046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			set_scissor();
1047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		num_scissor_rects = count;
1050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE RSGetScissorRects(
1053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned *out_count,
1054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		D3D11_RECT *out_rects)
1055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(out_rects)
1058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned i;
1060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			for(i = 0; i < std::min(*out_count, num_scissor_rects); ++i)
1061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				out_rects[i] = scissor_rects[i];
1062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			memset(out_rects + i, 0, (*out_count - i) * sizeof(D3D11_RECT));
1064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		*out_count = num_scissor_rects;
1067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE OMSetBlendState(
1070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11BlendState *new_blend_state,
1071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const float new_blend_factor[4],
1072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned new_sample_mask)
1073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		float white[4] = {1.0f, 1.0f, 1.0f, 1.0f};
1076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(blend_state.p != new_blend_state)
1078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			pipe->bind_blend_state(pipe, new_blend_state ? ((GalliumD3D11BlendState*)new_blend_state)->object : default_blend);
1080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			blend_state = new_blend_state;
1081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		// Windows D3D11 does this, even though it's apparently undocumented
1084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(!new_blend_factor)
1085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			new_blend_factor = white;
1086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(memcmp(blend_color, new_blend_factor, sizeof(blend_color)))
1088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			pipe->set_blend_color(pipe, (struct pipe_blend_color*)new_blend_factor);
1090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			memcpy(blend_color, new_blend_factor, sizeof(blend_color));
1091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(sample_mask != new_sample_mask)
1094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			pipe->set_sample_mask(pipe, new_sample_mask);
1096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			sample_mask = new_sample_mask;
1097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE OMGetBlendState(
1101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11BlendState **out_blend_state,
1102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		float out_blend_factor[4],
1103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned *out_sample_mask)
1104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(out_blend_state)
1107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			*out_blend_state = blend_state.ref();
1108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(out_blend_factor)
1109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			memcpy(out_blend_factor, blend_color, sizeof(blend_color));
1110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(out_sample_mask)
1111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			*out_sample_mask = sample_mask;
1112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void set_stencil_ref()
1115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct pipe_stencil_ref sref;
1117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		sref.ref_value[0] = stencil_ref;
1118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		sref.ref_value[1] = stencil_ref;
1119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->set_stencil_ref(pipe, &sref);
1120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE OMSetDepthStencilState(
1123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11DepthStencilState *new_depth_stencil_state,
1124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned new_stencil_ref)
1125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(new_depth_stencil_state != depth_stencil_state.p)
1128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			pipe->bind_depth_stencil_alpha_state(pipe, new_depth_stencil_state ? ((GalliumD3D11DepthStencilState*)new_depth_stencil_state)->object : default_depth_stencil);
1130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			depth_stencil_state = new_depth_stencil_state;
1131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(new_stencil_ref != stencil_ref)
1134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			stencil_ref = new_stencil_ref;
1136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			set_stencil_ref();
1137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE OMGetDepthStencilState(
1141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11DepthStencilState **out_depth_stencil_state,
1142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned *out_stencil_ref)
1143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(*out_depth_stencil_state)
1146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			*out_depth_stencil_state = depth_stencil_state.ref();
1147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(out_stencil_ref)
1148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			*out_stencil_ref = stencil_ref;
1149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void set_framebuffer()
1152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct pipe_framebuffer_state fb;
1154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		memset(&fb, 0, sizeof(fb));
1155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(depth_stencil_view)
1156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			struct pipe_surface* surf = ((GalliumD3D11DepthStencilView*)depth_stencil_view.p)->object;
1158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			fb.zsbuf = surf;
1159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if(surf->width > fb.width)
1160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				fb.width = surf->width;
1161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if(surf->height > fb.height)
1162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				fb.height = surf->height;
1163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		fb.nr_cbufs = num_render_target_views;
1165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned i;
1166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for(i = 0; i < num_render_target_views; ++i)
1167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if(render_target_views[i])
1169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{
1170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				struct pipe_surface* surf = ((GalliumD3D11RenderTargetView*)render_target_views[i].p)->object;
1171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				fb.cbufs[i] = surf;
1172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				if(surf->width > fb.width)
1173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					fb.width = surf->width;
1174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				if(surf->height > fb.height)
1175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					fb.height = surf->height;
1176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
1177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->set_framebuffer_state(pipe, &fb);
1180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* TODO: the docs say that we should unbind conflicting resources (e.g. those bound for read while we are binding them for write too), but we aren't.
1183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * Hopefully nobody relies on this happening
1184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 */
1185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE OMSetRenderTargets(
1187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned count,
1188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11RenderTargetView *const *new_render_target_views,
1189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11DepthStencilView  *new_depth_stencil_view)
1190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		bool update = false;
1194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned i, num;
1195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(depth_stencil_view.p != new_depth_stencil_view) {
1197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			update = true;
1198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			depth_stencil_view = new_depth_stencil_view;
1199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(!new_render_target_views)
1202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			count = 0;
1203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for(num = 0, i = 0; i < count; ++i) {
1205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if API >= 11
1206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			// XXX: is unbinding the UAVs here correct ?
1207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			om_unordered_access_views[i] = (ID3D11UnorderedAccessView*)NULL;
1208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
1209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if(new_render_target_views[i] != render_target_views[i].p) {
1210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				update = true;
1211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				render_target_views[i] = new_render_target_views[i];
1212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
1213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if(new_render_target_views[i])
1214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				num = i + 1;
1215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(num != num_render_target_views) {
1217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			update = true;
1218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			for(; i < num_render_target_views; ++i)
1219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				render_target_views[i] = (ID3D11RenderTargetView*)NULL;
1220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		num_render_target_views = num;
1222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(update)
1223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			set_framebuffer();
1224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE OMGetRenderTargets(
1227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned count,
1228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11RenderTargetView **out_render_target_views,
1229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11DepthStencilView  **out_depth_stencil_view)
1230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(out_render_target_views)
1233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned i;
1235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			for(i = 0; i < std::min(num_render_target_views, count); ++i)
1236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				out_render_target_views[i] = render_target_views[i].ref();
1237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			for(; i < count; ++i)
1239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				out_render_target_views[i] = 0;
1240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(out_depth_stencil_view)
1243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			*out_depth_stencil_view = depth_stencil_view.ref();
1244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if API >= 11
1247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* TODO: what is this supposed to do _exactly_? are we doing the right thing? */
1248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE OMSetRenderTargetsAndUnorderedAccessViews(
1249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned rtv_count,
1250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11RenderTargetView *const *new_render_target_views,
1251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11DepthStencilView  *new_depth_stencil_view,
1252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned uav_start,
1253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned uav_count,
1254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11UnorderedAccessView *const *new_unordered_access_views,
1255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const unsigned *new_uav_initial_counts)
1256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(rtv_count != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL)
1259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			OMSetRenderTargets(rtv_count, new_render_target_views, new_depth_stencil_view);
1260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(uav_count != D3D11_KEEP_UNORDERED_ACCESS_VIEWS)
1262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			for(unsigned i = 0; i < uav_count; ++i)
1264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{
1265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				om_unordered_access_views[uav_start + i] = new_unordered_access_views[i];
1266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				render_target_views[uav_start + i] = (ID3D11RenderTargetView*)0;
1267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
1268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE OMGetRenderTargetsAndUnorderedAccessViews(
1272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned rtv_count,
1273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11RenderTargetView **out_render_target_views,
1274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11DepthStencilView  **out_depth_stencil_view,
1275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned uav_start,
1276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned uav_count,
1277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11UnorderedAccessView **out_unordered_access_views)
1278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(out_render_target_views)
1281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			OMGetRenderTargets(rtv_count, out_render_target_views, out_depth_stencil_view);
1282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(out_unordered_access_views)
1284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			for(unsigned i = 0; i < uav_count; ++i)
1286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				out_unordered_access_views[i] = om_unordered_access_views[uav_start + i].ref();
1287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
1290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE SOSetTargets(
1292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned count,
1293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11Buffer *const *new_so_targets,
1294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const unsigned *new_offsets)
1295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned new_count, i;
1299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		bool changed = false;
1300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		uint32_t append_mask = 0xffffffff;
1302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(!new_so_targets)
1304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			count = 0;
1305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for(new_count = 0, i = 0; i < count; ++i)
1306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			GalliumD3D11Buffer* buffer = static_cast<GalliumD3D11Buffer*>(new_so_targets[i]);
1308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if(buffer != so_buffers[i].p)
1310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{
1311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				changed = true;
1312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				so_buffers[i] = buffer;
1313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				so_targets[i] = buffer ? buffer->so_target : 0;
1314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
1315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if(!buffer)
1316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				continue;
1317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			new_count = i + 1;
1318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if(new_offsets[i] == (unsigned)-1)
1320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{
1321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				assert(so_targets[i]);
1322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				continue;
1323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
1324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			append_mask &= ~(1 << i);
1325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if(!so_targets[i] || new_offsets[i] != so_targets[i]->buffer_offset)
1327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{
1328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				pipe_so_target_reference(&buffer->so_target, NULL);
1329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				buffer->so_target = pipe->create_stream_output_target(
1330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					pipe, buffer->resource, new_offsets[i], buffer->resource->width0 - new_offsets[i]);
1331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				so_targets[i] = buffer->so_target;
1332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				changed = true;
1333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
1334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(i < num_so_targets) {
1336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			changed = true;
1337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			for(; i < num_so_targets; ++i)
1338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				so_buffers[i] = (GalliumD3D11Buffer*)0;
1339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		num_so_targets = new_count;
1341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(likely(caps.so) && (changed || append_mask != 0xffffffff))
1343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			pipe->set_stream_output_targets(pipe, num_so_targets, so_targets, append_mask);
1344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE SOGetTargets(
1347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned count,
1348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11Buffer **out_so_targets
1349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if API < 11
1350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		, UINT *out_offsets
1351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
1352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		)
1353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for(unsigned i = 0; i < count; ++i)
1356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			out_so_targets[i] = so_buffers[i].ref();
1358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if API < 11
1359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			out_offsets[i] = so_targets[i]->buffer_offset;
1360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
1361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE Begin(
1365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11Asynchronous *async)
1366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(caps.queries)
1369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			pipe->begin_query(pipe, ((GalliumD3D11Asynchronous<>*)async)->query);
1370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE End(
1373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11Asynchronous *async)
1374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(caps.queries)
1377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			pipe->end_query(pipe, ((GalliumD3D11Asynchronous<>*)async)->query);
1378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual HRESULT STDMETHODCALLTYPE GetData(
1381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11Asynchronous *iasync,
1382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		void *out_data,
1383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned data_size,
1384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned get_data_flags)
1385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(!caps.queries)
1388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			return E_NOTIMPL;
1389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11Asynchronous<>* async = (GalliumD3D11Asynchronous<>*)iasync;
1391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		void* tmp_data = alloca(async->data_size);
1392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		memset(tmp_data, 0, async->data_size); // sizeof(BOOL) is 4, sizeof(boolean) is 1
1393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		boolean ret = pipe->get_query_result(pipe, async->query, !(get_data_flags & D3D11_ASYNC_GETDATA_DONOTFLUSH), tmp_data);
1394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(out_data)
1395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      {
1396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			memcpy(out_data, tmp_data, std::min(async->data_size, data_size));
1397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return ret ? S_OK : S_FALSE;
1399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void set_render_condition()
1402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(caps.render_condition)
1404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if(!render_predicate)
1406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				pipe->render_condition(pipe, 0, 0);
1407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			else
1408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{
1409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				GalliumD3D11Predicate* predicate = (GalliumD3D11Predicate*)render_predicate.p;
1410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				if(!render_predicate_value && predicate->desc.Query == D3D11_QUERY_OCCLUSION_PREDICATE)
1411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				{
1412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					unsigned mode = (predicate->desc.MiscFlags & D3D11_QUERY_MISC_PREDICATEHINT) ? PIPE_RENDER_COND_NO_WAIT : PIPE_RENDER_COND_WAIT;
1413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					pipe->render_condition(pipe, predicate->query, mode);
1414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				}
1415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				else
1416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				{
1417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					/* TODO: add inverted predication to Gallium*/
1418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					pipe->render_condition(pipe, 0, 0);
1419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				}
1420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
1421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE SetPredication(
1425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11Predicate *new_predicate,
1426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		BOOL new_predicate_value)
1427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(render_predicate.p != new_predicate || render_predicate_value != new_predicate_value)
1430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			render_predicate = new_predicate;
1432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			render_predicate_value = new_predicate_value;
1433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			set_render_condition();
1434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE GetPredication(
1438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11Predicate **out_predicate,
1439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		BOOL *out_predicate_value)
1440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(out_predicate)
1443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			*out_predicate = render_predicate.ref();
1444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(out_predicate_value)
1445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			*out_predicate_value = render_predicate_value;
1446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	static unsigned d3d11_subresource_to_level(struct pipe_resource* resource, unsigned subresource)
1449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(subresource <= resource->last_level)
1451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			return subresource;
1453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		else
1455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned levels = resource->last_level + 1;
1457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			return subresource % levels;
1458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	static unsigned d3d11_subresource_to_layer(struct pipe_resource* resource, unsigned subresource)
1462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(subresource <= resource->last_level)
1464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			return 0;
1466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		else
1468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned levels = resource->last_level + 1;
1470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			return subresource / levels;
1471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* TODO: deferred contexts will need a different implementation of this,
1476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * because we can't put the transfer info into the resource itself.
1477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * Also, there are very different restrictions, for obvious reasons.
1478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 */
1479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual HRESULT STDMETHODCALLTYPE Map(
1480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11Resource *iresource,
1481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned subresource,
1482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		D3D11_MAP map_type,
1483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned map_flags,
1484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		D3D11_MAPPED_SUBRESOURCE *mapped_resource)
1485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11Resource<>* resource = (GalliumD3D11Resource<>*)iresource;
1488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(resource->transfers.count(subresource))
1489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			return E_FAIL;
1490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned level = d3d11_subresource_to_level(resource->resource, subresource);
1491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned layer = d3d11_subresource_to_layer(resource->resource, subresource);
1492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe_box box = d3d11_to_pipe_box(resource->resource, level, 0);
1493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		box.z += layer;
1494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned usage = 0;
1495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(map_type == D3D11_MAP_READ)
1496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			usage = PIPE_TRANSFER_READ;
1497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		else if(map_type == D3D11_MAP_WRITE)
1498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			usage = PIPE_TRANSFER_WRITE;
1499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		else if(map_type == D3D11_MAP_READ_WRITE)
1500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			usage = PIPE_TRANSFER_READ_WRITE;
1501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		else if(map_type == D3D11_MAP_WRITE_DISCARD)
1502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			usage = PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD;
1503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		else if(map_type == D3D11_MAP_WRITE_NO_OVERWRITE)
1504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			usage = PIPE_TRANSFER_WRITE | PIPE_TRANSFER_UNSYNCHRONIZED;
1505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		else
1506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			return E_INVALIDARG;
1507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(map_type & D3D10_MAP_FLAG_DO_NOT_WAIT)
1508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			usage |= PIPE_TRANSFER_DONTBLOCK;
1509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct pipe_transfer* transfer = pipe->get_transfer(pipe, resource->resource, level, usage, &box);
1510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(!transfer) {
1511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if(map_type & D3D10_MAP_FLAG_DO_NOT_WAIT)
1512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				return DXGI_ERROR_WAS_STILL_DRAWING;
1513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			else
1514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				return E_FAIL;
1515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		resource->transfers[subresource] = transfer;
1517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		mapped_resource->pData = pipe->transfer_map(pipe, transfer);
1518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		mapped_resource->RowPitch = transfer->stride;
1519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		mapped_resource->DepthPitch = transfer->layer_stride;
1520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return S_OK;
1521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE Unmap(
1524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11Resource *iresource,
1525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned subresource)
1526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11Resource<>* resource = (GalliumD3D11Resource<>*)iresource;
1529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		std::unordered_map<unsigned, pipe_transfer*>::iterator i = resource->transfers.find(subresource);
1530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(i != resource->transfers.end())
1531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			pipe->transfer_unmap(pipe, i->second);
1533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			pipe->transfer_destroy(pipe, i->second);
1534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			resource->transfers.erase(i);
1535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE CopySubresourceRegion(
1539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11Resource *dst_resource,
1540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned dst_subresource,
1541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned dst_x,
1542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned dst_y,
1543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned dst_z,
1544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11Resource *src_resource,
1545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned src_subresource,
1546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const D3D11_BOX *src_box)
1547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11Resource<>* dst = (GalliumD3D11Resource<>*)dst_resource;
1550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11Resource<>* src = (GalliumD3D11Resource<>*)src_resource;
1551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned dst_level = d3d11_subresource_to_level(dst->resource, dst_subresource);
1552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned dst_layer = d3d11_subresource_to_layer(dst->resource, dst_subresource);
1553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned src_level = d3d11_subresource_to_level(src->resource, src_subresource);
1554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned src_layer = d3d11_subresource_to_layer(src->resource, src_subresource);
1555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe_box box = d3d11_to_pipe_box(src->resource, src_level, src_box);
1556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		dst_z += dst_layer;
1557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		box.z += src_layer;
1558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			pipe->resource_copy_region(pipe,
1560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				dst->resource, dst_level, dst_x, dst_y, dst_z,
1561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				src->resource, src_level, &box);
1562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE CopyResource(
1566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11Resource *dst_resource,
1567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11Resource *src_resource)
1568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11Resource<>* dst = (GalliumD3D11Resource<>*)dst_resource;
1571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11Resource<>* src = (GalliumD3D11Resource<>*)src_resource;
1572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned level;
1573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for(level = 0; level <= dst->resource->last_level; ++level)
1574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			pipe_box box;
1576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			box.x = box.y = box.z = 0;
1577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			box.width = u_minify(dst->resource->width0, level);
1578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			box.height = u_minify(dst->resource->height0, level);
1579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if(dst->resource->target == PIPE_TEXTURE_3D)
1580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				box.depth = u_minify(dst->resource->depth0, level);
1581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			else
1582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				box.depth = dst->resource->array_size;
1583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			pipe->resource_copy_region(pipe,
1584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						   dst->resource, level, 0, 0, 0,
1585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						   src->resource, level, &box);
1586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE UpdateSubresource(
1590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11Resource *dst_resource,
1591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned dst_subresource,
1592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const D3D11_BOX *pDstBox,
1593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const void *pSrcData,
1594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned src_row_pitch,
1595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned src_depth_pitch)
1596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11Resource<>* dst = (GalliumD3D11Resource<>*)dst_resource;
1599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned dst_level = d3d11_subresource_to_level(dst->resource, dst_subresource);
1600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned dst_layer = d3d11_subresource_to_layer(dst->resource, dst_subresource);
1601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe_box box = d3d11_to_pipe_box(dst->resource, dst_level, pDstBox);
1602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		box.z += dst_layer;
1603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->transfer_inline_write(pipe, dst->resource, dst_level, PIPE_TRANSFER_WRITE, &box, pSrcData, src_row_pitch, src_depth_pitch);
1604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if API >= 11
1607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE CopyStructureCount(
1608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11Buffer *dst_buffer,
1609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned dst_aligned_byte_offset,
1610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11UnorderedAccessView *src_view)
1611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
1615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE ClearRenderTargetView(
1617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11RenderTargetView *render_target_view,
1618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const float color[4])
1619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11RenderTargetView* view = ((GalliumD3D11RenderTargetView*)render_target_view);
1622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		union pipe_color_union cc;
1623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cc.f[0] = color[0];
1624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cc.f[1] = color[1];
1625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cc.f[2] = color[2];
1626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cc.f[3] = color[3];
1627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->clear_render_target(pipe, view->object, &cc, 0, 0, view->object->width, view->object->height);
1628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE ClearDepthStencilView(
1631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11DepthStencilView  *depth_stencil_view,
1632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned clear_flags,
1633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		float depth,
1634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		UINT8 stencil)
1635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DepthStencilView* view = ((GalliumD3D11DepthStencilView*)depth_stencil_view);
1638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned flags = 0;
1639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(clear_flags & D3D11_CLEAR_DEPTH)
1640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			flags |= PIPE_CLEAR_DEPTH;
1641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(clear_flags & D3D11_CLEAR_STENCIL)
1642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			flags |= PIPE_CLEAR_STENCIL;
1643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->clear_depth_stencil(pipe, view->object, flags, depth, stencil, 0, 0, view->object->width, view->object->height);
1644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if API >= 11
1647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE ClearUnorderedAccessViewUint(
1648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11UnorderedAccessView *unordered_access_view,
1649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const unsigned values[4])
1650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE ClearUnorderedAccessViewFloat(
1655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			ID3D11UnorderedAccessView *unordered_access_view,
1656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			const float values[4])
1657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
1661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void restore_gallium_state_blit_only()
1663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->bind_blend_state(pipe, blend_state.p ? blend_state.p->object : default_blend);
1665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->bind_depth_stencil_alpha_state(pipe, depth_stencil_state.p ? depth_stencil_state.p->object : default_depth_stencil);
1666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->bind_rasterizer_state(pipe, rasterizer_state.p ? rasterizer_state.p->object : default_rasterizer);
1667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->bind_vertex_elements_state(pipe, input_layout.p ? input_layout.p->object : default_input_layout);
1668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->bind_fs_state(pipe, shaders[D3D11_STAGE_PS].p ? shaders[D3D11_STAGE_PS].p->object : default_shaders[PIPE_SHADER_FRAGMENT]);
1669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->bind_vs_state(pipe, shaders[D3D11_STAGE_VS].p ? shaders[D3D11_STAGE_VS].p->object : default_shaders[PIPE_SHADER_VERTEX]);
1670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(caps.gs)
1671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			pipe->bind_gs_state(pipe, shaders[D3D11_STAGE_GS].p ? shaders[D3D11_STAGE_GS].p->object : default_shaders[PIPE_SHADER_GEOMETRY]);
1672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(caps.so && num_so_targets)
1673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			pipe->set_stream_output_targets(pipe, num_so_targets, so_targets, ~0);
1674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		set_framebuffer();
1675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		set_viewport();
1676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		set_render_condition();
1677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		update_flags |= UPDATE_VERTEX_BUFFERS | (1 << (UPDATE_SAMPLERS_SHIFT + D3D11_STAGE_PS)) | (1 << (UPDATE_VIEWS_SHIFT + D3D11_STAGE_PS));
1679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE RestoreGalliumStateBlitOnly()
1682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		restore_gallium_state_blit_only();
1685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE GenerateMips(
1688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11ShaderResourceView *shader_resource_view)
1689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11ShaderResourceView* view = (GalliumD3D11ShaderResourceView*)shader_resource_view;
1693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(caps.gs)
1694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			pipe->bind_gs_state(pipe, 0);
1695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(caps.so && num_so_targets)
1696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			pipe->set_stream_output_targets(pipe, 0, NULL, 0);
1697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(pipe->render_condition)
1698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			pipe->render_condition(pipe, 0, 0);
1699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for(unsigned layer = view->object->u.tex.first_layer; layer <= view->object->u.tex.last_layer; ++layer)
1700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			util_gen_mipmap(gen_mipmap, view->object, layer, view->object->u.tex.first_level, view->object->u.tex.last_level, PIPE_TEX_FILTER_LINEAR);
1701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		restore_gallium_state_blit_only();
1702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE RestoreGalliumState()
1705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		restore_gallium_state_blit_only();
1708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		set_index_buffer();
1710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		set_stencil_ref();
1711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->set_blend_color(pipe, (struct pipe_blend_color*)blend_color);
1712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->set_sample_mask(pipe, sample_mask);
1713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for(unsigned s = 0; s < 3; ++s)
1715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned num = std::min(caps.constant_buffers[s], (unsigned)D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT);
1717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			for(unsigned i = 0; i < num; ++i)
1718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				pipe_set_constant_buffer(pipe, s, i, constant_buffers[s][i].p ? constant_buffers[s][i].p->resource : 0);
1719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		update_flags |= (1 << (UPDATE_SAMPLERS_SHIFT + D3D11_STAGE_VS)) | (1 << (UPDATE_VIEWS_SHIFT + D3D11_STAGE_VS));
1722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		update_flags |= (1 << (UPDATE_SAMPLERS_SHIFT + D3D11_STAGE_GS)) | (1 << (UPDATE_VIEWS_SHIFT + D3D11_STAGE_GS));
1723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		set_scissor();
1725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if API >= 11
1728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* TODO: hack SRVs or sampler states to handle this, or add to Gallium */
1729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE SetResourceMinLOD(
1730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11Resource *iresource,
1731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		float min_lod)
1732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11Resource<>* resource = (GalliumD3D11Resource<>*)iresource;
1735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(resource->min_lod != min_lod)
1736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			// TODO: actually do anything?
1738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			resource->min_lod = min_lod;
1739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual float STDMETHODCALLTYPE GetResourceMinLOD(
1743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11Resource *iresource)
1744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11Resource<>* resource = (GalliumD3D11Resource<>*)iresource;
1747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return resource->min_lod;
1748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
1750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE ResolveSubresource(
1752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11Resource *dst_resource,
1753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned dst_subresource,
1754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11Resource *src_resource,
1755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned src_subresource,
1756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		DXGI_FORMAT format)
1757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11Resource<>* dst = (GalliumD3D11Resource<>*)dst_resource;
1760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11Resource<>* src = (GalliumD3D11Resource<>*)src_resource;
1761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct pipe_resolve_info info;
1762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.dst.res = dst->resource;
1764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.src.res = src->resource;
1765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.dst.level = 0;
1766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.dst.layer = d3d11_subresource_to_layer(dst->resource, dst_subresource);
1767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.src.layer = d3d11_subresource_to_layer(src->resource, src_subresource);
1768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.src.x0 = 0;
1770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.src.x1 = info.src.res->width0;
1771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.src.y0 = 0;
1772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.src.y1 = info.src.res->height0;
1773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.dst.x0 = 0;
1774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.dst.x1 = info.dst.res->width0;
1775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.dst.y0 = 0;
1776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.dst.y1 = info.dst.res->height0;
1777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		info.mask = PIPE_MASK_RGBA | PIPE_MASK_ZS;
1779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pipe->resource_resolve(pipe, &info);
1781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if API >= 11
1784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE ExecuteCommandList(
1785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11CommandList *command_list,
1786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		BOOL restore_context_state)
1787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual HRESULT STDMETHODCALLTYPE FinishCommandList(
1792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		BOOL restore_deferred_context_state,
1793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ID3D11CommandList **out_command_list)
1794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return E_NOTIMPL;
1797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
1799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE ClearState(void)
1801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		/* we don't take a lock here because we would deadlock otherwise
1803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 * TODO: this is probably incorrect, because ClearState should likely be atomic.
1804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 * However, I can't think of any correct usage that would be affected by this
1805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 * being non-atomic, and making this atomic is quite expensive and complicates
1806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 * the code
1807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 */
1808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		// we qualify all calls so that we avoid virtual dispatch and might get them inlined
1810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		// TODO: make sure all this gets inlined, which might require more compiler flags
1811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		// TODO: optimize this
1812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if API >= 11
1813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::PSSetShader(0, 0, 0);
1814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::GSSetShader(0, 0, 0);
1815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::VSSetShader(0, 0, 0);
1816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::HSSetShader(0, 0, 0);
1817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::DSSetShader(0, 0, 0);
1818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::CSSetShader(0, 0, 0);
1819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
1820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::PSSetShader(0);
1821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::GSSetShader(0);
1822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::VSSetShader(0);
1823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
1824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::IASetInputLayout(0);
1826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::IASetIndexBuffer(0, DXGI_FORMAT_UNKNOWN, 0);
1827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::RSSetState(0);
1828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::OMSetDepthStencilState(0, 0);
1829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::OMSetBlendState(0, (float*)zero_data, ~0);
1830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::SetPredication(0, 0);
1831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_UNDEFINED);
1832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::PSSetConstantBuffers(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, (ID3D11Buffer**)zero_data);
1834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::GSSetConstantBuffers(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, (ID3D11Buffer**)zero_data);
1835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::VSSetConstantBuffers(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, (ID3D11Buffer**)zero_data);
1836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if API >= 11
1837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::HSSetConstantBuffers(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, (ID3D11Buffer**)zero_data);
1838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::DSSetConstantBuffers(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, (ID3D11Buffer**)zero_data);
1839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::CSSetConstantBuffers(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, (ID3D11Buffer**)zero_data);
1840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
1841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::IASetVertexBuffers(0, num_vertex_buffers, (ID3D11Buffer**)zero_data, (unsigned*)zero_data, (unsigned*)zero_data);
1843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if API >= 11
1844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::OMSetRenderTargetsAndUnorderedAccessViews(0, 0, 0 , 0, 0, 0, 0);
1845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
1846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::OMSetRenderTargets(0, 0, 0 );
1847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
1848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::SOSetTargets(0, 0, 0);
1849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::PSSetShaderResources(0, num_shader_resource_views[D3D11_STAGE_PS], (ID3D11ShaderResourceView**)zero_data);
1851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::GSSetShaderResources(0, num_shader_resource_views[D3D11_STAGE_GS], (ID3D11ShaderResourceView**)zero_data);
1852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::VSSetShaderResources(0, num_shader_resource_views[D3D11_STAGE_VS], (ID3D11ShaderResourceView**)zero_data);
1853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if API >= 11
1854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::HSSetShaderResources(0, num_shader_resource_views[D3D11_STAGE_HS], (ID3D11ShaderResourceView**)zero_data);
1855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::DSSetShaderResources(0, num_shader_resource_views[D3D11_STAGE_DS], (ID3D11ShaderResourceView**)zero_data);
1856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::CSSetShaderResources(0, num_shader_resource_views[D3D11_STAGE_CS], (ID3D11ShaderResourceView**)zero_data);
1857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
1858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::PSSetSamplers(0, num_shader_resource_views[D3D11_STAGE_PS], (ID3D11SamplerState**)zero_data);
1860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::GSSetSamplers(0, num_shader_resource_views[D3D11_STAGE_GS], (ID3D11SamplerState**)zero_data);
1861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::VSSetSamplers(0, num_shader_resource_views[D3D11_STAGE_VS], (ID3D11SamplerState**)zero_data);
1862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if API >= 11
1863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::HSSetSamplers(0, num_shader_resource_views[D3D11_STAGE_HS], (ID3D11SamplerState**)zero_data);
1864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::DSSetSamplers(0, num_shader_resource_views[D3D11_STAGE_DS], (ID3D11SamplerState**)zero_data);
1865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::CSSetSamplers(0, num_shader_resource_views[D3D11_STAGE_CS], (ID3D11SamplerState**)zero_data);
1866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
1867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::RSSetViewports(0, 0);
1869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GalliumD3D11DeviceContext::RSSetScissorRects(0, 0);
1870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual void STDMETHODCALLTYPE Flush(void)
1873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                pipe->flush(pipe, 0);
1876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* In Direct3D 10, if the reference count of an object drops to 0, it is automatically
1879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * cleanly unbound from the pipeline.
1880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * In Direct3D 11, the pipeline holds a reference.
1881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 *
1882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * Note that instead of always scanning the pipeline on destruction, we could
1883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * maintain the internal reference count on DirectX 10 and use it to check if an
1884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * object is still bound.
1885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * Presumably, on average, scanning is faster if the application is well written.
1886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 */
1887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if API < 11
1888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define IMPLEMENT_SIMPLE_UNBIND(name, member, gallium, def) \
1889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void Unbind##name(ID3D11##name* state) \
1890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{ \
1891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED; \
1892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if((void*)state == (void*)member.p) \
1893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{ \
1894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			member.p = 0; \
1895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			pipe->bind_##gallium##_state(pipe, default_##def); \
1896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		} \
1897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	IMPLEMENT_SIMPLE_UNBIND(BlendState, blend_state, blend, blend)
1899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	IMPLEMENT_SIMPLE_UNBIND(RasterizerState, rasterizer_state, rasterizer, rasterizer)
1900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	IMPLEMENT_SIMPLE_UNBIND(DepthStencilState, depth_stencil_state, depth_stencil_alpha, depth_stencil)
1901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	IMPLEMENT_SIMPLE_UNBIND(InputLayout, input_layout, vertex_elements, input_layout)
1902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	IMPLEMENT_SIMPLE_UNBIND(PixelShader, shaders[D3D11_STAGE_PS], fs, shaders[D3D11_STAGE_PS])
1903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	IMPLEMENT_SIMPLE_UNBIND(VertexShader, shaders[D3D11_STAGE_VS], vs, shaders[D3D11_STAGE_VS])
1904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	IMPLEMENT_SIMPLE_UNBIND(GeometryShader, shaders[D3D11_STAGE_GS], gs, shaders[D3D11_STAGE_GS])
1905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void UnbindPredicate(ID3D11Predicate* predicate)
1907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(predicate == render_predicate)
1910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			render_predicate.p = NULL;
1912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			render_predicate_value = 0;
1913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			pipe->render_condition(pipe, 0, 0);
1914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void UnbindSamplerState(ID3D11SamplerState* state)
1918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for(unsigned s = 0; s < D3D11_STAGES; ++s)
1921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			for(unsigned i = 0; i < num_samplers[s]; ++i)
1923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{
1924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				if(samplers[s][i] == state)
1925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				{
1926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					samplers[s][i].p = NULL;
1927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					sampler_csos[s][i] = NULL;
1928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					update_flags |= (1 << (UPDATE_SAMPLERS_SHIFT + s));
1929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				}
1930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
1931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void UnbindBuffer(ID3D11Buffer* buffer)
1935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(buffer == index_buffer)
1938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			index_buffer.p = 0;
1940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			index_format = DXGI_FORMAT_UNKNOWN;
1941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			index_offset = 0;
1942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			struct pipe_index_buffer ib;
1943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			memset(&ib, 0, sizeof(ib));
1944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			pipe->set_index_buffer(pipe, &ib);
1945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for(unsigned i = 0; i < num_vertex_buffers; ++i)
1948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if(buffer == input_buffers[i])
1950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{
1951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				input_buffers[i].p = 0;
1952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				memset(&vertex_buffers[num_vertex_buffers], 0, sizeof(vertex_buffers[num_vertex_buffers]));
1953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				update_flags |= UPDATE_VERTEX_BUFFERS;
1954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
1955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for(unsigned s = 0; s < D3D11_STAGES; ++s)
1958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			for(unsigned i = 0; i < sizeof(constant_buffers) / sizeof(constant_buffers[0]); ++i)
1960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{
1961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				if(constant_buffers[s][i] == buffer)
1962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				{
1963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					constant_buffers[s][i] = (ID3D10Buffer*)NULL;
1964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					pipe_set_constant_buffer(pipe, s, i, NULL);
1965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				}
1966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
1967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void UnbindDepthStencilView(ID3D11DepthStencilView * view)
1971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(view == depth_stencil_view)
1974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			depth_stencil_view.p = NULL;
1976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			set_framebuffer();
1977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void UnbindRenderTargetView(ID3D11RenderTargetView* view)
1981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		bool any_bound = false;
1984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for(unsigned i = 0; i < num_render_target_views; ++i)
1985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
1986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if(render_target_views[i] == view)
1987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{
1988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				render_target_views[i].p = NULL;
1989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				any_bound = true;
1990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
1991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
1992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(any_bound)
1993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			set_framebuffer();
1994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
1995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void UnbindShaderResourceView(ID3D11ShaderResourceView* view)
1997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
1998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		SYNCHRONIZED;
1999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for(unsigned s = 0; s < D3D11_STAGES; ++s)
2000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
2001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			for(unsigned i = 0; i < num_shader_resource_views[s]; ++i)
2002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			{
2003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				if(shader_resource_views[s][i] == view)
2004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				{
2005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					shader_resource_views[s][i].p = NULL;
2006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					sampler_views[s][i] = NULL;
2007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					update_flags |= (1 << (UPDATE_VIEWS_SHIFT + s));
2008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				}
2009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
2010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
2011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
2012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
2013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#undef SYNCHRONIZED
2015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
2016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if API >= 11
2018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* This approach serves two purposes.
2019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * First, we don't want to do an atomic operation to manipulate the reference
2020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * count every time something is bound/unbound to the pipeline, since they are
2021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * expensive.
2022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Fortunately, the immediate context can only be used by a single thread, so
2023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * we don't have to use them, as long as a separate reference count is used
2024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * (see dual_refcnt_t).
2025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
2026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Second, we want to avoid the Device -> DeviceContext -> bound DeviceChild -> Device
2027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * garbage cycle.
2028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * To avoid it, DeviceChild doesn't hold a reference to Device as usual, but adds
2029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * one for each external reference count, while internal nonatomic_add_ref doesn't
2030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * add any.
2031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
2032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Note that ideally we would to eliminate the non-atomic op too, but this is more
2033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * complicated, since we would either need to use garbage collection and give up
2034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * deterministic destruction (especially bad for large textures), or scan the whole
2035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * pipeline state every time the reference count of object drops to 0, which risks
2036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * pathological slowdowns.
2037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
2038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Since this microoptimization should matter relatively little, let's avoid it for now.
2039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
2040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Note that deferred contexts don't use this, since as a whole, they must thread-safe.
2041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Eliminating the atomic ops for deferred contexts seems substantially harder.
2042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This might be a problem if they are used in a one-shot multithreaded rendering
2043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * fashion, where SMP cacheline bouncing on the reference count may be visible.
2044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
2045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The idea would be to attach a structure of reference counts indexed by deferred
2046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * context id to each object. Ideally, this should be organized like ext2 block pointers.
2047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
2048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Every deferred context would get a reference count in its own cacheline.
2049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The external count is protected by a lock bit, and there is also a "lock bit" in each
2050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * internal count.
2051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
2052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * When the external count has to be dropped to 0, the lock bit is taken and all internal
2053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * reference counts are scanned, taking a count of them. A flag would also be set on them.
2054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Deferred context manipulation would notice the flag, and update the count.
2055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Once the count goes to zero, the object is freed.
2056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
2057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The problem of this is that if the external reference count ping-pongs between
2058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * zero and non-zero, the scans will take a lot of time.
2059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
2060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The idea to solve this is to compute the scans in a binary-tree like fashion, where
2061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * each binary tree node would have a "determined bit", which would be invalidated
2062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * by manipulations.
2063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
2064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * However, all this complexity might actually be a loss in most cases, so let's just
2065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * stick to a single atomic refcnt for now.
2066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
2067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Also, we don't even support deferred contexts yet, so this can wait.
2068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
2069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct nonatomic_device_child_ptr_traits
2070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	static void add_ref(void* p)
2072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
2073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(p)
2074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			((GalliumD3D11DeviceChild<>*)p)->nonatomic_add_ref();
2075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
2076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	static void release(void* p)
2078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
2079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(p)
2080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			((GalliumD3D11DeviceChild<>*)p)->nonatomic_release();
2081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
2082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
2083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct GalliumD3D11ImmediateDeviceContext
2085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	: public GalliumD3D11DeviceContext<nonatomic_device_child_ptr_traits>
2086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	GalliumD3D11ImmediateDeviceContext(GalliumD3D11Screen* device, pipe_context* pipe, unsigned context_flags = 0)
2088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	: GalliumD3D11DeviceContext<nonatomic_device_child_ptr_traits>(device, pipe, context_flags)
2089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
2090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		// not necessary, but tests that the API at least basically works
2091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ClearState();
2092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
2093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* we do this since otherwise we would have a garbage cycle between this and the device */
2095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual ULONG STDMETHODCALLTYPE AddRef()
2096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
2097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return this->device->AddRef();
2098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
2099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual ULONG STDMETHODCALLTYPE Release()
2101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
2102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return this->device->Release();
2103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
2104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	virtual D3D11_DEVICE_CONTEXT_TYPE STDMETHODCALLTYPE GetType()
2106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
2107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return D3D11_DEVICE_CONTEXT_IMMEDIATE;
2108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
2109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
2110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic ID3D11DeviceContext* GalliumD3D11ImmediateDeviceContext_Create(GalliumD3D11Screen* device, struct pipe_context* pipe, bool owns_pipe)
2112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return new GalliumD3D11ImmediateDeviceContext(device, pipe, owns_pipe);
2114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void GalliumD3D11ImmediateDeviceContext_RestoreGalliumState(ID3D11DeviceContext* context)
2117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	((GalliumD3D11ImmediateDeviceContext*)context)->RestoreGalliumState();
2119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void GalliumD3D11ImmediateDeviceContext_RestoreGalliumStateBlitOnly(ID3D11DeviceContext* context)
2122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	((GalliumD3D11ImmediateDeviceContext*)context)->RestoreGalliumStateBlitOnly();
2124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void GalliumD3D11ImmediateDeviceContext_Destroy(ID3D11DeviceContext* context)
2127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	delete (GalliumD3D11ImmediateDeviceContext*)context;
2129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
2131