Home | History | Annotate | Download | only in gd3d11
      1 /**************************************************************************
      2  *
      3  * Copyright 2010 Luca Barbieri
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining
      6  * a copy of this software and associated documentation files (the
      7  * "Software"), to deal in the Software without restriction, including
      8  * without limitation the rights to use, copy, modify, merge, publish,
      9  * distribute, sublicense, and/or sell copies of the Software, and to
     10  * permit persons to whom the Software is furnished to do so, subject to
     11  * the following conditions:
     12  *
     13  * The above copyright notice and this permission notice (including the
     14  * next paragraph) shall be included in all copies or substantial
     15  * portions of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     20  * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
     21  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
     22  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     23  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     24  *
     25  **************************************************************************/
     26 
     27 DEBUG_GET_ONCE_BOOL_OPTION(dump_shaders, "D3D1X_DUMP_SHADERS", FALSE);
     28 
     29 /* These cap sets are much more correct than the ones in u_caps.c */
     30 /* TODO: it seems cube levels should be the same as 2D levels */
     31 
     32 /* DX 9_1 */
     33 static unsigned caps_dx_9_1[] = {
     34 	UTIL_CHECK_INT(MAX_RENDER_TARGETS, 1),
     35 	UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 12),	/* 2048 */
     36 	UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS, 8),	 /* 256 */
     37 	UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS, 10), /* 512 */
     38 	UTIL_CHECK_TERMINATE
     39 };
     40 
     41 /* DX 9_2 */
     42 static unsigned caps_dx_9_2[] = {
     43 	UTIL_CHECK_CAP(OCCLUSION_QUERY),
     44 	UTIL_CHECK_CAP(TWO_SIDED_STENCIL),
     45 	UTIL_CHECK_CAP(TEXTURE_MIRROR_CLAMP),
     46 	UTIL_CHECK_CAP(BLEND_EQUATION_SEPARATE),
     47 	UTIL_CHECK_INT(MAX_RENDER_TARGETS, 1),
     48 	UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 12),	/* 2048 */
     49 	UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS, 9),	 /* 256 */
     50 	UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS, 10), /* 512 */
     51 	UTIL_CHECK_TERMINATE
     52 };
     53 
     54 /* DX 9_3 */
     55 static unsigned caps_dx_9_3[] = {
     56 	UTIL_CHECK_CAP(OCCLUSION_QUERY),
     57 	UTIL_CHECK_CAP(TWO_SIDED_STENCIL),
     58 	UTIL_CHECK_CAP(TEXTURE_MIRROR_CLAMP),
     59 	UTIL_CHECK_CAP(BLEND_EQUATION_SEPARATE),
     60 	UTIL_CHECK_CAP(SM3),
     61 	UTIL_CHECK_CAP(VERTEX_ELEMENT_INSTANCE_DIVISOR),
     62 	UTIL_CHECK_CAP(OCCLUSION_QUERY),
     63 	UTIL_CHECK_INT(MAX_RENDER_TARGETS, 4),
     64 	UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 13),	/* 4096 */
     65 	UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS, 9),	 /* 256 */
     66 	UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS, 10), /* 512 */
     67 	UTIL_CHECK_TERMINATE
     68 };
     69 
     70 static unsigned caps_dx_10_0[] = {
     71 	UTIL_CHECK_CAP(INDEP_BLEND_ENABLE),
     72 	UTIL_CHECK_CAP(ANISOTROPIC_FILTER),
     73 	UTIL_CHECK_CAP(MIXED_COLORBUFFER_FORMATS),
     74 	UTIL_CHECK_CAP(FRAGMENT_COLOR_CLAMP_CONTROL),
     75 	UTIL_CHECK_CAP(CONDITIONAL_RENDER),
     76 	UTIL_CHECK_CAP(PRIMITIVE_RESTART),
     77 	UTIL_CHECK_CAP(TGSI_INSTANCEID),
     78 	UTIL_CHECK_INT(MAX_RENDER_TARGETS, 8),
     79 	UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 13),
     80 	UTIL_CHECK_INT(MAX_TEXTURE_ARRAY_LAYERS, 512),
     81 	UTIL_CHECK_INT(MAX_STREAM_OUTPUT_BUFFERS, 4),
     82 	UTIL_CHECK_SHADER(VERTEX, MAX_INPUTS, 16),
     83 	UTIL_CHECK_SHADER(GEOMETRY, MAX_CONST_BUFFERS, 14),
     84 	UTIL_CHECK_SHADER(GEOMETRY, MAX_TEXTURE_SAMPLERS, 16),
     85 	UTIL_CHECK_SHADER(GEOMETRY, SUBROUTINES, 1),
     86 	UTIL_CHECK_SHADER(FRAGMENT, INTEGERS, 1),
     87 	UTIL_CHECK_TERMINATE
     88 };
     89 
     90 
     91 // this is called "screen" because in the D3D10 case it's only part of the device
     92 template<bool threadsafe>
     93 struct GalliumD3D11ScreenImpl : public GalliumD3D11Screen
     94 {
     95 	D3D_FEATURE_LEVEL feature_level;
     96 	int format_support[PIPE_FORMAT_COUNT];
     97 	unsigned creation_flags;
     98 	unsigned exception_mode;
     99 	maybe_mutex_t<threadsafe> mutex;
    100 
    101 /* TODO: Direct3D 11 specifies that fine-grained locking should be used if the driver supports it.
    102  * Right now, I don't trust Gallium drivers to get this right.
    103  */
    104 #define SYNCHRONIZED lock_t<maybe_mutex_t<threadsafe> > lock_(mutex)
    105 
    106 	GalliumD3D11ScreenImpl(struct pipe_screen* screen, struct pipe_context* immediate_pipe, BOOL owns_immediate_pipe,unsigned creation_flags, IDXGIAdapter* adapter)
    107 	: GalliumD3D11Screen(screen, immediate_pipe, adapter), creation_flags(creation_flags)
    108 	{
    109 		memset(&screen_caps, 0, sizeof(screen_caps));
    110 		screen_caps.gs = screen->get_shader_param(screen, PIPE_SHADER_GEOMETRY, PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0;
    111 		screen_caps.so = screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS) > 0;
    112 		screen_caps.queries = screen->get_param(screen, PIPE_CAP_OCCLUSION_QUERY);
    113 		screen_caps.render_condition = screen->get_param(screen, PIPE_CAP_CONDITIONAL_RENDER);
    114 		for(unsigned i = 0; i < PIPE_SHADER_TYPES; ++i)
    115 			screen_caps.constant_buffers[i] = screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_CONST_BUFFERS);
    116 		screen_caps.stages = 0;
    117 		for(unsigned i = 0; i < PIPE_SHADER_TYPES; ++i)
    118 		{
    119 			if(!screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_INSTRUCTIONS))
    120 				break;
    121 			screen_caps.stages = i + 1;
    122 		}
    123 
    124 		screen_caps.stages_with_sampling = (1 << screen_caps.stages) - 1;
    125 		if(!screen->get_shader_param(screen, PIPE_SHADER_VERTEX, PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS))
    126 			screen_caps.stages_with_sampling &=~ (1 << PIPE_SHADER_VERTEX);
    127 
    128 		memset(format_support, 0xff, sizeof(format_support));
    129 
    130 		float default_level = 9.1f;
    131 		if(!util_check_caps(screen, caps_dx_9_1))
    132 			_debug_printf("Warning: driver does not even meet D3D_FEATURE_LEVEL_9_1 features, advertising it anyway!\n");
    133 		else if(!util_check_caps(screen, caps_dx_9_2))
    134 			default_level = 9.1f;
    135 		else if(!util_check_caps(screen, caps_dx_9_3))
    136 			default_level = 9.2f;
    137 		else if(!util_check_caps(screen, caps_dx_10_0))
    138 			default_level = 9.3f;
    139 		else
    140 			default_level = 10.0f;
    141 
    142 		char default_level_name[64];
    143 		sprintf(default_level_name, "%.1f", default_level);
    144 		float feature_level_number = atof(debug_get_option("D3D11_FEATURE_LEVEL", default_level_name));
    145 		if(!feature_level_number)
    146 			feature_level_number = default_level;
    147 
    148 #if API >= 11
    149 		if(feature_level_number >= 11.0f)
    150 			feature_level = D3D_FEATURE_LEVEL_11_0;
    151 		else
    152 #endif
    153 		if(feature_level_number >= 10.1f)
    154 			feature_level = D3D_FEATURE_LEVEL_10_1;
    155 		else if(feature_level_number >= 10.0f)
    156 			feature_level = D3D_FEATURE_LEVEL_10_0;
    157 		else if(feature_level_number >= 9.3f)
    158 			feature_level = D3D_FEATURE_LEVEL_9_3;
    159 		else if(feature_level_number >= 9.2f)
    160 			feature_level = D3D_FEATURE_LEVEL_9_2;
    161 		else
    162 			feature_level = D3D_FEATURE_LEVEL_9_1;
    163 
    164 #if API >= 11
    165 		immediate_context = GalliumD3D11ImmediateDeviceContext_Create(this, immediate_pipe, owns_immediate_pipe);
    166 		// release to the reference to ourselves that the immediate context took, to avoid a garbage cycle
    167 		immediate_context->Release();
    168 #endif
    169 	}
    170 
    171 	~GalliumD3D11ScreenImpl()
    172 	{
    173 #if API >= 11
    174 		GalliumD3D11ImmediateDeviceContext_Destroy(immediate_context);
    175 #endif
    176 	}
    177 
    178 	virtual D3D_FEATURE_LEVEL STDMETHODCALLTYPE GetFeatureLevel(void)
    179 	{
    180 		return feature_level;
    181 	}
    182 
    183 	virtual unsigned STDMETHODCALLTYPE GetCreationFlags(void)
    184 	{
    185 		return creation_flags;
    186 	}
    187 
    188 	virtual HRESULT STDMETHODCALLTYPE GetDeviceRemovedReason(void)
    189 	{
    190 		return S_OK;
    191 	}
    192 
    193 #if API >= 11
    194 	virtual void STDMETHODCALLTYPE GetImmediateContext(
    195 		ID3D11DeviceContext **out_immediate_context)
    196 	{
    197 		immediate_context->AddRef();
    198 		*out_immediate_context = immediate_context;
    199 	}
    200 #endif
    201 
    202 	virtual HRESULT STDMETHODCALLTYPE SetExceptionMode(unsigned RaiseFlags)
    203 	{
    204 		exception_mode = RaiseFlags;
    205 		return S_OK;
    206 	}
    207 
    208 	virtual unsigned STDMETHODCALLTYPE GetExceptionMode(void)
    209 	{
    210 		return exception_mode;
    211 	}
    212 
    213 	virtual HRESULT STDMETHODCALLTYPE CheckCounter(
    214 		const D3D11_COUNTER_DESC *desc,
    215 		D3D11_COUNTER_TYPE *type,
    216 		unsigned *active_counters,
    217 		LPSTR sz_name,
    218 		unsigned *name_length,
    219 		LPSTR sz_units,
    220 		unsigned *units_length,
    221 		LPSTR sz_description,
    222 		unsigned *description_length)
    223 	{
    224 		return E_NOTIMPL;
    225 	}
    226 
    227 	virtual void STDMETHODCALLTYPE CheckCounterInfo(
    228 		D3D11_COUNTER_INFO *counter_info)
    229 	{
    230 		/* none supported at the moment */
    231 		counter_info->LastDeviceDependentCounter = (D3D11_COUNTER)0;
    232 		counter_info->NumDetectableParallelUnits = 1;
    233 		counter_info->NumSimultaneousCounters = 0;
    234 	}
    235 
    236 #if API >= 11
    237 	virtual HRESULT STDMETHODCALLTYPE CheckFeatureSupport(
    238 		D3D11_FEATURE feature,
    239 		void *out_feature_support_data,
    240 		unsigned feature_support_data_size)
    241 	{
    242 		SYNCHRONIZED;
    243 
    244 		switch(feature)
    245 		{
    246 			case D3D11_FEATURE_THREADING:
    247 			{
    248 				D3D11_FEATURE_DATA_THREADING* data = (D3D11_FEATURE_DATA_THREADING*)out_feature_support_data;
    249 				if(feature_support_data_size != sizeof(*data))
    250 					return E_INVALIDARG;
    251 
    252 				data->DriverCommandLists = FALSE;
    253 				data->DriverConcurrentCreates = FALSE;
    254 				return S_OK;
    255 			}
    256 			case D3D11_FEATURE_DOUBLES:
    257 			{
    258 				D3D11_FEATURE_DATA_DOUBLES* data = (D3D11_FEATURE_DATA_DOUBLES*)out_feature_support_data;
    259 				if(feature_support_data_size != sizeof(*data))
    260 					return E_INVALIDARG;
    261 
    262 				data->DoublePrecisionFloatShaderOps = FALSE;
    263 				return S_OK;
    264 			}
    265 			case D3D11_FEATURE_FORMAT_SUPPORT:
    266 			{
    267 				D3D11_FEATURE_DATA_FORMAT_SUPPORT* data = (D3D11_FEATURE_DATA_FORMAT_SUPPORT*)out_feature_support_data;
    268 				if(feature_support_data_size != sizeof(*data))
    269 					return E_INVALIDARG;
    270 
    271 				return this->CheckFormatSupport(data->InFormat, &data->OutFormatSupport);
    272 			}
    273 			case D3D11_FEATURE_FORMAT_SUPPORT2:
    274 			{
    275 				D3D11_FEATURE_DATA_FORMAT_SUPPORT* data = (D3D11_FEATURE_DATA_FORMAT_SUPPORT*)out_feature_support_data;
    276 				if(feature_support_data_size != sizeof(*data))
    277 					return E_INVALIDARG;
    278 
    279 				data->OutFormatSupport = 0;
    280 				/* TODO: should this be S_OK? */
    281 				return E_INVALIDARG;
    282 			}
    283 			case D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS:
    284 			{
    285 				D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS* data = (D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS*)out_feature_support_data;
    286 				if(feature_support_data_size != sizeof(*data))
    287 					return E_INVALIDARG;
    288 
    289 				data->ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x = FALSE;
    290 				return S_OK;
    291 			}
    292 			default:
    293 				return E_INVALIDARG;
    294 		}
    295 	}
    296 #endif
    297 
    298 	virtual HRESULT STDMETHODCALLTYPE CheckFormatSupport(
    299 		DXGI_FORMAT dxgi_format,
    300 		unsigned *out_format_support
    301 	)
    302 	{
    303 		SYNCHRONIZED;
    304 
    305 		/* TODO: MSAA, advanced features */
    306 
    307 		pipe_format format = dxgi_to_pipe_format[dxgi_format];
    308 		if(!format)
    309 			return E_INVALIDARG;
    310 
    311 		int support = format_support[format];
    312 		if(support < 0)
    313 		{
    314 			support = 0;
    315 
    316 			if(dxgi_format == DXGI_FORMAT_R8_UINT ||
    317 			   dxgi_format == DXGI_FORMAT_R16_UINT ||
    318 			   dxgi_format == DXGI_FORMAT_R32_UINT)
    319 				support |= D3D11_FORMAT_SUPPORT_IA_INDEX_BUFFER;
    320 
    321 			if(screen->is_format_supported(screen, format, PIPE_BUFFER, 0, PIPE_BIND_VERTEX_BUFFER))
    322 				support |= D3D11_FORMAT_SUPPORT_IA_VERTEX_BUFFER;
    323 
    324                         if(screen->is_format_supported(screen, format, PIPE_BUFFER, 0, PIPE_BIND_STREAM_OUTPUT))
    325 				support |= D3D11_FORMAT_SUPPORT_SO_BUFFER;
    326 
    327                         if(screen->is_format_supported(screen, format, PIPE_TEXTURE_1D, 0, PIPE_BIND_SAMPLER_VIEW))
    328 				support |= D3D11_FORMAT_SUPPORT_TEXTURE1D;
    329                         if(screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW))
    330 				support |= D3D11_FORMAT_SUPPORT_TEXTURE2D;
    331                         if(screen->is_format_supported(screen, format, PIPE_TEXTURE_CUBE, 0, PIPE_BIND_SAMPLER_VIEW))
    332 				support |= D3D11_FORMAT_SUPPORT_TEXTURECUBE;
    333                         if(screen->is_format_supported(screen, format, PIPE_TEXTURE_3D, 0, PIPE_BIND_SAMPLER_VIEW))
    334 				support |= D3D11_FORMAT_SUPPORT_TEXTURE3D;
    335 
    336 			if(support & (D3D11_FORMAT_SUPPORT_TEXTURE1D | D3D11_FORMAT_SUPPORT_TEXTURE2D |
    337 				      D3D11_FORMAT_SUPPORT_TEXTURE3D | D3D11_FORMAT_SUPPORT_TEXTURECUBE))
    338 			{
    339 				support |=
    340 					D3D11_FORMAT_SUPPORT_SHADER_LOAD |
    341 					D3D11_FORMAT_SUPPORT_SHADER_SAMPLE |
    342 					D3D11_FORMAT_SUPPORT_MIP |
    343 					D3D11_FORMAT_SUPPORT_MIP_AUTOGEN;
    344 				if(util_format_is_depth_or_stencil(format))
    345 					support |= D3D11_FORMAT_SUPPORT_SHADER_SAMPLE_COMPARISON;
    346 			}
    347 
    348 			if(screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET | PIPE_BIND_BLENDABLE))
    349 				support |= D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_RENDER_TARGET | D3D11_FORMAT_SUPPORT_BLENDABLE;
    350 			else
    351 			if(screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET))
    352 				support |= D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_RENDER_TARGET;
    353 			if(screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL))
    354 				support |= D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_DEPTH_STENCIL;
    355 			if(screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_DISPLAY_TARGET))
    356 				support |= D3D11_FORMAT_SUPPORT_DISPLAY;
    357 
    358 			unsigned ms;
    359 			for(ms = 2; ms <= 8; ++ms)
    360 			{
    361 				if(screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, ms, PIPE_BIND_RENDER_TARGET))
    362 				{
    363 					support |= D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET | D3D11_FORMAT_SUPPORT_MULTISAMPLE_RESOLVE;
    364 					break;
    365 				}
    366 			}
    367 			if(ms <= 8 && screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, ms, PIPE_BIND_SAMPLER_VIEW))
    368 				support |= D3D11_FORMAT_SUPPORT_MULTISAMPLE_LOAD;
    369 
    370 			format_support[format] = support;
    371 		}
    372 		*out_format_support = support;
    373 		return S_OK;
    374 	}
    375 
    376 	virtual HRESULT STDMETHODCALLTYPE CheckMultisampleQualityLevels(
    377 		DXGI_FORMAT format,
    378 		unsigned sample_count,
    379 		unsigned *pcount
    380 	)
    381 	{
    382 		SYNCHRONIZED;
    383 
    384 		if(sample_count == 1)
    385 			*pcount = 1;
    386 		else
    387 			*pcount = 0;
    388 		return S_OK;
    389 	}
    390 
    391 	template<typename T, typename U>
    392 	bool convert_blend_state(T& to, const U& from, unsigned BlendEnable, unsigned RenderTargetWriteMask)
    393 	{
    394 		if(unlikely(BlendEnable &&
    395 			    (from.SrcBlend >= D3D11_BLEND_COUNT ||
    396 			     from.SrcBlendAlpha >= D3D11_BLEND_COUNT ||
    397 			     from.DestBlend >= D3D11_BLEND_COUNT ||
    398 			     from.DestBlendAlpha >= D3D11_BLEND_COUNT ||
    399 			     from.BlendOp >= 6 ||
    400 			     from.BlendOp == 0 ||
    401 			     from.BlendOpAlpha >= 6 ||
    402 			     from.BlendOpAlpha == 0)))
    403 			return false;
    404 
    405 		to.blend_enable = BlendEnable;
    406 
    407 		if(BlendEnable)
    408 		{
    409 			to.rgb_func = from.BlendOp - 1;
    410 			to.alpha_func = from.BlendOpAlpha - 1;
    411 
    412 			to.rgb_src_factor = d3d11_to_pipe_blend[from.SrcBlend];
    413 			to.alpha_src_factor = d3d11_to_pipe_blend[from.SrcBlendAlpha];
    414 			to.rgb_dst_factor = d3d11_to_pipe_blend[from.DestBlend];
    415 			to.alpha_dst_factor = d3d11_to_pipe_blend[from.DestBlendAlpha];
    416 		}
    417 
    418 		to.colormask = RenderTargetWriteMask & 0xf;
    419 		return true;
    420 	}
    421 
    422 #if API >= 11
    423 	virtual HRESULT STDMETHODCALLTYPE CreateBlendState(
    424 		const D3D11_BLEND_DESC *blend_state_desc,
    425 		ID3D11BlendState **out_blend_state
    426 	)
    427 #else
    428 	virtual HRESULT STDMETHODCALLTYPE CreateBlendState1(
    429 		const D3D10_BLEND_DESC1 *blend_state_desc,
    430 		ID3D10BlendState1 **out_blend_state
    431 	)
    432 #endif
    433 	{
    434 		SYNCHRONIZED;
    435 
    436 		pipe_blend_state state;
    437 		memset(&state, 0, sizeof(state));
    438 		state.alpha_to_coverage = !!blend_state_desc->AlphaToCoverageEnable;
    439 		state.independent_blend_enable = !!blend_state_desc->IndependentBlendEnable;
    440 
    441 		assert(PIPE_MAX_COLOR_BUFS >= 8);
    442 		const unsigned n = blend_state_desc->IndependentBlendEnable ? 8 : 1;
    443 		for(unsigned i = 0; i < n; ++i)
    444 		{
    445 			 if(!convert_blend_state(
    446 					 state.rt[i],
    447 					 blend_state_desc->RenderTarget[i],
    448 					 blend_state_desc->RenderTarget[i].BlendEnable,
    449 					 blend_state_desc->RenderTarget[i].RenderTargetWriteMask))
    450 				 return E_INVALIDARG;
    451 		}
    452 
    453 		if(!out_blend_state)
    454 			return S_FALSE;
    455 
    456 		void* object = immediate_pipe->create_blend_state(immediate_pipe, &state);
    457 		if(!object)
    458 			return E_FAIL;
    459 
    460 		*out_blend_state = new GalliumD3D11BlendState(this, object, *blend_state_desc);
    461 		return S_OK;
    462 	}
    463 
    464 #if API < 11
    465 	virtual HRESULT STDMETHODCALLTYPE CreateBlendState(
    466 		const D3D10_BLEND_DESC *blend_state_desc,
    467 		ID3D10BlendState **out_blend_state
    468 	)
    469 	{
    470 		SYNCHRONIZED;
    471 
    472 		pipe_blend_state state;
    473 		memset(&state, 0, sizeof(state));
    474 		state.alpha_to_coverage = !!blend_state_desc->AlphaToCoverageEnable;
    475 		assert(PIPE_MAX_COLOR_BUFS >= 8);
    476 		for(unsigned i = 0; i < 8; ++i)
    477 		{
    478 			if(!convert_blend_state(
    479 				state.rt[i],
    480 				*blend_state_desc,
    481 				blend_state_desc->BlendEnable[i],
    482 				blend_state_desc->RenderTargetWriteMask[i]))
    483 				return E_INVALIDARG;
    484 		}
    485 
    486 		for(unsigned i = 1; i < 8; ++i)
    487 		{
    488 			if(memcmp(&state.rt[0], &state.rt[i], sizeof(state.rt[0])))
    489 			{
    490 				state.independent_blend_enable = TRUE;
    491 				break;
    492 			}
    493 		}
    494 
    495 		void* object = immediate_pipe->create_blend_state(immediate_pipe, &state);
    496 		if(!object)
    497 			return E_FAIL;
    498 
    499 		*out_blend_state = new GalliumD3D11BlendState(this, object, *blend_state_desc);
    500 		return S_OK;
    501 	}
    502 #endif
    503 
    504 	virtual HRESULT STDMETHODCALLTYPE CreateDepthStencilState(
    505 		const D3D11_DEPTH_STENCIL_DESC *depth_stencil_state_desc,
    506 		ID3D11DepthStencilState **depth_stencil_state
    507 	)
    508 	{
    509 		SYNCHRONIZED;
    510 
    511 		pipe_depth_stencil_alpha_state state;
    512 		memset(&state, 0, sizeof(state));
    513 
    514 		state.depth.enabled = !!depth_stencil_state_desc->DepthEnable;
    515 		if(depth_stencil_state_desc->DepthEnable)
    516 		{
    517 			if(depth_stencil_state_desc->DepthFunc == 0 ||
    518 			   depth_stencil_state_desc->DepthFunc >= 9)
    519 				return E_INVALIDARG;
    520 			state.depth.writemask = depth_stencil_state_desc->DepthWriteMask;
    521 			state.depth.func = depth_stencil_state_desc->DepthFunc - 1;
    522 		}
    523 
    524 		state.stencil[0].enabled = !!depth_stencil_state_desc->StencilEnable;
    525 		if(depth_stencil_state_desc->StencilEnable)
    526 		{
    527 			if(depth_stencil_state_desc->FrontFace.StencilPassOp >= D3D11_STENCIL_OP_COUNT ||
    528 			   depth_stencil_state_desc->FrontFace.StencilFailOp >= D3D11_STENCIL_OP_COUNT ||
    529 			   depth_stencil_state_desc->FrontFace.StencilDepthFailOp >= D3D11_STENCIL_OP_COUNT ||
    530 			   depth_stencil_state_desc->BackFace.StencilPassOp >= D3D11_STENCIL_OP_COUNT ||
    531 			   depth_stencil_state_desc->BackFace.StencilFailOp >= D3D11_STENCIL_OP_COUNT ||
    532 			   depth_stencil_state_desc->BackFace.StencilDepthFailOp >= D3D11_STENCIL_OP_COUNT)
    533 				return E_INVALIDARG;
    534 			state.stencil[0].writemask = depth_stencil_state_desc->StencilWriteMask;
    535 			state.stencil[0].valuemask = depth_stencil_state_desc->StencilReadMask;
    536 			state.stencil[0].zpass_op = d3d11_to_pipe_stencil_op[depth_stencil_state_desc->FrontFace.StencilPassOp];
    537 			state.stencil[0].fail_op = d3d11_to_pipe_stencil_op[depth_stencil_state_desc->FrontFace.StencilFailOp];
    538 			state.stencil[0].zfail_op = d3d11_to_pipe_stencil_op[depth_stencil_state_desc->FrontFace.StencilDepthFailOp];
    539 			state.stencil[0].func = depth_stencil_state_desc->FrontFace.StencilFunc - 1;
    540 			state.stencil[1].enabled = !!depth_stencil_state_desc->StencilEnable;
    541 			state.stencil[1].writemask = depth_stencil_state_desc->StencilWriteMask;
    542 			state.stencil[1].valuemask = depth_stencil_state_desc->StencilReadMask;
    543 			state.stencil[1].zpass_op = d3d11_to_pipe_stencil_op[depth_stencil_state_desc->BackFace.StencilPassOp];
    544 			state.stencil[1].fail_op = d3d11_to_pipe_stencil_op[depth_stencil_state_desc->BackFace.StencilFailOp];
    545 			state.stencil[1].zfail_op = d3d11_to_pipe_stencil_op[depth_stencil_state_desc->BackFace.StencilDepthFailOp];
    546 			state.stencil[1].func = depth_stencil_state_desc->BackFace.StencilFunc - 1;
    547 		}
    548 
    549 		if(!depth_stencil_state)
    550 			return S_FALSE;
    551 
    552 		void* object = immediate_pipe->create_depth_stencil_alpha_state(immediate_pipe, &state);
    553 		if(!object)
    554 			return E_FAIL;
    555 
    556 		*depth_stencil_state = new GalliumD3D11DepthStencilState(this, object, *depth_stencil_state_desc);
    557 		return S_OK;
    558 	}
    559 
    560 	virtual HRESULT STDMETHODCALLTYPE CreateRasterizerState(
    561 		const D3D11_RASTERIZER_DESC *rasterizer_desc,
    562 		ID3D11RasterizerState **out_rasterizer_state)
    563 	{
    564 		SYNCHRONIZED;
    565 
    566 		pipe_rasterizer_state state;
    567 		memset(&state, 0, sizeof(state));
    568 		state.gl_rasterization_rules = 1; /* D3D10/11 use GL rules */
    569 		state.fill_front = state.fill_back = (rasterizer_desc->FillMode == D3D11_FILL_WIREFRAME) ? PIPE_POLYGON_MODE_LINE : PIPE_POLYGON_MODE_FILL;
    570 		if(rasterizer_desc->CullMode == D3D11_CULL_FRONT)
    571 			state.cull_face = PIPE_FACE_FRONT;
    572 		else if(rasterizer_desc->CullMode == D3D11_CULL_BACK)
    573 			state.cull_face = PIPE_FACE_BACK;
    574 		else
    575 			state.cull_face = PIPE_FACE_NONE;
    576 		state.front_ccw = !!rasterizer_desc->FrontCounterClockwise;
    577 		state.offset_tri = state.offset_line = state.offset_point = rasterizer_desc->SlopeScaledDepthBias || rasterizer_desc->DepthBias;
    578 		state.offset_scale = rasterizer_desc->SlopeScaledDepthBias;
    579 		state.offset_units = rasterizer_desc->DepthBias;
    580 		state.offset_clamp = rasterizer_desc->DepthBiasClamp;
    581 		state.depth_clip = rasterizer_desc->DepthClipEnable;
    582 		state.scissor = !!rasterizer_desc->ScissorEnable;
    583 		state.multisample = !!rasterizer_desc->MultisampleEnable;
    584 		state.line_smooth = !!rasterizer_desc->AntialiasedLineEnable;
    585 		state.flatshade_first = 1;
    586 		state.line_width = 1.0f;
    587 		state.point_size = 1.0f;
    588 
    589 		/* TODO: is this correct? */
    590 		state.point_quad_rasterization = 1;
    591 
    592 		if(!out_rasterizer_state)
    593 			return S_FALSE;
    594 
    595 		void* object = immediate_pipe->create_rasterizer_state(immediate_pipe, &state);
    596 		if(!object)
    597 			return E_FAIL;
    598 
    599 		*out_rasterizer_state = new GalliumD3D11RasterizerState(this, object, *rasterizer_desc);
    600 		return S_OK;
    601 	}
    602 
    603 	virtual HRESULT STDMETHODCALLTYPE CreateSamplerState(
    604 		const D3D11_SAMPLER_DESC *sampler_desc,
    605 		ID3D11SamplerState **out_sampler_state)
    606 	{
    607 		SYNCHRONIZED;
    608 
    609 		pipe_sampler_state state;
    610 		memset(&state, 0, sizeof(state));
    611 		state.normalized_coords = 1;
    612 		state.min_mip_filter = (sampler_desc->Filter & 1);
    613 		state.mag_img_filter = ((sampler_desc->Filter >> 2) & 1);
    614 		state.min_img_filter = ((sampler_desc->Filter >> 4) & 1);
    615 		if(sampler_desc->Filter & 0x40)
    616 			state.max_anisotropy = sampler_desc->MaxAnisotropy;
    617 		if(sampler_desc->Filter & 0x80)
    618 		{
    619 			state.compare_mode = PIPE_TEX_COMPARE_R_TO_TEXTURE;
    620 			state.compare_func = sampler_desc->ComparisonFunc - 1;
    621 		}
    622 		state.wrap_s = d3d11_to_pipe_wrap[sampler_desc->AddressU];
    623 		state.wrap_t = d3d11_to_pipe_wrap[sampler_desc->AddressV];
    624 		state.wrap_r = d3d11_to_pipe_wrap[sampler_desc->AddressW];
    625 		state.lod_bias = sampler_desc->MipLODBias;
    626 		memcpy(state.border_color.f, sampler_desc->BorderColor, sizeof(state.border_color));
    627 		state.min_lod = sampler_desc->MinLOD;
    628 		state.max_lod = sampler_desc->MaxLOD;
    629 
    630 		if(!out_sampler_state)
    631 			return S_FALSE;
    632 
    633 		void* object = immediate_pipe->create_sampler_state(immediate_pipe, &state);
    634 		if(!object)
    635 			return E_FAIL;
    636 
    637 		*out_sampler_state = new GalliumD3D11SamplerState(this, object, *sampler_desc);
    638 		return S_OK;
    639 	}
    640 
    641 	virtual HRESULT STDMETHODCALLTYPE CreateInputLayout(
    642 		const D3D11_INPUT_ELEMENT_DESC *input_element_descs,
    643 		unsigned count,
    644 		const void *shader_bytecode_with_input_signature,
    645 		SIZE_T bytecode_length,
    646 		ID3D11InputLayout **out_input_layout)
    647 	{
    648 		SYNCHRONIZED;
    649 
    650 		if(count > D3D11_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT)
    651 			return E_INVALIDARG;
    652 		assert(D3D11_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT <= PIPE_MAX_ATTRIBS);
    653 
    654 		// putting semantics matching in the core API seems to be a (minor) design mistake
    655 
    656 		struct dxbc_chunk_signature* sig = dxbc_find_signature(shader_bytecode_with_input_signature, bytecode_length, DXBC_FIND_INPUT_SIGNATURE);
    657 		D3D11_SIGNATURE_PARAMETER_DESC* params;
    658 		unsigned num_params = dxbc_parse_signature(sig, &params);
    659 
    660 		typedef std::unordered_map<std::pair<c_string, unsigned>, unsigned> semantic_to_idx_map_t;
    661 		semantic_to_idx_map_t semantic_to_idx_map;
    662 		for(unsigned i = 0; i < count; ++i)
    663 			semantic_to_idx_map[std::make_pair(c_string(input_element_descs[i].SemanticName), input_element_descs[i].SemanticIndex)] = i;
    664 
    665 		struct pipe_vertex_element elements[D3D11_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT];
    666 
    667 		enum pipe_format formats[D3D11_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT];
    668 		unsigned offsets[D3D11_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT];
    669 
    670 		offsets[0] = 0;
    671 		for(unsigned i = 0; i < count; ++i)
    672 		{
    673 			formats[i] = dxgi_to_pipe_format[input_element_descs[i].Format];
    674 
    675 			if(likely(input_element_descs[i].AlignedByteOffset != D3D11_APPEND_ALIGNED_ELEMENT))
    676 			{
    677 				offsets[i] = input_element_descs[i].AlignedByteOffset;
    678 			}
    679 			else if(i > 0)
    680 			{
    681 				unsigned align_mask = util_format_description(formats[i])->channel[0].size;
    682 				if(align_mask & 7) // e.g. R10G10B10A2
    683 					align_mask = 32;
    684 				align_mask = (align_mask / 8) - 1;
    685 
    686 				offsets[i] = (offsets[i - 1] + util_format_get_blocksize(formats[i - 1]) + align_mask) & ~align_mask;
    687 			}
    688 		}
    689 
    690 		// TODO: check for & report errors (e.g. ambiguous layouts, unmatched semantics)
    691 
    692 		unsigned num_params_to_use = 0;
    693 		for(unsigned i = 0; i < num_params && num_params_to_use < D3D11_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT; ++i)
    694 		{
    695 			if(!strcasecmp(params[i].SemanticName, "SV_INSTANCEID") ||
    696 			   !strcasecmp(params[i].SemanticName, "SV_VERTEXID"))
    697 				continue;
    698 			const unsigned n = num_params_to_use++;
    699 
    700 			semantic_to_idx_map_t::iterator iter = semantic_to_idx_map.find(std::make_pair(c_string(params[i].SemanticName), params[i].SemanticIndex));
    701 
    702 			if(iter != semantic_to_idx_map.end())
    703 			{
    704 				unsigned idx = iter->second;
    705 
    706 				elements[n].src_format = formats[idx];
    707 				elements[n].src_offset = offsets[idx];
    708 				elements[n].vertex_buffer_index = input_element_descs[idx].InputSlot;
    709 				elements[n].instance_divisor = input_element_descs[idx].InstanceDataStepRate;
    710 				if (input_element_descs[idx].InputSlotClass == D3D11_INPUT_PER_INSTANCE_DATA)
    711 					if (elements[n].instance_divisor == 0)
    712 						elements[n].instance_divisor = ~0; // XXX: can't specify 'never' to gallium
    713 			}
    714 			else
    715 			{
    716 				// XXX: undefined input, is this valid or should we return an error ?
    717 				elements[n].src_format = PIPE_FORMAT_NONE;
    718 				elements[n].src_offset = 0;
    719 				elements[n].vertex_buffer_index = 0;
    720 				elements[n].instance_divisor = 0;
    721 			}
    722 		}
    723 
    724 		free(params);
    725 
    726 		if(!out_input_layout)
    727 			return S_FALSE;
    728 
    729 		void* object = immediate_pipe->create_vertex_elements_state(immediate_pipe, num_params_to_use, elements);
    730 		if(!object)
    731 			return E_FAIL;
    732 
    733 		*out_input_layout = new GalliumD3D11InputLayout(this, object);
    734 		return S_OK;
    735 	}
    736 
    737 	static unsigned d3d11_to_pipe_bind_flags(unsigned bind_flags)
    738 	{
    739 		unsigned bind = 0;
    740 		if(bind_flags & D3D11_BIND_VERTEX_BUFFER)
    741 			bind |= PIPE_BIND_VERTEX_BUFFER;
    742 		if(bind_flags & D3D11_BIND_INDEX_BUFFER)
    743 			bind |= PIPE_BIND_INDEX_BUFFER;
    744 		if(bind_flags & D3D11_BIND_CONSTANT_BUFFER)
    745 			bind |= PIPE_BIND_CONSTANT_BUFFER;
    746 		if(bind_flags & D3D11_BIND_SHADER_RESOURCE)
    747 			bind |= PIPE_BIND_SAMPLER_VIEW;
    748 		if(bind_flags & D3D11_BIND_STREAM_OUTPUT)
    749 			bind |= PIPE_BIND_STREAM_OUTPUT;
    750 		if(bind_flags & D3D11_BIND_RENDER_TARGET)
    751 			bind |= PIPE_BIND_RENDER_TARGET;
    752 		if(bind_flags & D3D11_BIND_DEPTH_STENCIL)
    753 			bind |= PIPE_BIND_DEPTH_STENCIL;
    754 		return bind;
    755 	}
    756 
    757 	inline HRESULT create_resource(
    758 		pipe_texture_target target,
    759 		unsigned width,
    760 		unsigned height,
    761 		unsigned depth,
    762 		unsigned mip_levels,
    763 		unsigned array_size,
    764 		DXGI_FORMAT format,
    765 		const DXGI_SAMPLE_DESC* SampleDesc,
    766 		D3D11_USAGE usage,
    767 		unsigned bind_flags,
    768 		unsigned c_p_u_access_flags,
    769 		unsigned misc_flags,
    770 		const D3D11_SUBRESOURCE_DATA *initial_data,
    771 		DXGI_USAGE dxgi_usage,
    772 		struct pipe_resource** ppresource
    773 	)
    774 	{
    775 		if(invalid(format >= DXGI_FORMAT_COUNT))
    776 			return E_INVALIDARG;
    777 		if(misc_flags & D3D11_RESOURCE_MISC_TEXTURECUBE)
    778 		{
    779 			if(target != PIPE_TEXTURE_2D)
    780 				return E_INVALIDARG;
    781 			target = PIPE_TEXTURE_CUBE;
    782 			if(array_size % 6)
    783 				return E_INVALIDARG;
    784 		}
    785 		else if(array_size > 1)
    786 		{
    787 			switch (target) {
    788 			case PIPE_TEXTURE_1D: target = PIPE_TEXTURE_1D_ARRAY; break;
    789 			case PIPE_TEXTURE_2D: target = PIPE_TEXTURE_2D_ARRAY; break;
    790 			default:
    791 				return E_INVALIDARG;
    792 			}
    793 		}
    794 		/* TODO: msaa */
    795 		struct pipe_resource templat;
    796 		memset(&templat, 0, sizeof(templat));
    797 		templat.target = target;
    798 		templat.width0 = width;
    799 		templat.height0 = height;
    800 		templat.depth0 = depth;
    801 		templat.array_size = array_size;
    802 		if(mip_levels)
    803 			templat.last_level = mip_levels - 1;
    804 		else
    805 			templat.last_level = MAX2(MAX2(util_logbase2(templat.width0), util_logbase2(templat.height0)), util_logbase2(templat.depth0));
    806 		templat.format = dxgi_to_pipe_format[format];
    807 		if(bind_flags & D3D11_BIND_DEPTH_STENCIL) {
    808 			// colour formats are not depth-renderable, but depth/stencil-formats may be colour-renderable
    809 			switch(format)
    810 			{
    811 			case DXGI_FORMAT_R32_TYPELESS: templat.format = PIPE_FORMAT_Z32_FLOAT; break;
    812 			case DXGI_FORMAT_R16_TYPELESS: templat.format = PIPE_FORMAT_Z16_UNORM; break;
    813 			default:
    814 				break;
    815 			}
    816 		}
    817 		templat.bind = d3d11_to_pipe_bind_flags(bind_flags);
    818 		if(c_p_u_access_flags & D3D11_CPU_ACCESS_READ)
    819 			templat.bind |= PIPE_BIND_TRANSFER_READ;
    820 		if(c_p_u_access_flags & D3D11_CPU_ACCESS_WRITE)
    821 			templat.bind |= PIPE_BIND_TRANSFER_WRITE;
    822 		if(misc_flags & D3D11_RESOURCE_MISC_SHARED)
    823 			templat.bind |= PIPE_BIND_SHARED;
    824 		if(misc_flags & D3D11_RESOURCE_MISC_GDI_COMPATIBLE)
    825 			templat.bind |= PIPE_BIND_TRANSFER_READ | PIPE_BIND_TRANSFER_WRITE;
    826 		if(dxgi_usage & DXGI_USAGE_BACK_BUFFER)
    827 			templat.bind |= PIPE_BIND_DISPLAY_TARGET;
    828 		templat.usage = d3d11_to_pipe_usage[usage];
    829 		if(invalid(!templat.format))
    830 			return E_NOTIMPL;
    831 
    832 		if(!ppresource)
    833 			return S_FALSE;
    834 
    835 		struct pipe_resource* resource = screen->resource_create(screen, &templat);
    836 		if(!resource)
    837 			return E_FAIL;
    838 		if(initial_data)
    839 		{
    840 			for(unsigned slice = 0; slice < array_size; ++slice)
    841 			{
    842 				for(unsigned level = 0; level <= templat.last_level; ++level)
    843 				{
    844 					struct pipe_box box;
    845 					box.x = box.y = 0;
    846 					box.z = slice;
    847 					box.width = u_minify(width, level);
    848 					box.height = u_minify(height, level);
    849 					box.depth = u_minify(depth, level);
    850 					immediate_pipe->transfer_inline_write(immediate_pipe, resource, level, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD | PIPE_TRANSFER_UNSYNCHRONIZED, &box, initial_data->pSysMem, initial_data->SysMemPitch, initial_data->SysMemSlicePitch);
    851 					++initial_data;
    852 				}
    853 			}
    854 		}
    855 		*ppresource = resource;
    856 		return S_OK;
    857 	}
    858 
    859 	static unsigned d3d_to_dxgi_usage(unsigned bind, unsigned misc)
    860 	{
    861 		unsigned dxgi_usage = 0;
    862 		if(bind |= D3D11_BIND_RENDER_TARGET)
    863 			dxgi_usage |= DXGI_USAGE_RENDER_TARGET_OUTPUT;
    864 		if(bind & D3D11_BIND_SHADER_RESOURCE)
    865 			dxgi_usage |= DXGI_USAGE_SHADER_INPUT;
    866 #if API >= 11
    867 		if(bind & D3D11_BIND_UNORDERED_ACCESS)
    868 			dxgi_usage |= DXGI_USAGE_UNORDERED_ACCESS;
    869 #endif
    870 		if(misc & D3D11_RESOURCE_MISC_SHARED)
    871 			dxgi_usage |= DXGI_USAGE_SHARED;
    872 		return dxgi_usage;
    873 	}
    874 
    875 	virtual HRESULT STDMETHODCALLTYPE CreateTexture1D(
    876 		const D3D11_TEXTURE1D_DESC *desc,
    877 		const D3D11_SUBRESOURCE_DATA *initial_data,
    878 		ID3D11Texture1D **out_texture1d)
    879 	{
    880 		SYNCHRONIZED;
    881 
    882 		struct pipe_resource* resource;
    883 		DXGI_USAGE dxgi_usage = d3d_to_dxgi_usage(desc->BindFlags, desc->MiscFlags);
    884 		HRESULT hr = create_resource(PIPE_TEXTURE_1D, desc->Width, 1, 1, desc->MipLevels, desc->ArraySize, desc->Format, 0, desc->Usage, desc->BindFlags, desc->CPUAccessFlags, desc->MiscFlags, initial_data, dxgi_usage, out_texture1d ? &resource : 0);
    885 		if(hr != S_OK)
    886 			return hr;
    887 		D3D11_TEXTURE1D_DESC cdesc = *desc;
    888 		cdesc.MipLevels = resource->last_level + 1;
    889 		*out_texture1d = new GalliumD3D11Texture1D(this, resource, cdesc, dxgi_usage);
    890 		return S_OK;
    891 	}
    892 
    893 	virtual HRESULT STDMETHODCALLTYPE CreateTexture2D(
    894 		const D3D11_TEXTURE2D_DESC *desc,
    895 		const D3D11_SUBRESOURCE_DATA *initial_data,
    896 		ID3D11Texture2D **out_texture2d)
    897 	{
    898 		SYNCHRONIZED;
    899 
    900 		struct pipe_resource* resource;
    901 		DXGI_USAGE dxgi_usage = d3d_to_dxgi_usage(desc->BindFlags, desc->MiscFlags);
    902 		HRESULT hr = create_resource(PIPE_TEXTURE_2D, desc->Width, desc->Height, 1, desc->MipLevels, desc->ArraySize, desc->Format, &desc->SampleDesc, desc->Usage, desc->BindFlags, desc->CPUAccessFlags, desc->MiscFlags, initial_data, dxgi_usage, out_texture2d ? &resource : 0);
    903 		if(hr != S_OK)
    904 			return hr;
    905 		D3D11_TEXTURE2D_DESC cdesc = *desc;
    906 		cdesc.MipLevels = resource->last_level + 1;
    907 		if(cdesc.MipLevels == 1 && cdesc.ArraySize == 1)
    908 			*out_texture2d = new GalliumD3D11Surface(this, resource, cdesc, dxgi_usage);
    909 		else
    910 			*out_texture2d = new GalliumD3D11Texture2D(this, resource, cdesc, dxgi_usage);
    911 		return S_OK;
    912 	}
    913 
    914 	virtual HRESULT STDMETHODCALLTYPE CreateTexture3D(
    915 		const D3D11_TEXTURE3D_DESC *desc,
    916 		const D3D11_SUBRESOURCE_DATA *initial_data,
    917 		ID3D11Texture3D **out_texture3d)
    918 	{
    919 		SYNCHRONIZED;
    920 
    921 		struct pipe_resource* resource;
    922 		DXGI_USAGE dxgi_usage = d3d_to_dxgi_usage(desc->BindFlags, desc->MiscFlags);
    923 		HRESULT hr = create_resource(PIPE_TEXTURE_3D, desc->Width, desc->Height, desc->Depth, desc->MipLevels, 1, desc->Format, 0, desc->Usage, desc->BindFlags, desc->CPUAccessFlags, desc->MiscFlags, initial_data, dxgi_usage, out_texture3d ? &resource : 0);
    924 		if(hr != S_OK)
    925 			return hr;
    926 		D3D11_TEXTURE3D_DESC cdesc = *desc;
    927 		cdesc.MipLevels = resource->last_level + 1;
    928 		*out_texture3d = new GalliumD3D11Texture3D(this, resource, cdesc, dxgi_usage);
    929 		return S_OK;
    930 	}
    931 
    932 	virtual HRESULT STDMETHODCALLTYPE CreateBuffer(
    933 		const D3D11_BUFFER_DESC *desc,
    934 		const D3D11_SUBRESOURCE_DATA *initial_data,
    935 		ID3D11Buffer **out_buffer)
    936 	{
    937 		SYNCHRONIZED;
    938 
    939 		struct pipe_resource* resource;
    940 		DXGI_USAGE dxgi_usage = d3d_to_dxgi_usage(desc->BindFlags, desc->MiscFlags);
    941 		HRESULT hr = create_resource(PIPE_BUFFER, desc->ByteWidth, 1, 1, 1, 1, DXGI_FORMAT_R8_UNORM, 0, desc->Usage, desc->BindFlags, desc->CPUAccessFlags, desc->MiscFlags, initial_data, dxgi_usage, out_buffer ? &resource : 0);
    942 		if(hr != S_OK)
    943 			return hr;
    944 		*out_buffer = new GalliumD3D11Buffer(this, resource, *desc, dxgi_usage);
    945 		return S_OK;
    946 	}
    947 
    948 	virtual HRESULT STDMETHODCALLTYPE OpenGalliumResource(
    949 		struct pipe_resource* resource,
    950 		IUnknown** dxgi_resource)
    951 	{
    952 		SYNCHRONIZED;
    953 
    954 		/* TODO: maybe support others */
    955 		assert(resource->target == PIPE_TEXTURE_2D);
    956 		*dxgi_resource = 0;
    957 		D3D11_TEXTURE2D_DESC desc;
    958 		memset(&desc, 0, sizeof(desc));
    959 		desc.Width = resource->width0;
    960 		desc.Height = resource->height0;
    961 		init_pipe_to_dxgi_format();
    962 		desc.Format = pipe_to_dxgi_format[resource->format];
    963 		desc.SampleDesc.Count = resource->nr_samples;
    964 		desc.SampleDesc.Quality = 0;
    965 		desc.ArraySize = 1;
    966 		desc.MipLevels = resource->last_level + 1;
    967 		desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
    968 		if(resource->bind & PIPE_BIND_RENDER_TARGET)
    969 			desc.BindFlags |= D3D11_BIND_RENDER_TARGET;
    970 		if(resource->bind & PIPE_BIND_DEPTH_STENCIL)
    971 			desc.BindFlags |= D3D11_BIND_DEPTH_STENCIL;
    972 		if(resource->bind & PIPE_BIND_SAMPLER_VIEW)
    973 			desc.BindFlags |= D3D11_BIND_SHADER_RESOURCE;
    974 		if(resource->bind & PIPE_BIND_SHARED)
    975 			desc.MiscFlags |= D3D11_RESOURCE_MISC_SHARED;
    976 		DXGI_USAGE dxgi_usage = d3d_to_dxgi_usage(desc.BindFlags, desc.MiscFlags);
    977 		if(desc.MipLevels == 1 && desc.ArraySize == 1)
    978 			*dxgi_resource = (ID3D11Texture2D*)new GalliumD3D11Surface(this, resource, desc, dxgi_usage);
    979 		else
    980 			*dxgi_resource = (ID3D11Texture2D*)new GalliumD3D11Texture2D(this, resource, desc, dxgi_usage);
    981 		return S_OK;
    982 	}
    983 
    984 	virtual HRESULT STDMETHODCALLTYPE CreateSurface(
    985 		const DXGI_SURFACE_DESC *dxgi_desc,
    986 		unsigned count,
    987 		DXGI_USAGE usage,
    988 		const DXGI_SHARED_RESOURCE *shared_resource,
    989 		IDXGISurface **out_surface)
    990 	{
    991 		SYNCHRONIZED;
    992 
    993 		D3D11_TEXTURE2D_DESC desc;
    994 		memset(&desc, 0, sizeof(desc));
    995 
    996 		struct pipe_resource* resource;
    997 		desc.Width = dxgi_desc->Width;
    998 		desc.Height = dxgi_desc->Height;
    999 		desc.Format = dxgi_desc->Format;
   1000 		desc.SampleDesc = dxgi_desc->SampleDesc;
   1001 		desc.ArraySize = count;
   1002 		desc.MipLevels = 1;
   1003 		desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
   1004 		if(usage & DXGI_USAGE_RENDER_TARGET_OUTPUT)
   1005 			desc.BindFlags |= D3D11_BIND_RENDER_TARGET;
   1006 		if(usage & DXGI_USAGE_SHADER_INPUT)
   1007 			desc.BindFlags |= D3D11_BIND_SHADER_RESOURCE;
   1008 #if API >= 11
   1009 		if(usage & DXGI_USAGE_UNORDERED_ACCESS)
   1010 			desc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS;
   1011 #endif
   1012 		if(usage & DXGI_USAGE_SHARED)
   1013 			desc.MiscFlags |= D3D11_RESOURCE_MISC_SHARED;
   1014 		HRESULT hr = create_resource(PIPE_TEXTURE_2D, dxgi_desc->Width, dxgi_desc->Height, 1, 1, count, dxgi_desc->Format, &dxgi_desc->SampleDesc, D3D11_USAGE_DEFAULT, desc.BindFlags, D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE, desc.MiscFlags, 0, usage, &resource);
   1015 		if(hr != S_OK)
   1016 			return hr;
   1017 		*out_surface = new GalliumD3D11Surface(this, resource, desc, usage);
   1018 		return S_OK;
   1019 	}
   1020 
   1021 	virtual HRESULT STDMETHODCALLTYPE CreateShaderResourceView(
   1022 		ID3D11Resource *iresource,
   1023 		const D3D11_SHADER_RESOURCE_VIEW_DESC *desc,
   1024 		ID3D11ShaderResourceView **out_srv)
   1025 	{
   1026 #if API >= 11
   1027 		D3D11_SHADER_RESOURCE_VIEW_DESC def_desc;
   1028 #else
   1029 		if(desc->ViewDimension == D3D10_1_SRV_DIMENSION_TEXTURECUBEARRAY)
   1030 			return E_INVALIDARG;
   1031 		D3D10_SHADER_RESOURCE_VIEW_DESC1 desc1;
   1032 		memset(&desc1, 0, sizeof(desc1));
   1033 		memcpy(&desc1, desc, sizeof(*desc));
   1034 		return CreateShaderResourceView1(iresource, &desc1, (ID3D10ShaderResourceView1**)out_srv);
   1035 	}
   1036 
   1037 	virtual HRESULT STDMETHODCALLTYPE CreateShaderResourceView1(
   1038 			ID3D11Resource *iresource,
   1039 			const D3D10_SHADER_RESOURCE_VIEW_DESC1 *desc,
   1040 			ID3D10ShaderResourceView1 **out_srv)
   1041 	{
   1042 		D3D10_SHADER_RESOURCE_VIEW_DESC1 def_desc;
   1043 #endif
   1044 		SYNCHRONIZED;
   1045 
   1046 		const struct pipe_resource* resource = ((GalliumD3D11Resource<>*)iresource)->resource;
   1047 
   1048 		if(!desc)
   1049 		{
   1050 			init_pipe_to_dxgi_format();
   1051 			memset(&def_desc, 0, sizeof(def_desc));
   1052 			def_desc.Format = pipe_to_dxgi_format[resource->format];
   1053 			switch(resource->target)
   1054 			{
   1055 			case PIPE_BUFFER:
   1056 				def_desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
   1057 				def_desc.Buffer.ElementWidth = resource->width0;
   1058 				break;
   1059 			case PIPE_TEXTURE_1D:
   1060 				def_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D;
   1061 				def_desc.Texture1D.MipLevels = resource->last_level + 1;
   1062 				break;
   1063 			case PIPE_TEXTURE_1D_ARRAY:
   1064 				def_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1DARRAY;
   1065 				def_desc.Texture1DArray.MipLevels = resource->last_level + 1;
   1066 				def_desc.Texture1DArray.ArraySize = resource->array_size;
   1067 				break;
   1068 			case PIPE_TEXTURE_2D:
   1069 			case PIPE_TEXTURE_RECT:
   1070 				def_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
   1071 				def_desc.Texture2D.MipLevels = resource->last_level + 1;
   1072 				break;
   1073 			case PIPE_TEXTURE_2D_ARRAY:
   1074 				def_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
   1075 				def_desc.Texture2DArray.MipLevels = resource->last_level + 1;
   1076 				def_desc.Texture2DArray.ArraySize = resource->array_size;
   1077 				break;
   1078 			case PIPE_TEXTURE_3D:
   1079 				def_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
   1080 				def_desc.Texture3D.MipLevels = resource->last_level + 1;
   1081 				break;
   1082 			case PIPE_TEXTURE_CUBE:
   1083 				if(resource->array_size > 6)
   1084 				{
   1085 					def_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY;
   1086 					def_desc.TextureCubeArray.NumCubes = resource->array_size / 6;
   1087 				}
   1088 				else
   1089 				{
   1090 					def_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
   1091 				}
   1092 				def_desc.TextureCube.MipLevels = resource->last_level + 1;
   1093 				break;
   1094 			default:
   1095 				return E_INVALIDARG;
   1096 			}
   1097 			desc = &def_desc;
   1098 		}
   1099 
   1100 		struct pipe_sampler_view templat;
   1101 		memset(&templat, 0, sizeof(templat));
   1102 		if(invalid(format >= DXGI_FORMAT_COUNT))
   1103 			return E_INVALIDARG;
   1104 		templat.format = (desc->Format == DXGI_FORMAT_UNKNOWN) ? resource->format : dxgi_to_pipe_format[desc->Format];
   1105 		if(!templat.format)
   1106 			return E_NOTIMPL;
   1107 		templat.swizzle_r = PIPE_SWIZZLE_RED;
   1108 		templat.swizzle_g = PIPE_SWIZZLE_GREEN;
   1109 		templat.swizzle_b = PIPE_SWIZZLE_BLUE;
   1110 		templat.swizzle_a = PIPE_SWIZZLE_ALPHA;
   1111 
   1112 		templat.texture = ((GalliumD3D11Resource<>*)iresource)->resource;
   1113 		switch(desc->ViewDimension)
   1114 		{
   1115 		case D3D11_SRV_DIMENSION_TEXTURE1DARRAY:
   1116 		case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
   1117 		case D3D11_SRV_DIMENSION_TEXTURECUBEARRAY:
   1118 			templat.u.tex.first_layer = desc->Texture1DArray.FirstArraySlice;
   1119 			templat.u.tex.last_layer = desc->Texture1DArray.FirstArraySlice + desc->Texture1DArray.ArraySize - 1;
   1120 			if (desc->ViewDimension == D3D11_SRV_DIMENSION_TEXTURECUBEARRAY) {
   1121 				templat.u.tex.first_layer *= 6;
   1122 				templat.u.tex.last_layer *= 6;
   1123 			}
   1124 			// fall through
   1125 		case D3D11_SRV_DIMENSION_TEXTURE1D:
   1126 		case D3D11_SRV_DIMENSION_TEXTURE2D:
   1127 		case D3D11_SRV_DIMENSION_TEXTURE3D:
   1128 		case D3D11_SRV_DIMENSION_TEXTURECUBE:
   1129 			// yes, this works for all of these types
   1130 			templat.u.tex.first_level = desc->Texture1D.MostDetailedMip;
   1131 			if(desc->Texture1D.MipLevels == (unsigned)-1)
   1132 				templat.u.tex.last_level = templat.texture->last_level;
   1133 			else
   1134 				templat.u.tex.last_level = templat.u.tex.first_level + desc->Texture1D.MipLevels - 1;
   1135 			assert(templat.u.tex.last_level >= templat.u.tex.first_level);
   1136 			break;
   1137 		case D3D11_SRV_DIMENSION_BUFFER:
   1138 			templat.u.buf.first_element = desc->Buffer.ElementOffset;
   1139 			templat.u.buf.last_element = desc->Buffer.ElementOffset + desc->Buffer.ElementWidth - 1;
   1140 			break;
   1141 		case D3D11_SRV_DIMENSION_TEXTURE2DMS:
   1142 		case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY:
   1143 			return E_NOTIMPL;
   1144 		default:
   1145 			return E_INVALIDARG;
   1146 		}
   1147 
   1148 		if(!out_srv)
   1149 			return S_FALSE;
   1150 
   1151 		struct pipe_sampler_view* view = immediate_pipe->create_sampler_view(immediate_pipe, templat.texture, &templat);
   1152 		if(!view)
   1153 			return E_FAIL;
   1154 		*out_srv = new GalliumD3D11ShaderResourceView(this, (GalliumD3D11Resource<>*)iresource, view, *desc);
   1155 		return S_OK;
   1156 	}
   1157 
   1158 #if API >= 11
   1159 	virtual HRESULT STDMETHODCALLTYPE CreateUnorderedAccessView(
   1160 		ID3D11Resource *resource,
   1161 		const D3D11_UNORDERED_ACCESS_VIEW_DESC *desc,
   1162 		ID3D11UnorderedAccessView **out_uav)
   1163 	{
   1164 		SYNCHRONIZED;
   1165 
   1166 		return E_NOTIMPL;
   1167 
   1168 		// remember to return S_FALSE and not crash if out_u_a_view == 0 and parameters are valid
   1169 	}
   1170 #endif
   1171 
   1172 	virtual HRESULT STDMETHODCALLTYPE CreateRenderTargetView(
   1173 		ID3D11Resource *iresource,
   1174 		const D3D11_RENDER_TARGET_VIEW_DESC *desc,
   1175 		ID3D11RenderTargetView **out_rtv)
   1176 	{
   1177 		SYNCHRONIZED;
   1178 
   1179 		const struct pipe_resource* resource = ((GalliumD3D11Resource<>*)iresource)->resource;
   1180 
   1181 		D3D11_RENDER_TARGET_VIEW_DESC def_desc;
   1182 		if(!desc)
   1183 		{
   1184 			init_pipe_to_dxgi_format();
   1185 			memset(&def_desc, 0, sizeof(def_desc));
   1186 			def_desc.Format = pipe_to_dxgi_format[resource->format];
   1187 			switch(resource->target)
   1188 			{
   1189 			case PIPE_BUFFER:
   1190 				def_desc.ViewDimension = D3D11_RTV_DIMENSION_BUFFER;
   1191 				def_desc.Buffer.ElementWidth = resource->width0;
   1192 				break;
   1193 			case PIPE_TEXTURE_1D:
   1194 				def_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1D;
   1195 				break;
   1196 			case PIPE_TEXTURE_1D_ARRAY:
   1197 				def_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1DARRAY;
   1198 				def_desc.Texture1DArray.ArraySize = resource->array_size;
   1199 				break;
   1200 			case PIPE_TEXTURE_2D:
   1201 			case PIPE_TEXTURE_RECT:
   1202 				def_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
   1203 				break;
   1204 			case PIPE_TEXTURE_2D_ARRAY:
   1205 				def_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
   1206 				def_desc.Texture2DArray.ArraySize = resource->array_size;
   1207 				break;
   1208 			case PIPE_TEXTURE_3D:
   1209 				def_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
   1210 				def_desc.Texture3D.WSize = resource->depth0;
   1211 				break;
   1212 			case PIPE_TEXTURE_CUBE:
   1213 				def_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
   1214 				def_desc.Texture2DArray.ArraySize = 6;
   1215 				break;
   1216 			default:
   1217 				return E_INVALIDARG;
   1218 			}
   1219 			desc = &def_desc;
   1220 		}
   1221 
   1222 		struct pipe_surface templat;
   1223 		memset(&templat, 0, sizeof(templat));
   1224 		if(invalid(desc->format >= DXGI_FORMAT_COUNT))
   1225 			return E_INVALIDARG;
   1226 		templat.format = (desc->Format == DXGI_FORMAT_UNKNOWN) ? resource->format : dxgi_to_pipe_format[desc->Format];
   1227 		if(!templat.format)
   1228 			return E_NOTIMPL;
   1229 		templat.usage = PIPE_BIND_RENDER_TARGET;
   1230 		templat.texture = ((GalliumD3D11Resource<>*)iresource)->resource;
   1231 
   1232 		switch(desc->ViewDimension)
   1233 		{
   1234 		case D3D11_RTV_DIMENSION_TEXTURE1D:
   1235 		case D3D11_RTV_DIMENSION_TEXTURE2D:
   1236 			templat.u.tex.level = desc->Texture1D.MipSlice;
   1237 			break;
   1238 		case D3D11_RTV_DIMENSION_TEXTURE3D:
   1239 			templat.u.tex.level = desc->Texture3D.MipSlice;
   1240 			templat.u.tex.first_layer = desc->Texture3D.FirstWSlice;
   1241 			templat.u.tex.last_layer = desc->Texture3D.FirstWSlice + desc->Texture3D.WSize - 1;
   1242 			break;
   1243 		case D3D11_RTV_DIMENSION_TEXTURE1DARRAY:
   1244 		case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:
   1245 			templat.u.tex.level = desc->Texture1DArray.MipSlice;
   1246 			templat.u.tex.first_layer = desc->Texture1DArray.FirstArraySlice;
   1247 			templat.u.tex.last_layer = desc->Texture1DArray.FirstArraySlice + desc->Texture1DArray.ArraySize - 1;
   1248 			break;
   1249 		case D3D11_RTV_DIMENSION_BUFFER:
   1250 			templat.u.buf.first_element = desc->Buffer.ElementOffset;
   1251 			templat.u.buf.last_element = desc->Buffer.ElementOffset + desc->Buffer.ElementWidth - 1;
   1252 			break;
   1253 		case D3D11_RTV_DIMENSION_TEXTURE2DMS:
   1254 		case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY:
   1255 			return E_NOTIMPL;
   1256 		default:
   1257 			return E_INVALIDARG;
   1258 		}
   1259 
   1260 		if(!out_rtv)
   1261 			return S_FALSE;
   1262 
   1263 		struct pipe_surface* surface = immediate_pipe->create_surface(immediate_pipe, templat.texture, &templat);
   1264 		if(!surface)
   1265 			return E_FAIL;
   1266 		*out_rtv = new GalliumD3D11RenderTargetView(this, (GalliumD3D11Resource<>*)iresource, surface, *desc);
   1267 		return S_OK;
   1268 	}
   1269 
   1270 	virtual HRESULT STDMETHODCALLTYPE CreateDepthStencilView(
   1271 		ID3D11Resource *iresource,
   1272 		const D3D11_DEPTH_STENCIL_VIEW_DESC *desc,
   1273 		ID3D11DepthStencilView **out_depth_stencil_view)
   1274 	{
   1275 		SYNCHRONIZED;
   1276 
   1277 		const struct pipe_resource* resource = ((GalliumD3D11Resource<>*)iresource)->resource;
   1278 
   1279 		D3D11_DEPTH_STENCIL_VIEW_DESC def_desc;
   1280 		if(!desc)
   1281 		{
   1282 			init_pipe_to_dxgi_format();
   1283 			memset(&def_desc, 0, sizeof(def_desc));
   1284 			def_desc.Format = pipe_to_dxgi_format[resource->format];
   1285 			switch(resource->target)
   1286 			{
   1287 			case PIPE_TEXTURE_1D:
   1288 				def_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1D;
   1289 				break;
   1290 			case PIPE_TEXTURE_1D_ARRAY:
   1291 				def_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1DARRAY;
   1292 				def_desc.Texture1DArray.ArraySize = resource->array_size;
   1293 				break;
   1294 			case PIPE_TEXTURE_2D:
   1295 			case PIPE_TEXTURE_RECT:
   1296 				def_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
   1297 				break;
   1298 			case PIPE_TEXTURE_2D_ARRAY:
   1299 				def_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
   1300 				def_desc.Texture2DArray.ArraySize = resource->array_size;
   1301 				break;
   1302 			case PIPE_TEXTURE_CUBE:
   1303 				def_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
   1304 				def_desc.Texture2DArray.ArraySize = 6;
   1305 				break;
   1306 			default:
   1307 				return E_INVALIDARG;
   1308 			}
   1309 			desc = &def_desc;
   1310 		}
   1311 
   1312 		struct pipe_surface templat;
   1313 		memset(&templat, 0, sizeof(templat));
   1314 		if(invalid(desc->format >= DXGI_FORMAT_COUNT))
   1315 			return E_INVALIDARG;
   1316 		templat.format = (desc->Format == DXGI_FORMAT_UNKNOWN) ? resource->format : dxgi_to_pipe_format[desc->Format];
   1317 		if(!templat.format)
   1318 			return E_NOTIMPL;
   1319 		templat.usage = PIPE_BIND_DEPTH_STENCIL;
   1320 		templat.texture = ((GalliumD3D11Resource<>*)iresource)->resource;
   1321 
   1322 		switch(desc->ViewDimension)
   1323 		{
   1324 		case D3D11_DSV_DIMENSION_TEXTURE1D:
   1325 		case D3D11_DSV_DIMENSION_TEXTURE2D:
   1326 			templat.u.tex.level = desc->Texture1D.MipSlice;
   1327 			break;
   1328 		case D3D11_DSV_DIMENSION_TEXTURE1DARRAY:
   1329 		case D3D11_DSV_DIMENSION_TEXTURE2DARRAY:
   1330 			templat.u.tex.level = desc->Texture1DArray.MipSlice;
   1331 			templat.u.tex.first_layer = desc->Texture1DArray.FirstArraySlice;
   1332 			templat.u.tex.last_layer = desc->Texture1DArray.FirstArraySlice + desc->Texture1DArray.ArraySize - 1;
   1333 			break;
   1334 		case D3D11_DSV_DIMENSION_TEXTURE2DMS:
   1335 		case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY:
   1336 			return E_NOTIMPL;
   1337 		default:
   1338 			return E_INVALIDARG;
   1339 		}
   1340 
   1341 		if(!out_depth_stencil_view)
   1342 			return S_FALSE;
   1343 
   1344 		struct pipe_surface* surface = immediate_pipe->create_surface(immediate_pipe, templat.texture, &templat);
   1345 		if(!surface)
   1346 			return E_FAIL;
   1347 		*out_depth_stencil_view = new GalliumD3D11DepthStencilView(this, (GalliumD3D11Resource<>*)iresource, surface, *desc);
   1348 		return S_OK;
   1349 	}
   1350 
   1351 #define D3D1X_SHVER_GEOMETRY_SHADER 2 /* D3D11_SHVER_GEOMETRY_SHADER */
   1352 
   1353 	GalliumD3D11Shader<>* create_stage_shader(unsigned type, const void* shader_bytecode, SIZE_T bytecode_length
   1354 #if API >= 11
   1355 			, ID3D11ClassLinkage *class_linkage
   1356 #endif
   1357 			, struct pipe_stream_output_info* so_info)
   1358 	{
   1359 		bool dump = debug_get_option_dump_shaders();
   1360 
   1361 		std::auto_ptr<sm4_program> sm4(0);
   1362 
   1363 		dxbc_chunk_header* sm4_chunk = dxbc_find_shader_bytecode(shader_bytecode, bytecode_length);
   1364 		if(!sm4_chunk)
   1365 		{
   1366 			if(so_info)
   1367 				sm4.reset(new sm4_program());
   1368 		}
   1369 		else
   1370 		{
   1371 			sm4.reset(sm4_parse(sm4_chunk + 1, bswap_le32(sm4_chunk->size)));
   1372 			// check if this is a dummy GS, in which case we only need a place to store the signature
   1373 			if(sm4.get() && so_info && sm4->version.type != D3D1X_SHVER_GEOMETRY_SHADER)
   1374 				sm4.reset(new sm4_program());
   1375 		}
   1376 		if(!sm4.get())
   1377 			return 0;
   1378 
   1379 		if(dump)
   1380 			sm4->dump();
   1381 
   1382 		struct dxbc_chunk_signature* sig;
   1383 
   1384 		sig = dxbc_find_signature(shader_bytecode, bytecode_length, DXBC_FIND_INPUT_SIGNATURE);
   1385 		if(sig)
   1386 			sm4->num_params_in = dxbc_parse_signature(sig, &sm4->params_in);
   1387 
   1388 		sig = dxbc_find_signature(shader_bytecode, bytecode_length, DXBC_FIND_OUTPUT_SIGNATURE);
   1389 		if(sig)
   1390 			sm4->num_params_out = dxbc_parse_signature(sig, &sm4->params_out);
   1391 
   1392 		sig = dxbc_find_signature(shader_bytecode, bytecode_length, DXBC_FIND_PATCH_SIGNATURE);
   1393 		if(sig)
   1394 			sm4->num_params_patch = dxbc_parse_signature(sig, &sm4->params_patch);
   1395 
   1396 		struct pipe_shader_state tgsi_shader;
   1397 		memset(&tgsi_shader, 0, sizeof(tgsi_shader));
   1398 		if(so_info)
   1399 			memcpy(&tgsi_shader.stream_output, so_info, sizeof(tgsi_shader.stream_output));
   1400 
   1401 		if(so_info && sm4->version.type != D3D1X_SHVER_GEOMETRY_SHADER)
   1402 			tgsi_shader.tokens = (const tgsi_token*)sm4_to_tgsi_linkage_only(*sm4);
   1403 		else
   1404 			tgsi_shader.tokens = (const tgsi_token*)sm4_to_tgsi(*sm4);
   1405 		if(!tgsi_shader.tokens)
   1406 			return 0;
   1407 
   1408 		if(dump)
   1409 			tgsi_dump(tgsi_shader.tokens, 0);
   1410 
   1411 		void* shader_cso;
   1412 		GalliumD3D11Shader<>* shader;
   1413 
   1414 		switch(type)
   1415 		{
   1416 		case PIPE_SHADER_VERTEX:
   1417 			shader_cso = immediate_pipe->create_vs_state(immediate_pipe, &tgsi_shader);
   1418 			shader = (GalliumD3D11Shader<>*)new GalliumD3D11VertexShader(this, shader_cso);
   1419 			break;
   1420 		case PIPE_SHADER_FRAGMENT:
   1421 			shader_cso = immediate_pipe->create_fs_state(immediate_pipe, &tgsi_shader);
   1422 			shader = (GalliumD3D11Shader<>*)new GalliumD3D11PixelShader(this, shader_cso);
   1423 			break;
   1424 		case PIPE_SHADER_GEOMETRY:
   1425 			shader_cso = immediate_pipe->create_gs_state(immediate_pipe, &tgsi_shader);
   1426 			shader = (GalliumD3D11Shader<>*)new GalliumD3D11GeometryShader(this, shader_cso);
   1427 			break;
   1428 		default:
   1429 			shader_cso = 0;
   1430 			shader = 0;
   1431 			break;
   1432 		}
   1433 
   1434 		free((void*)tgsi_shader.tokens);
   1435 		return shader;
   1436 	}
   1437 
   1438 #if API >= 11
   1439 #define CREATE_SHADER_ARGS \
   1440 	const void *shader_bytecode, \
   1441 	SIZE_T bytecode_length, \
   1442 	ID3D11ClassLinkage *class_linkage
   1443 #define PASS_SHADER_ARGS shader_bytecode, bytecode_length, class_linkage
   1444 #else
   1445 #define CREATE_SHADER_ARGS \
   1446 	const void *shader_bytecode, \
   1447 	SIZE_T bytecode_length
   1448 #define PASS_SHADER_ARGS shader_bytecode, bytecode_length
   1449 #endif
   1450 
   1451 #define IMPLEMENT_CREATE_SHADER(Stage, GALLIUM) \
   1452 	virtual HRESULT STDMETHODCALLTYPE Create##Stage##Shader( \
   1453 		CREATE_SHADER_ARGS, \
   1454 		ID3D11##Stage##Shader **out_shader) \
   1455 	{ \
   1456 		SYNCHRONIZED; \
   1457 		GalliumD3D11##Stage##Shader* shader = (GalliumD3D11##Stage##Shader*)create_stage_shader(PIPE_SHADER_##GALLIUM, PASS_SHADER_ARGS, NULL); \
   1458 		if(!shader) \
   1459 			return E_FAIL; \
   1460 		if(out_shader) \
   1461 		{ \
   1462 			*out_shader = shader; \
   1463 			return S_OK; \
   1464 		} \
   1465 		else \
   1466 		{ \
   1467 			shader->Release(); \
   1468 			return S_FALSE; \
   1469 		} \
   1470 	}
   1471 
   1472 #define IMPLEMENT_NOTIMPL_CREATE_SHADER(Stage) \
   1473 	virtual HRESULT STDMETHODCALLTYPE Create##Stage##Shader( \
   1474 		CREATE_SHADER_ARGS, \
   1475 		ID3D11##Stage##Shader **out_shader) \
   1476 	{ \
   1477 		return E_NOTIMPL; \
   1478 	}
   1479 
   1480 	IMPLEMENT_CREATE_SHADER(Vertex, VERTEX)
   1481 	IMPLEMENT_CREATE_SHADER(Pixel, FRAGMENT)
   1482 	IMPLEMENT_CREATE_SHADER(Geometry, GEOMETRY)
   1483 #if API >= 11
   1484 	IMPLEMENT_NOTIMPL_CREATE_SHADER(Hull)
   1485 	IMPLEMENT_NOTIMPL_CREATE_SHADER(Domain)
   1486 	IMPLEMENT_NOTIMPL_CREATE_SHADER(Compute)
   1487 #endif
   1488 
   1489 	virtual HRESULT STDMETHODCALLTYPE CreateGeometryShaderWithStreamOutput(
   1490 		const void *shader_bytecode,
   1491 		SIZE_T bytecode_length,
   1492 		const D3D11_SO_DECLARATION_ENTRY *so_declaration,
   1493 		unsigned num_entries,
   1494 #if API >= 11
   1495 		const unsigned *buffer_strides,
   1496 		unsigned num_strides,
   1497 		unsigned rasterized_stream,
   1498 		ID3D11ClassLinkage *class_linkage,
   1499 #else
   1500 		UINT output_stream_stride,
   1501 #endif
   1502 		ID3D11GeometryShader **out_geometry_shader)
   1503 	{
   1504 		SYNCHRONIZED;
   1505 		GalliumD3D11GeometryShader* gs;
   1506 
   1507 #if API >= 11
   1508 		if(rasterized_stream != 0)
   1509 			return E_NOTIMPL; // not yet supported by gallium
   1510 #endif
   1511 		struct dxbc_chunk_signature* sig = dxbc_find_signature(shader_bytecode, bytecode_length, DXBC_FIND_OUTPUT_SIGNATURE);
   1512 		if(!sig)
   1513 			return E_INVALIDARG;
   1514 		D3D11_SIGNATURE_PARAMETER_DESC* out;
   1515 		unsigned num_outputs = dxbc_parse_signature(sig, &out);
   1516 
   1517 		struct pipe_stream_output_info so;
   1518 		memset(&so, 0, sizeof(so));
   1519 
   1520 #if API >= 11
   1521 		if(num_strides)
   1522 			so.stride = buffer_strides[0];
   1523 		if(num_strides > 1)
   1524 			debug_printf("Warning: multiple user-specified strides not implemented !\n");
   1525 #else
   1526 		so.stride = output_stream_stride;
   1527 #endif
   1528 
   1529 		for(unsigned i = 0; i < num_entries; ++i)
   1530 		{
   1531 			unsigned j;
   1532 			for(j = 0; j < num_outputs; ++j)
   1533 				if(out[j].SemanticIndex == so_declaration[i].SemanticIndex && !strcasecmp(out[j].SemanticName, so_declaration[i].SemanticName))
   1534 					break;
   1535 			if(j >= num_outputs)
   1536 				continue;
   1537 			const int first_comp = ffs(out[j].Mask) - 1 + so_declaration[i].StartComponent;
   1538 			so.output[i].output_buffer = so_declaration[i].OutputSlot;
   1539 			so.output[i].register_index = out[j].Register;
   1540 			so.output[i].register_mask = ((1 << so_declaration[i].ComponentCount) - 1) << first_comp;
   1541 			++so.num_outputs;
   1542 		}
   1543 		if(out)
   1544 			free(out);
   1545 
   1546 		gs = reinterpret_cast<GalliumD3D11GeometryShader*>(create_stage_shader(PIPE_SHADER_GEOMETRY, PASS_SHADER_ARGS, &so));
   1547 		if(!gs)
   1548 			return E_FAIL;
   1549 
   1550 		if(!out_geometry_shader) {
   1551 			gs->Release();
   1552 			return S_FALSE;
   1553 		}
   1554 		*out_geometry_shader = gs;
   1555 
   1556 		return S_OK;
   1557 	}
   1558 
   1559 #if API >= 11
   1560 	virtual HRESULT STDMETHODCALLTYPE CreateClassLinkage(
   1561 		ID3D11ClassLinkage **out_linkage)
   1562 	{
   1563 		SYNCHRONIZED;
   1564 
   1565 		return E_NOTIMPL;
   1566 	}
   1567 #endif
   1568 
   1569 	virtual HRESULT STDMETHODCALLTYPE CreateQuery(
   1570 		const D3D11_QUERY_DESC *query_desc,
   1571 		ID3D11Query **out_query)
   1572 	{
   1573 		SYNCHRONIZED;
   1574 
   1575 		if(invalid(query_desc->Query >= D3D11_QUERY_COUNT))
   1576 			return E_INVALIDARG;
   1577 		unsigned query_type = d3d11_to_pipe_query[query_desc->Query];
   1578 		if(query_type >= PIPE_QUERY_TYPES)
   1579 			return E_NOTIMPL;
   1580 
   1581 		if(!out_query)
   1582 			return S_FALSE;
   1583 
   1584 		struct pipe_query* query = immediate_pipe->create_query(immediate_pipe, query_type);
   1585 		if(!query)
   1586 			return E_FAIL;
   1587 
   1588 		*out_query = new GalliumD3D11Query(this, query, d3d11_query_size[query_desc->Query], *query_desc);
   1589 		return S_OK;
   1590 	}
   1591 
   1592 	virtual HRESULT STDMETHODCALLTYPE CreatePredicate(
   1593 		const D3D11_QUERY_DESC *predicate_desc,
   1594 		ID3D11Predicate **out_predicate)
   1595 	{
   1596 		SYNCHRONIZED;
   1597 
   1598 		unsigned query_type;
   1599 		switch(predicate_desc->Query)
   1600 		{
   1601 		case D3D11_QUERY_SO_OVERFLOW_PREDICATE:
   1602 			query_type = PIPE_QUERY_SO_OVERFLOW_PREDICATE;
   1603 			break;
   1604 		case D3D11_QUERY_OCCLUSION_PREDICATE:
   1605 			query_type = PIPE_QUERY_OCCLUSION_PREDICATE;
   1606 			break;
   1607 		default:
   1608 			return E_INVALIDARG;
   1609 		}
   1610 
   1611 		if(out_predicate)
   1612 			return S_FALSE;
   1613 
   1614 		struct pipe_query* query = immediate_pipe->create_query(immediate_pipe, query_type);
   1615 		if(!query)
   1616 			return E_FAIL;
   1617 
   1618 		*out_predicate = new GalliumD3D11Predicate(this, query, sizeof(BOOL), *predicate_desc);
   1619 		return S_OK;
   1620 	}
   1621 
   1622 
   1623 	virtual HRESULT STDMETHODCALLTYPE CreateCounter(
   1624 		const D3D11_COUNTER_DESC *counter_desc,
   1625 		ID3D11Counter **out_counter)
   1626 	{
   1627 		SYNCHRONIZED;
   1628 
   1629 		return E_NOTIMPL;
   1630 
   1631 		// remember to return S_FALSE if out_counter == NULL and everything is OK
   1632 	}
   1633 
   1634 #if API >= 11
   1635 	virtual HRESULT STDMETHODCALLTYPE CreateDeferredContext(
   1636 		unsigned context_flags,
   1637 		ID3D11DeviceContext **out_deferred_context)
   1638 	{
   1639 		SYNCHRONIZED;
   1640 
   1641 		// TODO: this will have to be implemented using a new Gallium util module
   1642 		return E_NOTIMPL;
   1643 
   1644 		// remember to return S_FALSE if out_counter == NULL and everything is OK
   1645 	}
   1646 #endif
   1647 
   1648 	virtual HRESULT STDMETHODCALLTYPE OpenSharedResource(
   1649 			HANDLE resource,
   1650 			REFIID iid,
   1651 			void **out_resource)
   1652 	{
   1653 		SYNCHRONIZED;
   1654 
   1655 		// TODO: the problem here is that we need to communicate dimensions somehow
   1656 		return E_NOTIMPL;
   1657 
   1658 		// remember to return S_FALSE if out_counter == NULL and everything is OK
   1659 #if 0
   1660 		struct pipe_resou	rce templat;
   1661 		struct winsys_handle handle;
   1662 		handle.stride = 0;
   1663 		handle.handle = resource;
   1664 		handle.type = DRM_API_HANDLE_TYPE_SHARED;
   1665 		screen->resource_from_handle(screen, &templat, &handle);
   1666 #endif
   1667 	}
   1668 
   1669 #if API < 11
   1670 	/* these are documented as "Not implemented".
   1671 	 * According to the UMDDI documentation, they apparently turn on a
   1672 	 * (width + 1) x (height + 1) convolution filter for 1-bit textures.
   1673 	 * Probably nothing uses these, assuming it has ever been implemented anywhere.
   1674 	 */
   1675 	void STDMETHODCALLTYPE SetTextFilterSize(
   1676 		UINT width,
   1677 		UINT height
   1678 	)
   1679 	{}
   1680 
   1681 	virtual void STDMETHODCALLTYPE GetTextFilterSize(
   1682 		UINT *width,
   1683 		UINT *height
   1684 	)
   1685 	{}
   1686 #endif
   1687 
   1688 #if API >= 11
   1689 	virtual void STDMETHODCALLTYPE RestoreGalliumState()
   1690 	{
   1691 		GalliumD3D11ImmediateDeviceContext_RestoreGalliumState(immediate_context);
   1692 	}
   1693 
   1694 	virtual void STDMETHODCALLTYPE RestoreGalliumStateBlitOnly()
   1695 	{
   1696 		GalliumD3D11ImmediateDeviceContext_RestoreGalliumStateBlitOnly(immediate_context);
   1697 	}
   1698 #endif
   1699 
   1700 	virtual struct pipe_context* STDMETHODCALLTYPE GetGalliumContext(void)
   1701 	{
   1702 		return immediate_pipe;
   1703 	}
   1704 
   1705 #undef SYNCHRONIZED
   1706 };
   1707