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