d3d11_screen.h revision dac5baf2e4702fabe627adc5b30e537560e8980d
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 27DEBUG_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 */ 33static 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 */ 42static 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 */ 55static 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 70static 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(STREAM_OUTPUT), 76 UTIL_CHECK_CAP(CONDITIONAL_RENDER), 77 UTIL_CHECK_CAP(PRIMITIVE_RESTART), 78 UTIL_CHECK_CAP(TGSI_INSTANCEID), 79 UTIL_CHECK_INT(MAX_RENDER_TARGETS, 8), 80 UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 13), 81 UTIL_CHECK_INT(MAX_TEXTURE_ARRAY_LAYERS, 512), 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 92template<bool threadsafe> 93struct 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_STREAM_OUTPUT); 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 pipe_format format = dxgi_to_pipe_format[dxgi_format]; 307 if(!format) 308 return E_INVALIDARG; 309 310 int support = format_support[format]; 311 if(support < 0) 312 { 313 support = 0; 314 unsigned buffer = D3D11_FORMAT_SUPPORT_BUFFER | D3D11_FORMAT_SUPPORT_IA_VERTEX_BUFFER | D3D11_FORMAT_SUPPORT_IA_INDEX_BUFFER; 315 unsigned sampler_view = D3D11_FORMAT_SUPPORT_SHADER_SAMPLE | D3D11_FORMAT_SUPPORT_MIP | D3D11_FORMAT_SUPPORT_MIP_AUTOGEN; 316 if(util_format_is_depth_or_stencil(format)) 317 sampler_view |= D3D11_FORMAT_SUPPORT_SHADER_SAMPLE_COMPARISON; 318 319 /* TODO: do this properly when Gallium drivers actually support index/vertex format queries */ 320 if(screen->is_format_supported(screen, format, PIPE_BUFFER, 0, PIPE_BIND_VERTEX_BUFFER) 321 || (screen->is_format_supported(screen, format, PIPE_BUFFER, 0, PIPE_BIND_INDEX_BUFFER) 322 || format == PIPE_FORMAT_R8_UNORM)) 323 support |= buffer; 324 if(screen->is_format_supported(screen, format, PIPE_BUFFER, 0, PIPE_BIND_STREAM_OUTPUT)) 325 support |= buffer | D3D11_FORMAT_SUPPORT_SO_BUFFER; 326 if(screen->is_format_supported(screen, format, PIPE_TEXTURE_1D, 0, PIPE_BIND_SAMPLER_VIEW)) 327 support |= D3D11_FORMAT_SUPPORT_TEXTURE1D | sampler_view; 328 if(screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW)) 329 support |= D3D11_FORMAT_SUPPORT_TEXTURE2D | sampler_view; 330 if(screen->is_format_supported(screen, format, PIPE_TEXTURE_CUBE, 0, PIPE_BIND_SAMPLER_VIEW)) 331 support |= D3D11_FORMAT_SUPPORT_TEXTURE2D | sampler_view; 332 if(screen->is_format_supported(screen, format, PIPE_TEXTURE_3D, 0, PIPE_BIND_SAMPLER_VIEW)) 333 support |= D3D11_FORMAT_SUPPORT_TEXTURE3D | sampler_view; 334 if(screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET)) 335 support |= D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_RENDER_TARGET | D3D11_FORMAT_SUPPORT_BLENDABLE; 336 if(screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL)) 337 support |= D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_DEPTH_STENCIL; 338 if(screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_DISPLAY_TARGET)) 339 support |= D3D11_FORMAT_SUPPORT_DISPLAY; 340 format_support[format] = support; 341 } 342 *out_format_support = support; 343 return S_OK; 344 } 345 346 virtual HRESULT STDMETHODCALLTYPE CheckMultisampleQualityLevels( 347 DXGI_FORMAT format, 348 unsigned sample_count, 349 unsigned *pcount 350 ) 351 { 352 SYNCHRONIZED; 353 354 if(sample_count == 1) 355 *pcount = 1; 356 else 357 *pcount = 0; 358 return S_OK; 359 } 360 361 template<typename T, typename U> 362 bool convert_blend_state(T& to, const U& from, unsigned BlendEnable, unsigned RenderTargetWriteMask) 363 { 364 if(invalid(0 365 || from.SrcBlend >= D3D11_BLEND_COUNT 366 || from.SrcBlendAlpha >= D3D11_BLEND_COUNT 367 || from.DestBlend >= D3D11_BLEND_COUNT 368 || from.DestBlendAlpha >= D3D11_BLEND_COUNT 369 || from.BlendOp >= 6 370 || from.BlendOpAlpha >= 6 371 || !from.BlendOp 372 || !from.BlendOpAlpha 373 )) 374 return false; 375 376 to.blend_enable = BlendEnable; 377 378 to.rgb_func = from.BlendOp - 1; 379 to.alpha_func = from.BlendOpAlpha - 1; 380 381 to.rgb_src_factor = d3d11_to_pipe_blend[from.SrcBlend]; 382 to.alpha_src_factor = d3d11_to_pipe_blend[from.SrcBlendAlpha]; 383 to.rgb_dst_factor = d3d11_to_pipe_blend[from.DestBlend]; 384 to.alpha_dst_factor = d3d11_to_pipe_blend[from.DestBlendAlpha]; 385 386 to.colormask = RenderTargetWriteMask & 0xf; 387 return true; 388 } 389 390#if API >= 11 391 virtual HRESULT STDMETHODCALLTYPE CreateBlendState( 392 const D3D11_BLEND_DESC *blend_state_desc, 393 ID3D11BlendState **out_blend_state 394 ) 395#else 396 virtual HRESULT STDMETHODCALLTYPE CreateBlendState1( 397 const D3D10_BLEND_DESC1 *blend_state_desc, 398 ID3D10BlendState1 **out_blend_state 399 ) 400#endif 401 { 402 SYNCHRONIZED; 403 404 pipe_blend_state state; 405 memset(&state, 0, sizeof(state)); 406 state.alpha_to_coverage = !!blend_state_desc->AlphaToCoverageEnable; 407 state.independent_blend_enable = !!blend_state_desc->IndependentBlendEnable; 408 assert(PIPE_MAX_COLOR_BUFS >= 8); 409 for(unsigned i = 0; i < 8; ++i) 410 { 411 if(!convert_blend_state( 412 state.rt[i], 413 blend_state_desc->RenderTarget[i], 414 blend_state_desc->RenderTarget[i].BlendEnable, 415 blend_state_desc->RenderTarget[i].RenderTargetWriteMask)) 416 return E_INVALIDARG; 417 } 418 419 if(!out_blend_state) 420 return S_FALSE; 421 422 void* object = immediate_pipe->create_blend_state(immediate_pipe, &state); 423 if(!object) 424 return E_FAIL; 425 426 *out_blend_state = new GalliumD3D11BlendState(this, object, *blend_state_desc); 427 return S_OK; 428 } 429 430#if API < 11 431 virtual HRESULT STDMETHODCALLTYPE CreateBlendState( 432 const D3D10_BLEND_DESC *blend_state_desc, 433 ID3D10BlendState **out_blend_state 434 ) 435 { 436 SYNCHRONIZED; 437 438 pipe_blend_state state; 439 memset(&state, 0, sizeof(state)); 440 state.alpha_to_coverage = !!blend_state_desc->AlphaToCoverageEnable; 441 assert(PIPE_MAX_COLOR_BUFS >= 8); 442 for(unsigned i = 0; i < 8; ++i) 443 { 444 if(!convert_blend_state( 445 state.rt[i], 446 *blend_state_desc, 447 blend_state_desc->BlendEnable[i], 448 blend_state_desc->RenderTargetWriteMask[i])) 449 return E_INVALIDARG; 450 } 451 452 for(unsigned i = 1; i < 8; ++i) 453 { 454 if(memcmp(&state.rt[0], &state.rt[i], sizeof(state.rt[0]))) 455 { 456 state.independent_blend_enable = TRUE; 457 break; 458 } 459 } 460 461 void* object = immediate_pipe->create_blend_state(immediate_pipe, &state); 462 if(!object) 463 return E_FAIL; 464 465 *out_blend_state = new GalliumD3D11BlendState(this, object, *blend_state_desc); 466 return S_OK; 467 } 468#endif 469 470 virtual HRESULT STDMETHODCALLTYPE CreateDepthStencilState( 471 const D3D11_DEPTH_STENCIL_DESC *depth_stencil_state_desc, 472 ID3D11DepthStencilState **depth_stencil_state 473 ) 474 { 475 SYNCHRONIZED; 476 477 pipe_depth_stencil_alpha_state state; 478 memset(&state, 0, sizeof(state)); 479 state.depth.enabled = !!depth_stencil_state_desc->DepthEnable; 480 state.depth.writemask = depth_stencil_state_desc->DepthWriteMask; 481 state.depth.func = depth_stencil_state_desc->DepthFunc - 1; 482 state.stencil[0].enabled = !!depth_stencil_state_desc->StencilEnable; 483 state.stencil[0].writemask = depth_stencil_state_desc->StencilWriteMask; 484 state.stencil[0].valuemask = depth_stencil_state_desc->StencilReadMask; 485 state.stencil[0].zpass_op = d3d11_to_pipe_stencil_op[depth_stencil_state_desc->FrontFace.StencilPassOp]; 486 state.stencil[0].fail_op = d3d11_to_pipe_stencil_op[depth_stencil_state_desc->FrontFace.StencilFailOp]; 487 state.stencil[0].zfail_op = d3d11_to_pipe_stencil_op[depth_stencil_state_desc->FrontFace.StencilDepthFailOp]; 488 state.stencil[0].func = depth_stencil_state_desc->FrontFace.StencilFunc - 1; 489 state.stencil[1].enabled = !!depth_stencil_state_desc->StencilEnable; 490 state.stencil[1].writemask = depth_stencil_state_desc->StencilWriteMask; 491 state.stencil[1].valuemask = depth_stencil_state_desc->StencilReadMask; 492 state.stencil[1].zpass_op = d3d11_to_pipe_stencil_op[depth_stencil_state_desc->BackFace.StencilPassOp]; 493 state.stencil[1].fail_op = d3d11_to_pipe_stencil_op[depth_stencil_state_desc->BackFace.StencilFailOp]; 494 state.stencil[1].zfail_op = d3d11_to_pipe_stencil_op[depth_stencil_state_desc->BackFace.StencilDepthFailOp]; 495 state.stencil[1].func = depth_stencil_state_desc->BackFace.StencilFunc - 1; 496 497 if(!depth_stencil_state) 498 return S_FALSE; 499 500 void* object = immediate_pipe->create_depth_stencil_alpha_state(immediate_pipe, &state); 501 if(!object) 502 return E_FAIL; 503 504 *depth_stencil_state = new GalliumD3D11DepthStencilState(this, object, *depth_stencil_state_desc); 505 return S_OK; 506 } 507 508 virtual HRESULT STDMETHODCALLTYPE CreateRasterizerState( 509 const D3D11_RASTERIZER_DESC *rasterizer_desc, 510 ID3D11RasterizerState **out_rasterizer_state) 511 { 512 SYNCHRONIZED; 513 514 pipe_rasterizer_state state; 515 memset(&state, 0, sizeof(state)); 516 state.gl_rasterization_rules = 1; /* D3D10/11 use GL rules */ 517 state.fill_front = state.fill_back = (rasterizer_desc->FillMode == D3D11_FILL_WIREFRAME) ? PIPE_POLYGON_MODE_LINE : PIPE_POLYGON_MODE_FILL; 518 if(rasterizer_desc->CullMode == D3D11_CULL_FRONT) 519 state.cull_face = PIPE_FACE_FRONT; 520 else if(rasterizer_desc->CullMode == D3D11_CULL_BACK) 521 state.cull_face = PIPE_FACE_BACK; 522 else 523 state.cull_face = PIPE_FACE_NONE; 524 state.front_ccw = !!rasterizer_desc->FrontCounterClockwise; 525 state.offset_tri = state.offset_line = state.offset_point = rasterizer_desc->SlopeScaledDepthBias || rasterizer_desc->DepthBias; 526 state.offset_scale = rasterizer_desc->SlopeScaledDepthBias; 527 state.offset_units = rasterizer_desc->DepthBias; 528 state.offset_clamp = rasterizer_desc->DepthBiasClamp; 529 state.scissor = !!rasterizer_desc->ScissorEnable; 530 state.multisample = !!rasterizer_desc->MultisampleEnable; 531 state.line_smooth = !!rasterizer_desc->AntialiasedLineEnable; 532 state.flatshade_first = 1; 533 state.line_width = 1.0f; 534 state.point_size = 1.0f; 535 536 /* TODO: is this correct? */ 537 state.point_quad_rasterization = 1; 538 539 if(!out_rasterizer_state) 540 return S_FALSE; 541 542 void* object = immediate_pipe->create_rasterizer_state(immediate_pipe, &state); 543 if(!object) 544 return E_FAIL; 545 546 *out_rasterizer_state = new GalliumD3D11RasterizerState(this, object, *rasterizer_desc, !rasterizer_desc->DepthClipEnable); 547 return S_OK; 548 } 549 550 virtual HRESULT STDMETHODCALLTYPE CreateSamplerState( 551 const D3D11_SAMPLER_DESC *sampler_desc, 552 ID3D11SamplerState **out_sampler_state) 553 { 554 SYNCHRONIZED; 555 556 pipe_sampler_state state; 557 memset(&state, 0, sizeof(state)); 558 state.normalized_coords = 1; 559 state.min_mip_filter = (sampler_desc->Filter & 1); 560 state.mag_img_filter = ((sampler_desc->Filter >> 2) & 1); 561 state.min_img_filter = ((sampler_desc->Filter >> 4) & 1); 562 if(sampler_desc->Filter & 0x40) 563 state.max_anisotropy = sampler_desc->MaxAnisotropy; 564 if(sampler_desc->Filter & 0x80) 565 { 566 state.compare_mode = PIPE_TEX_COMPARE_R_TO_TEXTURE; 567 state.compare_func = sampler_desc->ComparisonFunc; 568 } 569 state.wrap_s = d3d11_to_pipe_wrap[sampler_desc->AddressU]; 570 state.wrap_t = d3d11_to_pipe_wrap[sampler_desc->AddressV]; 571 state.wrap_r = d3d11_to_pipe_wrap[sampler_desc->AddressW]; 572 state.lod_bias = sampler_desc->MipLODBias; 573 memcpy(state.border_color.f, sampler_desc->BorderColor, sizeof(state.border_color)); 574 state.min_lod = sampler_desc->MinLOD; 575 state.max_lod = sampler_desc->MaxLOD; 576 577 if(!out_sampler_state) 578 return S_FALSE; 579 580 void* object = immediate_pipe->create_sampler_state(immediate_pipe, &state); 581 if(!object) 582 return E_FAIL; 583 584 *out_sampler_state = new GalliumD3D11SamplerState(this, object, *sampler_desc); 585 return S_OK; 586 } 587 588 virtual HRESULT STDMETHODCALLTYPE CreateInputLayout( 589 const D3D11_INPUT_ELEMENT_DESC *input_element_descs, 590 unsigned count, 591 const void *shader_bytecode_with_input_signature, 592 SIZE_T bytecode_length, 593 ID3D11InputLayout **out_input_layout) 594 { 595 SYNCHRONIZED; 596 597 if(count > D3D11_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT) 598 return E_INVALIDARG; 599 assert(D3D11_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT <= PIPE_MAX_ATTRIBS); 600 601 // putting semantics matching in the core API seems to be a (minor) design mistake 602 603 struct dxbc_chunk_signature* sig = dxbc_find_signature(shader_bytecode_with_input_signature, bytecode_length, DXBC_FIND_INPUT_SIGNATURE); 604 D3D11_SIGNATURE_PARAMETER_DESC* params; 605 unsigned num_params = dxbc_parse_signature(sig, ¶ms); 606 607 typedef std::unordered_map<std::pair<c_string, unsigned>, unsigned> semantic_to_idx_map_t; 608 semantic_to_idx_map_t semantic_to_idx_map; 609 for(unsigned i = 0; i < count; ++i) 610 semantic_to_idx_map[std::make_pair(c_string(input_element_descs[i].SemanticName), input_element_descs[i].SemanticIndex)] = i; 611 612 struct pipe_vertex_element elements[D3D11_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT]; 613 614 unsigned num_params_to_use = std::min(num_params, (unsigned)D3D11_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT); 615 for(unsigned i = 0; i < num_params_to_use; ++i) 616 { 617 int idx = -1; 618 semantic_to_idx_map_t::iterator iter = semantic_to_idx_map.find(std::make_pair(c_string(params[i].SemanticName), params[i].SemanticIndex)); 619 if(iter != semantic_to_idx_map.end()) 620 idx = iter->second; 621 622 // TODO: I kind of doubt Gallium drivers will like null elements; should we do something about it, either here, in the interface, or in the drivers? 623 // TODO: also, in which cases should we return errors? (i.e. duplicate semantics in vs, duplicate semantics in layout, unmatched semantic in vs, unmatched semantic in layout) 624 memset(&elements[i], 0, sizeof(elements[i])); 625 if(idx >= 0) 626 { 627 elements[i].src_format = dxgi_to_pipe_format[input_element_descs[idx].Format]; 628 elements[i].src_offset = input_element_descs[idx].AlignedByteOffset; 629 elements[i].vertex_buffer_index = input_element_descs[idx].InputSlot; 630 elements[i].instance_divisor = input_element_descs[idx].InstanceDataStepRate; 631 } 632 } 633 634 free(params); 635 636 if(!out_input_layout) 637 return S_FALSE; 638 639 void* object = immediate_pipe->create_vertex_elements_state(immediate_pipe, num_params_to_use, elements); 640 if(!object) 641 return E_FAIL; 642 643 *out_input_layout = new GalliumD3D11InputLayout(this, object); 644 return S_OK; 645 } 646 647 static unsigned d3d11_to_pipe_bind_flags(unsigned bind_flags) 648 { 649 unsigned bind = 0; 650 if(bind_flags & D3D11_BIND_VERTEX_BUFFER) 651 bind |= PIPE_BIND_VERTEX_BUFFER; 652 if(bind_flags & D3D11_BIND_INDEX_BUFFER) 653 bind |= PIPE_BIND_INDEX_BUFFER; 654 if(bind_flags & D3D11_BIND_CONSTANT_BUFFER) 655 bind |= PIPE_BIND_CONSTANT_BUFFER; 656 if(bind_flags & D3D11_BIND_SHADER_RESOURCE) 657 bind |= PIPE_BIND_SAMPLER_VIEW; 658 if(bind_flags & D3D11_BIND_STREAM_OUTPUT) 659 bind |= PIPE_BIND_STREAM_OUTPUT; 660 if(bind_flags & D3D11_BIND_RENDER_TARGET) 661 bind |= PIPE_BIND_RENDER_TARGET; 662 if(bind_flags & D3D11_BIND_DEPTH_STENCIL) 663 bind |= PIPE_BIND_DEPTH_STENCIL; 664 return bind; 665 } 666 667 inline HRESULT create_resource( 668 pipe_texture_target target, 669 unsigned width, 670 unsigned height, 671 unsigned depth, 672 unsigned mip_levels, 673 unsigned array_size, 674 DXGI_FORMAT format, 675 const DXGI_SAMPLE_DESC* SampleDesc, 676 D3D11_USAGE usage, 677 unsigned bind_flags, 678 unsigned c_p_u_access_flags, 679 unsigned misc_flags, 680 const D3D11_SUBRESOURCE_DATA *initial_data, 681 DXGI_USAGE dxgi_usage, 682 struct pipe_resource** ppresource 683 ) 684 { 685 if(invalid(format >= DXGI_FORMAT_COUNT)) 686 return E_INVALIDARG; 687 if(misc_flags & D3D11_RESOURCE_MISC_TEXTURECUBE) 688 { 689 if(target != PIPE_TEXTURE_2D) 690 return E_INVALIDARG; 691 target = PIPE_TEXTURE_CUBE; 692 if(array_size % 6) 693 return E_INVALIDARG; 694 } 695 else if(array_size > 1) 696 { 697 switch (target) { 698 case PIPE_TEXTURE_1D: target = PIPE_TEXTURE_1D_ARRAY; break; 699 case PIPE_TEXTURE_2D: target = PIPE_TEXTURE_2D_ARRAY; break; 700 default: 701 return E_INVALIDARG; 702 } 703 } 704 /* TODO: msaa */ 705 struct pipe_resource templat; 706 memset(&templat, 0, sizeof(templat)); 707 templat.target = target; 708 templat.width0 = width; 709 templat.height0 = height; 710 templat.depth0 = depth; 711 templat.array_size = array_size; 712 if(mip_levels) 713 templat.last_level = mip_levels - 1; 714 else 715 templat.last_level = MAX2(MAX2(util_logbase2(templat.width0), util_logbase2(templat.height0)), util_logbase2(templat.depth0)); 716 templat.format = dxgi_to_pipe_format[format]; 717 templat.bind = d3d11_to_pipe_bind_flags(bind_flags); 718 if(c_p_u_access_flags & D3D11_CPU_ACCESS_READ) 719 templat.bind |= PIPE_BIND_TRANSFER_READ; 720 if(c_p_u_access_flags & D3D11_CPU_ACCESS_WRITE) 721 templat.bind |= PIPE_BIND_TRANSFER_WRITE; 722 if(misc_flags & D3D11_RESOURCE_MISC_SHARED) 723 templat.bind |= PIPE_BIND_SHARED; 724 if(misc_flags & D3D11_RESOURCE_MISC_GDI_COMPATIBLE) 725 templat.bind |= PIPE_BIND_TRANSFER_READ | PIPE_BIND_TRANSFER_WRITE; 726 if(dxgi_usage & DXGI_USAGE_BACK_BUFFER) 727 templat.bind |= PIPE_BIND_DISPLAY_TARGET; 728 templat.usage = d3d11_to_pipe_usage[usage]; 729 if(invalid(!templat.format)) 730 return E_NOTIMPL; 731 732 if(!ppresource) 733 return S_FALSE; 734 735 struct pipe_resource* resource = screen->resource_create(screen, &templat); 736 if(!resource) 737 return E_FAIL; 738 if(initial_data) 739 { 740 for(unsigned slice = 0; slice < array_size; ++slice) 741 { 742 for(unsigned level = 0; level <= templat.last_level; ++level) 743 { 744 struct pipe_box box; 745 box.x = box.y = 0; 746 box.z = slice; 747 box.width = u_minify(width, level); 748 box.height = u_minify(height, level); 749 box.depth = 1; 750 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); 751 ++initial_data; 752 } 753 } 754 } 755 *ppresource = resource; 756 return S_OK; 757 } 758 759 static unsigned d3d_to_dxgi_usage(unsigned bind, unsigned misc) 760 { 761 unsigned dxgi_usage = 0; 762 if(bind |= D3D11_BIND_RENDER_TARGET) 763 dxgi_usage |= DXGI_USAGE_RENDER_TARGET_OUTPUT; 764 if(bind & D3D11_BIND_SHADER_RESOURCE) 765 dxgi_usage |= DXGI_USAGE_SHADER_INPUT; 766#if API >= 11 767 if(bind & D3D11_BIND_UNORDERED_ACCESS) 768 dxgi_usage |= DXGI_USAGE_UNORDERED_ACCESS; 769#endif 770 if(misc & D3D11_RESOURCE_MISC_SHARED) 771 dxgi_usage |= DXGI_USAGE_SHARED; 772 return dxgi_usage; 773 } 774 775 virtual HRESULT STDMETHODCALLTYPE CreateTexture1D( 776 const D3D11_TEXTURE1D_DESC *desc, 777 const D3D11_SUBRESOURCE_DATA *initial_data, 778 ID3D11Texture1D **out_texture1d) 779 { 780 SYNCHRONIZED; 781 782 struct pipe_resource* resource; 783 DXGI_USAGE dxgi_usage = d3d_to_dxgi_usage(desc->BindFlags, desc->MiscFlags); 784 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); 785 if(hr != S_OK) 786 return hr; 787 D3D11_TEXTURE1D_DESC cdesc = *desc; 788 cdesc.MipLevels = resource->last_level + 1; 789 *out_texture1d = new GalliumD3D11Texture1D(this, resource, cdesc, dxgi_usage); 790 return S_OK; 791 } 792 793 virtual HRESULT STDMETHODCALLTYPE CreateTexture2D( 794 const D3D11_TEXTURE2D_DESC *desc, 795 const D3D11_SUBRESOURCE_DATA *initial_data, 796 ID3D11Texture2D **out_texture2d) 797 { 798 SYNCHRONIZED; 799 800 struct pipe_resource* resource; 801 DXGI_USAGE dxgi_usage = d3d_to_dxgi_usage(desc->BindFlags, desc->MiscFlags); 802 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); 803 if(hr != S_OK) 804 return hr; 805 D3D11_TEXTURE2D_DESC cdesc = *desc; 806 cdesc.MipLevels = resource->last_level + 1; 807 if(cdesc.MipLevels == 1 && cdesc.ArraySize == 1) 808 *out_texture2d = new GalliumD3D11Surface(this, resource, cdesc, dxgi_usage); 809 else 810 *out_texture2d = new GalliumD3D11Texture2D(this, resource, cdesc, dxgi_usage); 811 return S_OK; 812 } 813 814 virtual HRESULT STDMETHODCALLTYPE CreateTexture3D( 815 const D3D11_TEXTURE3D_DESC *desc, 816 const D3D11_SUBRESOURCE_DATA *initial_data, 817 ID3D11Texture3D **out_texture3d) 818 { 819 SYNCHRONIZED; 820 821 struct pipe_resource* resource; 822 DXGI_USAGE dxgi_usage = d3d_to_dxgi_usage(desc->BindFlags, desc->MiscFlags); 823 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); 824 if(hr != S_OK) 825 return hr; 826 D3D11_TEXTURE3D_DESC cdesc = *desc; 827 cdesc.MipLevels = resource->last_level + 1; 828 *out_texture3d = new GalliumD3D11Texture3D(this, resource, cdesc, dxgi_usage); 829 return S_OK; 830 } 831 832 virtual HRESULT STDMETHODCALLTYPE CreateBuffer( 833 const D3D11_BUFFER_DESC *desc, 834 const D3D11_SUBRESOURCE_DATA *initial_data, 835 ID3D11Buffer **out_buffer) 836 { 837 SYNCHRONIZED; 838 839 struct pipe_resource* resource; 840 DXGI_USAGE dxgi_usage = d3d_to_dxgi_usage(desc->BindFlags, desc->MiscFlags); 841 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); 842 if(hr != S_OK) 843 return hr; 844 *out_buffer = new GalliumD3D11Buffer(this, resource, *desc, dxgi_usage); 845 return S_OK; 846 } 847 848 virtual HRESULT STDMETHODCALLTYPE OpenGalliumResource( 849 struct pipe_resource* resource, 850 IUnknown** dxgi_resource) 851 { 852 SYNCHRONIZED; 853 854 /* TODO: maybe support others */ 855 assert(resource->target == PIPE_TEXTURE_2D); 856 *dxgi_resource = 0; 857 D3D11_TEXTURE2D_DESC desc; 858 memset(&desc, 0, sizeof(desc)); 859 desc.Width = resource->width0; 860 desc.Height = resource->height0; 861 init_pipe_to_dxgi_format(); 862 desc.Format = pipe_to_dxgi_format[resource->format]; 863 desc.SampleDesc.Count = resource->nr_samples; 864 desc.SampleDesc.Quality = 0; 865 desc.ArraySize = 1; 866 desc.MipLevels = resource->last_level + 1; 867 desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; 868 if(resource->bind & PIPE_BIND_RENDER_TARGET) 869 desc.BindFlags |= D3D11_BIND_RENDER_TARGET; 870 if(resource->bind & PIPE_BIND_DEPTH_STENCIL) 871 desc.BindFlags |= D3D11_BIND_DEPTH_STENCIL; 872 if(resource->bind & PIPE_BIND_SAMPLER_VIEW) 873 desc.BindFlags |= D3D11_BIND_SHADER_RESOURCE; 874 if(resource->bind & PIPE_BIND_SHARED) 875 desc.MiscFlags |= D3D11_RESOURCE_MISC_SHARED; 876 DXGI_USAGE dxgi_usage = d3d_to_dxgi_usage(desc.BindFlags, desc.MiscFlags); 877 if(desc.MipLevels == 1 && desc.ArraySize == 1) 878 *dxgi_resource = (ID3D11Texture2D*)new GalliumD3D11Surface(this, resource, desc, dxgi_usage); 879 else 880 *dxgi_resource = (ID3D11Texture2D*)new GalliumD3D11Texture2D(this, resource, desc, dxgi_usage); 881 return S_OK; 882 } 883 884 virtual HRESULT STDMETHODCALLTYPE CreateSurface( 885 const DXGI_SURFACE_DESC *dxgi_desc, 886 unsigned count, 887 DXGI_USAGE usage, 888 const DXGI_SHARED_RESOURCE *shared_resource, 889 IDXGISurface **out_surface) 890 { 891 SYNCHRONIZED; 892 893 D3D11_TEXTURE2D_DESC desc; 894 memset(&desc, 0, sizeof(desc)); 895 896 struct pipe_resource* resource; 897 desc.Width = dxgi_desc->Width; 898 desc.Height = dxgi_desc->Height; 899 desc.Format = dxgi_desc->Format; 900 desc.SampleDesc = dxgi_desc->SampleDesc; 901 desc.ArraySize = count; 902 desc.MipLevels = 1; 903 desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; 904 if(usage & DXGI_USAGE_RENDER_TARGET_OUTPUT) 905 desc.BindFlags |= D3D11_BIND_RENDER_TARGET; 906 if(usage & DXGI_USAGE_SHADER_INPUT) 907 desc.BindFlags |= D3D11_BIND_SHADER_RESOURCE; 908#if API >= 11 909 if(usage & DXGI_USAGE_UNORDERED_ACCESS) 910 desc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS; 911#endif 912 if(usage & DXGI_USAGE_SHARED) 913 desc.MiscFlags |= D3D11_RESOURCE_MISC_SHARED; 914 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); 915 if(hr != S_OK) 916 return hr; 917 *out_surface = new GalliumD3D11Surface(this, resource, desc, usage); 918 return S_OK; 919 } 920 921 virtual HRESULT STDMETHODCALLTYPE CreateShaderResourceView( 922 ID3D11Resource *iresource, 923 const D3D11_SHADER_RESOURCE_VIEW_DESC *desc, 924 ID3D11ShaderResourceView **out_srv) 925 { 926#if API >= 11 927 D3D11_SHADER_RESOURCE_VIEW_DESC def_desc; 928#else 929 if(desc->ViewDimension == D3D10_1_SRV_DIMENSION_TEXTURECUBEARRAY) 930 return E_INVALIDARG; 931 D3D10_SHADER_RESOURCE_VIEW_DESC1 desc1; 932 memset(&desc1, 0, sizeof(desc1)); 933 memcpy(&desc1, desc, sizeof(*desc)); 934 return CreateShaderResourceView1(iresource, &desc1, (ID3D10ShaderResourceView1**)out_srv); 935 } 936 937 virtual HRESULT STDMETHODCALLTYPE CreateShaderResourceView1( 938 ID3D11Resource *iresource, 939 const D3D10_SHADER_RESOURCE_VIEW_DESC1 *desc, 940 ID3D10ShaderResourceView1 **out_srv) 941 { 942 D3D10_SHADER_RESOURCE_VIEW_DESC1 def_desc; 943#endif 944 SYNCHRONIZED; 945 946 if(!desc) 947 { 948 struct pipe_resource* resource = ((GalliumD3D11Resource<>*)iresource)->resource; 949 init_pipe_to_dxgi_format(); 950 memset(&def_desc, 0, sizeof(def_desc)); 951 def_desc.Format = pipe_to_dxgi_format[resource->format]; 952 switch(resource->target) 953 { 954 case PIPE_BUFFER: 955 def_desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; 956 def_desc.Buffer.ElementWidth = resource->width0; 957 break; 958 case PIPE_TEXTURE_1D: 959 def_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D; 960 def_desc.Texture1D.MipLevels = resource->last_level + 1; 961 break; 962 case PIPE_TEXTURE_1D_ARRAY: 963 def_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1DARRAY; 964 def_desc.Texture1DArray.MipLevels = resource->last_level + 1; 965 def_desc.Texture1DArray.ArraySize = resource->array_size; 966 break; 967 case PIPE_TEXTURE_2D: 968 case PIPE_TEXTURE_RECT: 969 def_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; 970 def_desc.Texture2D.MipLevels = resource->last_level + 1; 971 break; 972 case PIPE_TEXTURE_2D_ARRAY: 973 def_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; 974 def_desc.Texture2DArray.MipLevels = resource->last_level + 1; 975 def_desc.Texture2DArray.ArraySize = resource->array_size; 976 break; 977 case PIPE_TEXTURE_3D: 978 def_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; 979 def_desc.Texture3D.MipLevels = resource->last_level + 1; 980 break; 981 case PIPE_TEXTURE_CUBE: 982 if(resource->array_size > 6) 983 { 984 def_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY; 985 def_desc.TextureCubeArray.NumCubes = resource->array_size / 6; 986 } 987 else 988 { 989 def_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; 990 } 991 def_desc.TextureCube.MipLevels = resource->last_level + 1; 992 break; 993 default: 994 return E_INVALIDARG; 995 } 996 desc = &def_desc; 997 } 998 999 struct pipe_sampler_view templat; 1000 memset(&templat, 0, sizeof(templat)); 1001 if(invalid(format >= DXGI_FORMAT_COUNT)) 1002 return E_INVALIDARG; 1003 templat.format = dxgi_to_pipe_format[desc->Format]; 1004 if(!templat.format) 1005 return E_NOTIMPL; 1006 templat.swizzle_r = PIPE_SWIZZLE_RED; 1007 templat.swizzle_g = PIPE_SWIZZLE_GREEN; 1008 templat.swizzle_b = PIPE_SWIZZLE_BLUE; 1009 templat.swizzle_a = PIPE_SWIZZLE_ALPHA; 1010 1011 templat.texture = ((GalliumD3D11Resource<>*)iresource)->resource; 1012 switch(desc->ViewDimension) 1013 { 1014 case D3D11_SRV_DIMENSION_TEXTURE1DARRAY: 1015 case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: 1016 case D3D11_SRV_DIMENSION_TEXTURECUBEARRAY: 1017 templat.u.tex.first_layer = desc->Texture1DArray.FirstArraySlice; 1018 templat.u.tex.last_layer = desc->Texture1DArray.FirstArraySlice + desc->Texture1DArray.ArraySize - 1; 1019 if (desc->ViewDimension == D3D11_SRV_DIMENSION_TEXTURECUBEARRAY) { 1020 templat.u.tex.first_layer *= 6; 1021 templat.u.tex.last_layer *= 6; 1022 } 1023 // fall through 1024 case D3D11_SRV_DIMENSION_TEXTURE1D: 1025 case D3D11_SRV_DIMENSION_TEXTURE2D: 1026 case D3D11_SRV_DIMENSION_TEXTURE3D: 1027 case D3D11_SRV_DIMENSION_TEXTURECUBE: 1028 // yes, this works for all of these types 1029 templat.u.tex.first_level = desc->Texture1D.MostDetailedMip; 1030 if(desc->Texture1D.MipLevels == (unsigned)-1) 1031 templat.u.tex.last_level = templat.texture->last_level; 1032 else 1033 templat.u.tex.last_level = templat.u.tex.first_level + desc->Texture1D.MipLevels - 1; 1034 assert(templat.u.tex.last_level >= templat.u.tex.first_level); 1035 break; 1036 case D3D11_SRV_DIMENSION_BUFFER: 1037 case D3D11_SRV_DIMENSION_TEXTURE2DMS: 1038 case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY: 1039 return E_NOTIMPL; 1040 default: 1041 return E_INVALIDARG; 1042 } 1043 1044 if(!out_srv) 1045 return S_FALSE; 1046 1047 struct pipe_sampler_view* view = immediate_pipe->create_sampler_view(immediate_pipe, templat.texture, &templat); 1048 if(!view) 1049 return E_FAIL; 1050 *out_srv = new GalliumD3D11ShaderResourceView(this, (GalliumD3D11Resource<>*)iresource, view, *desc); 1051 return S_OK; 1052 } 1053 1054#if API >= 11 1055 virtual HRESULT STDMETHODCALLTYPE CreateUnorderedAccessView( 1056 ID3D11Resource *resource, 1057 const D3D11_UNORDERED_ACCESS_VIEW_DESC *desc, 1058 ID3D11UnorderedAccessView **out_uav) 1059 { 1060 SYNCHRONIZED; 1061 1062 return E_NOTIMPL; 1063 1064 // remember to return S_FALSE and not crash if out_u_a_view == 0 and parameters are valid 1065 } 1066#endif 1067 1068 virtual HRESULT STDMETHODCALLTYPE CreateRenderTargetView( 1069 ID3D11Resource *iresource, 1070 const D3D11_RENDER_TARGET_VIEW_DESC *desc, 1071 ID3D11RenderTargetView **out_rtv) 1072 { 1073 SYNCHRONIZED; 1074 1075 D3D11_RENDER_TARGET_VIEW_DESC def_desc; 1076 if(!desc) 1077 { 1078 struct pipe_resource* resource = ((GalliumD3D11Resource<>*)iresource)->resource; 1079 init_pipe_to_dxgi_format(); 1080 memset(&def_desc, 0, sizeof(def_desc)); 1081 def_desc.Format = pipe_to_dxgi_format[resource->format]; 1082 switch(resource->target) 1083 { 1084 case PIPE_BUFFER: 1085 def_desc.ViewDimension = D3D11_RTV_DIMENSION_BUFFER; 1086 def_desc.Buffer.ElementWidth = resource->width0; 1087 break; 1088 case PIPE_TEXTURE_1D: 1089 def_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1D; 1090 break; 1091 case PIPE_TEXTURE_1D_ARRAY: 1092 def_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1DARRAY; 1093 def_desc.Texture1DArray.ArraySize = resource->array_size; 1094 break; 1095 case PIPE_TEXTURE_2D: 1096 case PIPE_TEXTURE_RECT: 1097 def_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; 1098 break; 1099 case PIPE_TEXTURE_2D_ARRAY: 1100 def_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; 1101 def_desc.Texture2DArray.ArraySize = resource->array_size; 1102 break; 1103 case PIPE_TEXTURE_3D: 1104 def_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; 1105 def_desc.Texture3D.WSize = resource->depth0; 1106 break; 1107 case PIPE_TEXTURE_CUBE: 1108 def_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; 1109 def_desc.Texture2DArray.ArraySize = 6; 1110 break; 1111 default: 1112 return E_INVALIDARG; 1113 } 1114 desc = &def_desc; 1115 } 1116 1117 struct pipe_surface templat; 1118 memset(&templat, 0, sizeof(templat)); 1119 if(invalid(desc->format >= DXGI_FORMAT_COUNT)) 1120 return E_INVALIDARG; 1121 templat.format = dxgi_to_pipe_format[desc->Format]; 1122 if(!templat.format) 1123 return E_NOTIMPL; 1124 templat.usage = PIPE_BIND_RENDER_TARGET; 1125 templat.texture = ((GalliumD3D11Resource<>*)iresource)->resource; 1126 1127 switch(desc->ViewDimension) 1128 { 1129 case D3D11_RTV_DIMENSION_TEXTURE1D: 1130 case D3D11_RTV_DIMENSION_TEXTURE2D: 1131 templat.u.tex.level = desc->Texture1D.MipSlice; 1132 break; 1133 case D3D11_RTV_DIMENSION_TEXTURE3D: 1134 templat.u.tex.level = desc->Texture3D.MipSlice; 1135 templat.u.tex.first_layer = desc->Texture3D.FirstWSlice; 1136 templat.u.tex.last_layer = desc->Texture3D.FirstWSlice + desc->Texture3D.WSize - 1; 1137 break; 1138 case D3D11_RTV_DIMENSION_TEXTURE1DARRAY: 1139 case D3D11_RTV_DIMENSION_TEXTURE2DARRAY: 1140 templat.u.tex.level = desc->Texture1DArray.MipSlice; 1141 templat.u.tex.first_layer = desc->Texture1DArray.FirstArraySlice; 1142 templat.u.tex.last_layer = desc->Texture1DArray.FirstArraySlice + desc->Texture1DArray.ArraySize - 1; 1143 break; 1144 case D3D11_RTV_DIMENSION_BUFFER: 1145 case D3D11_RTV_DIMENSION_TEXTURE2DMS: 1146 case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY: 1147 return E_NOTIMPL; 1148 default: 1149 return E_INVALIDARG; 1150 } 1151 1152 if(!out_rtv) 1153 return S_FALSE; 1154 1155 struct pipe_surface* surface = immediate_pipe->create_surface(immediate_pipe, templat.texture, &templat); 1156 if(!surface) 1157 return E_FAIL; 1158 *out_rtv = new GalliumD3D11RenderTargetView(this, (GalliumD3D11Resource<>*)iresource, surface, *desc); 1159 return S_OK; 1160 } 1161 1162 virtual HRESULT STDMETHODCALLTYPE CreateDepthStencilView( 1163 ID3D11Resource *iresource, 1164 const D3D11_DEPTH_STENCIL_VIEW_DESC *desc, 1165 ID3D11DepthStencilView **out_depth_stencil_view) 1166 { 1167 SYNCHRONIZED; 1168 1169 D3D11_DEPTH_STENCIL_VIEW_DESC def_desc; 1170 if(!desc) 1171 { 1172 struct pipe_resource* resource = ((GalliumD3D11Resource<>*)iresource)->resource; 1173 init_pipe_to_dxgi_format(); 1174 memset(&def_desc, 0, sizeof(def_desc)); 1175 def_desc.Format = pipe_to_dxgi_format[resource->format]; 1176 switch(resource->target) 1177 { 1178 case PIPE_TEXTURE_1D: 1179 def_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1D; 1180 break; 1181 case PIPE_TEXTURE_1D_ARRAY: 1182 def_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1DARRAY; 1183 def_desc.Texture1DArray.ArraySize = resource->array_size; 1184 break; 1185 case PIPE_TEXTURE_2D: 1186 case PIPE_TEXTURE_RECT: 1187 def_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; 1188 break; 1189 case PIPE_TEXTURE_2D_ARRAY: 1190 def_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; 1191 def_desc.Texture2DArray.ArraySize = resource->array_size; 1192 break; 1193 case PIPE_TEXTURE_CUBE: 1194 def_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; 1195 def_desc.Texture2DArray.ArraySize = 6; 1196 break; 1197 default: 1198 return E_INVALIDARG; 1199 } 1200 desc = &def_desc; 1201 } 1202 1203 struct pipe_surface templat; 1204 memset(&templat, 0, sizeof(templat)); 1205 if(invalid(desc->format >= DXGI_FORMAT_COUNT)) 1206 return E_INVALIDARG; 1207 templat.format = dxgi_to_pipe_format[desc->Format]; 1208 if(!templat.format) 1209 return E_NOTIMPL; 1210 templat.usage = PIPE_BIND_DEPTH_STENCIL; 1211 templat.texture = ((GalliumD3D11Resource<>*)iresource)->resource; 1212 1213 switch(desc->ViewDimension) 1214 { 1215 case D3D11_DSV_DIMENSION_TEXTURE1D: 1216 case D3D11_DSV_DIMENSION_TEXTURE2D: 1217 templat.u.tex.level = desc->Texture1D.MipSlice; 1218 break; 1219 case D3D11_DSV_DIMENSION_TEXTURE1DARRAY: 1220 case D3D11_DSV_DIMENSION_TEXTURE2DARRAY: 1221 templat.u.tex.level = desc->Texture1DArray.MipSlice; 1222 templat.u.tex.first_layer = desc->Texture1DArray.FirstArraySlice; 1223 templat.u.tex.last_layer = desc->Texture1DArray.FirstArraySlice + desc->Texture1DArray.ArraySize - 1; 1224 break; 1225 case D3D11_DSV_DIMENSION_TEXTURE2DMS: 1226 case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY: 1227 return E_NOTIMPL; 1228 default: 1229 return E_INVALIDARG; 1230 } 1231 1232 if(!out_depth_stencil_view) 1233 return S_FALSE; 1234 1235 struct pipe_surface* surface = immediate_pipe->create_surface(immediate_pipe, templat.texture, &templat); 1236 if(!surface) 1237 return E_FAIL; 1238 *out_depth_stencil_view = new GalliumD3D11DepthStencilView(this, (GalliumD3D11Resource<>*)iresource, surface, *desc); 1239 return S_OK; 1240 } 1241 1242 GalliumD3D11Shader<>* create_stage_shader(unsigned type, const void* shader_bytecode, SIZE_T bytecode_length 1243#if API >= 11 1244 , ID3D11ClassLinkage *class_linkage 1245#endif 1246 ) 1247 { 1248 bool dump = debug_get_option_dump_shaders(); 1249 1250 dxbc_chunk_header* sm4_chunk = dxbc_find_shader_bytecode(shader_bytecode, bytecode_length); 1251 if(!sm4_chunk) 1252 return 0; 1253 1254 std::auto_ptr<sm4_program> sm4(sm4_parse(sm4_chunk + 1, bswap_le32(sm4_chunk->size))); 1255 if(!sm4.get()) 1256 return 0; 1257 1258 if(dump) 1259 sm4->dump(); 1260 1261 struct dxbc_chunk_signature* sig; 1262 1263 sig = dxbc_find_signature(shader_bytecode, bytecode_length, DXBC_FIND_INPUT_SIGNATURE); 1264 if(sig) 1265 sm4->num_params_in = dxbc_parse_signature(sig, &sm4->params_in); 1266 1267 sig = dxbc_find_signature(shader_bytecode, bytecode_length, DXBC_FIND_OUTPUT_SIGNATURE); 1268 if(sig) 1269 sm4->num_params_out = dxbc_parse_signature(sig, &sm4->params_out); 1270 1271 sig = dxbc_find_signature(shader_bytecode, bytecode_length, DXBC_FIND_PATCH_SIGNATURE); 1272 if(sig) 1273 sm4->num_params_patch = dxbc_parse_signature(sig, &sm4->params_patch); 1274 1275 struct pipe_shader_state tgsi_shader; 1276 memset(&tgsi_shader, 0, sizeof(tgsi_shader)); 1277 tgsi_shader.tokens = (const tgsi_token*)sm4_to_tgsi(*sm4); 1278 if(!tgsi_shader.tokens) 1279 return 0; 1280 1281 if(dump) 1282 tgsi_dump(tgsi_shader.tokens, 0); 1283 1284 void* shader_cso; 1285 GalliumD3D11Shader<>* shader; 1286 1287 switch(type) 1288 { 1289 case PIPE_SHADER_VERTEX: 1290 shader_cso = immediate_pipe->create_vs_state(immediate_pipe, &tgsi_shader); 1291 shader = (GalliumD3D11Shader<>*)new GalliumD3D11VertexShader(this, shader_cso); 1292 break; 1293 case PIPE_SHADER_FRAGMENT: 1294 shader_cso = immediate_pipe->create_fs_state(immediate_pipe, &tgsi_shader); 1295 shader = (GalliumD3D11Shader<>*)new GalliumD3D11PixelShader(this, shader_cso); 1296 break; 1297 case PIPE_SHADER_GEOMETRY: 1298 shader_cso = immediate_pipe->create_gs_state(immediate_pipe, &tgsi_shader); 1299 shader = (GalliumD3D11Shader<>*)new GalliumD3D11GeometryShader(this, shader_cso); 1300 break; 1301 default: 1302 shader_cso = 0; 1303 shader = 0; 1304 break; 1305 } 1306 1307 free((void*)tgsi_shader.tokens); 1308 return shader; 1309 } 1310 1311#if API >= 11 1312#define CREATE_SHADER_ARGS \ 1313 const void *shader_bytecode, \ 1314 SIZE_T bytecode_length, \ 1315 ID3D11ClassLinkage *class_linkage 1316#define PASS_SHADER_ARGS shader_bytecode, bytecode_length, class_linkage 1317#else 1318#define CREATE_SHADER_ARGS \ 1319 const void *shader_bytecode, \ 1320 SIZE_T bytecode_length 1321#define PASS_SHADER_ARGS shader_bytecode, bytecode_length 1322#endif 1323 1324#define IMPLEMENT_CREATE_SHADER(Stage, GALLIUM) \ 1325 virtual HRESULT STDMETHODCALLTYPE Create##Stage##Shader( \ 1326 CREATE_SHADER_ARGS, \ 1327 ID3D11##Stage##Shader **out_shader) \ 1328 { \ 1329 SYNCHRONIZED; \ 1330 GalliumD3D11##Stage##Shader* shader = (GalliumD3D11##Stage##Shader*)create_stage_shader(PIPE_SHADER_##GALLIUM, PASS_SHADER_ARGS); \ 1331 if(!shader) \ 1332 return E_FAIL; \ 1333 if(out_shader) \ 1334 { \ 1335 *out_shader = shader; \ 1336 return S_OK; \ 1337 } \ 1338 else \ 1339 { \ 1340 shader->Release(); \ 1341 return S_FALSE; \ 1342 } \ 1343 } 1344 1345#define IMPLEMENT_NOTIMPL_CREATE_SHADER(Stage) \ 1346 virtual HRESULT STDMETHODCALLTYPE Create##Stage##Shader( \ 1347 CREATE_SHADER_ARGS, \ 1348 ID3D11##Stage##Shader **out_shader) \ 1349 { \ 1350 return E_NOTIMPL; \ 1351 } 1352 1353 IMPLEMENT_CREATE_SHADER(Vertex, VERTEX) 1354 IMPLEMENT_CREATE_SHADER(Pixel, FRAGMENT) 1355 IMPLEMENT_CREATE_SHADER(Geometry, GEOMETRY) 1356#if API >= 11 1357 IMPLEMENT_NOTIMPL_CREATE_SHADER(Hull) 1358 IMPLEMENT_NOTIMPL_CREATE_SHADER(Domain) 1359 IMPLEMENT_NOTIMPL_CREATE_SHADER(Compute) 1360#endif 1361 1362 virtual HRESULT STDMETHODCALLTYPE CreateGeometryShaderWithStreamOutput( 1363 const void *shader_bytecode, 1364 SIZE_T bytecode_length, 1365 const D3D11_SO_DECLARATION_ENTRY *so_declaration, 1366 unsigned num_entries, 1367#if API >= 11 1368 const unsigned *buffer_strides, 1369 unsigned num_strides, 1370 unsigned rasterized_stream, 1371 ID3D11ClassLinkage *class_linkage, 1372#else 1373 UINT output_stream_stride, 1374#endif 1375 ID3D11GeometryShader **out_geometry_shader) 1376 { 1377 SYNCHRONIZED; 1378 1379 return E_NOTIMPL; 1380 1381 // remember to return S_FALSE if ppGeometyShader == NULL and the shader is OK 1382 } 1383 1384#if API >= 11 1385 virtual HRESULT STDMETHODCALLTYPE CreateClassLinkage( 1386 ID3D11ClassLinkage **out_linkage) 1387 { 1388 SYNCHRONIZED; 1389 1390 return E_NOTIMPL; 1391 } 1392#endif 1393 1394 virtual HRESULT STDMETHODCALLTYPE CreateQuery( 1395 const D3D11_QUERY_DESC *query_desc, 1396 ID3D11Query **out_query) 1397 { 1398 SYNCHRONIZED; 1399 1400 if(invalid(query_desc->Query >= D3D11_QUERY_COUNT)) 1401 return E_INVALIDARG; 1402 unsigned query_type = d3d11_to_pipe_query[query_desc->Query]; 1403 if(query_type >= PIPE_QUERY_TYPES) 1404 return E_NOTIMPL; 1405 1406 if(!out_query) 1407 return S_FALSE; 1408 1409 struct pipe_query* query = immediate_pipe->create_query(immediate_pipe, query_type); 1410 if(!query) 1411 return E_FAIL; 1412 1413 *out_query = new GalliumD3D11Query(this, query, d3d11_query_size[query_desc->Query], *query_desc); 1414 return S_OK; 1415 } 1416 1417 virtual HRESULT STDMETHODCALLTYPE CreatePredicate( 1418 const D3D11_QUERY_DESC *predicate_desc, 1419 ID3D11Predicate **out_predicate) 1420 { 1421 SYNCHRONIZED; 1422 1423 unsigned query_type; 1424 switch(predicate_desc->Query) 1425 { 1426 case D3D11_QUERY_SO_OVERFLOW_PREDICATE: 1427 query_type = PIPE_QUERY_SO_OVERFLOW_PREDICATE; 1428 break; 1429 case D3D11_QUERY_OCCLUSION_PREDICATE: 1430 query_type = PIPE_QUERY_OCCLUSION_PREDICATE; 1431 break; 1432 default: 1433 return E_INVALIDARG; 1434 } 1435 1436 if(out_predicate) 1437 return S_FALSE; 1438 1439 struct pipe_query* query = immediate_pipe->create_query(immediate_pipe, query_type); 1440 if(!query) 1441 return E_FAIL; 1442 1443 *out_predicate = new GalliumD3D11Predicate(this, query, sizeof(BOOL), *predicate_desc); 1444 return S_OK; 1445 } 1446 1447 1448 virtual HRESULT STDMETHODCALLTYPE CreateCounter( 1449 const D3D11_COUNTER_DESC *counter_desc, 1450 ID3D11Counter **out_counter) 1451 { 1452 SYNCHRONIZED; 1453 1454 return E_NOTIMPL; 1455 1456 // remember to return S_FALSE if out_counter == NULL and everything is OK 1457 } 1458 1459#if API >= 11 1460 virtual HRESULT STDMETHODCALLTYPE CreateDeferredContext( 1461 unsigned context_flags, 1462 ID3D11DeviceContext **out_deferred_context) 1463 { 1464 SYNCHRONIZED; 1465 1466 // TODO: this will have to be implemented using a new Gallium util module 1467 return E_NOTIMPL; 1468 1469 // remember to return S_FALSE if out_counter == NULL and everything is OK 1470 } 1471#endif 1472 1473 virtual HRESULT STDMETHODCALLTYPE OpenSharedResource( 1474 HANDLE resource, 1475 REFIID iid, 1476 void **out_resource) 1477 { 1478 SYNCHRONIZED; 1479 1480 // TODO: the problem here is that we need to communicate dimensions somehow 1481 return E_NOTIMPL; 1482 1483 // remember to return S_FALSE if out_counter == NULL and everything is OK 1484#if 0 1485 struct pipe_resou rce templat; 1486 struct winsys_handle handle; 1487 handle.stride = 0; 1488 handle.handle = resource; 1489 handle.type = DRM_API_HANDLE_TYPE_SHARED; 1490 screen->resource_from_handle(screen, &templat, &handle); 1491#endif 1492 } 1493 1494#if API < 11 1495 /* these are documented as "Not implemented". 1496 * According to the UMDDI documentation, they apparently turn on a 1497 * (width + 1) x (height + 1) convolution filter for 1-bit textures. 1498 * Probably nothing uses these, assuming it has ever been implemented anywhere. 1499 */ 1500 void STDMETHODCALLTYPE SetTextFilterSize( 1501 UINT width, 1502 UINT height 1503 ) 1504 {} 1505 1506 virtual void STDMETHODCALLTYPE GetTextFilterSize( 1507 UINT *width, 1508 UINT *height 1509 ) 1510 {} 1511#endif 1512 1513#if API >= 11 1514 virtual void STDMETHODCALLTYPE RestoreGalliumState() 1515 { 1516 GalliumD3D11ImmediateDeviceContext_RestoreGalliumState(immediate_context); 1517 } 1518 1519 virtual void STDMETHODCALLTYPE RestoreGalliumStateBlitOnly() 1520 { 1521 GalliumD3D11ImmediateDeviceContext_RestoreGalliumStateBlitOnly(immediate_context); 1522 } 1523#endif 1524 1525 virtual struct pipe_context* STDMETHODCALLTYPE GetGalliumContext(void) 1526 { 1527 return immediate_pipe; 1528 } 1529 1530#undef SYNCHRONIZED 1531}; 1532