1/* 2 * Copyright © Microsoft Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24#include "d3d12_screen.h" 25 26#include "d3d12_bufmgr.h" 27#include "d3d12_compiler.h" 28#include "d3d12_context.h" 29#include "d3d12_debug.h" 30#include "d3d12_fence.h" 31#ifdef HAVE_GALLIUM_D3D12_VIDEO 32#include "d3d12_video_screen.h" 33#endif 34#include "d3d12_format.h" 35#include "d3d12_residency.h" 36#include "d3d12_resource.h" 37#include "d3d12_nir_passes.h" 38 39#include "pipebuffer/pb_bufmgr.h" 40#include "util/debug.h" 41#include "util/u_math.h" 42#include "util/u_memory.h" 43#include "util/u_screen.h" 44#include "util/u_dl.h" 45#include "util/mesa-sha1.h" 46 47#include "nir.h" 48#include "frontend/sw_winsys.h" 49 50#include "nir_to_dxil.h" 51#include "git_sha1.h" 52 53#include <directx/d3d12sdklayers.h> 54 55#include <dxguids/dxguids.h> 56static GUID OpenGLOn12CreatorID = { 0x6bb3cd34, 0x0d19, 0x45ab, 0x97, 0xed, 0xd7, 0x20, 0xba, 0x3d, 0xfc, 0x80 }; 57 58static const struct debug_named_value 59d3d12_debug_options[] = { 60 { "verbose", D3D12_DEBUG_VERBOSE, NULL }, 61 { "blit", D3D12_DEBUG_BLIT, "Trace blit and copy resource calls" }, 62 { "experimental", D3D12_DEBUG_EXPERIMENTAL, "Enable experimental shader models feature" }, 63 { "dxil", D3D12_DEBUG_DXIL, "Dump DXIL during program compile" }, 64 { "disass", D3D12_DEBUG_DISASS, "Dump disassambly of created DXIL shader" }, 65 { "res", D3D12_DEBUG_RESOURCE, "Debug resources" }, 66 { "debuglayer", D3D12_DEBUG_DEBUG_LAYER, "Enable debug layer" }, 67 { "gpuvalidator", D3D12_DEBUG_GPU_VALIDATOR, "Enable GPU validator" }, 68 DEBUG_NAMED_VALUE_END 69}; 70 71DEBUG_GET_ONCE_FLAGS_OPTION(d3d12_debug, "D3D12_DEBUG", d3d12_debug_options, 0) 72 73uint32_t 74d3d12_debug; 75 76enum { 77 HW_VENDOR_AMD = 0x1002, 78 HW_VENDOR_INTEL = 0x8086, 79 HW_VENDOR_MICROSOFT = 0x1414, 80 HW_VENDOR_NVIDIA = 0x10de, 81}; 82 83static const char * 84d3d12_get_vendor(struct pipe_screen *pscreen) 85{ 86 return "Microsoft Corporation"; 87} 88 89static const char * 90d3d12_get_device_vendor(struct pipe_screen *pscreen) 91{ 92 struct d3d12_screen* screen = d3d12_screen(pscreen); 93 94 switch (screen->vendor_id) { 95 case HW_VENDOR_MICROSOFT: 96 return "Microsoft"; 97 case HW_VENDOR_AMD: 98 return "AMD"; 99 case HW_VENDOR_NVIDIA: 100 return "NVIDIA"; 101 case HW_VENDOR_INTEL: 102 return "Intel"; 103 default: 104 return "Unknown"; 105 } 106} 107 108static int 109d3d12_get_video_mem(struct pipe_screen *pscreen) 110{ 111 struct d3d12_screen* screen = d3d12_screen(pscreen); 112 113 return screen->memory_size_megabytes; 114} 115 116static int 117d3d12_get_param(struct pipe_screen *pscreen, enum pipe_cap param) 118{ 119 struct d3d12_screen *screen = d3d12_screen(pscreen); 120 121 switch (param) { 122 case PIPE_CAP_NPOT_TEXTURES: 123 return 1; 124 125 case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: 126 /* D3D12 only supports dual-source blending for a single 127 * render-target. From the D3D11 functional spec (which also defines 128 * this for D3D12): 129 * 130 * "When Dual Source Color Blending is enabled, the Pixel Shader must 131 * have only a single RenderTarget bound, at slot 0, and must output 132 * both o0 and o1. Writing to other outputs (o2, o3 etc.) produces 133 * undefined results for the corresponding RenderTargets, if bound 134 * illegally." 135 * 136 * Source: https://microsoft.github.io/DirectX-Specs/d3d/archive/D3D11_3_FunctionalSpec.htm#17.6%20Dual%20Source%20Color%20Blending 137 */ 138 return 1; 139 140 case PIPE_CAP_ANISOTROPIC_FILTER: 141 return 1; 142 143 case PIPE_CAP_MAX_RENDER_TARGETS: 144 return D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; 145 146 case PIPE_CAP_TEXTURE_SWIZZLE: 147 return 1; 148 149 case PIPE_CAP_MAX_TEXTURE_2D_SIZE: 150 return D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION; 151 152 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: 153 return 11; // D3D12_REQ_TEXTURE3D_U_V_OR_W_DIMENSION == 2^10 154 155 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: 156 return D3D12_REQ_MIP_LEVELS; 157 158 case PIPE_CAP_PRIMITIVE_RESTART: 159 case PIPE_CAP_INDEP_BLEND_ENABLE: 160 case PIPE_CAP_INDEP_BLEND_FUNC: 161 case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD: 162 case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES: 163 case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION: 164 case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY: 165 case PIPE_CAP_RGB_OVERRIDE_DST_ALPHA_BLEND: 166 case PIPE_CAP_MIXED_COLOR_DEPTH_BITS: 167 return 1; 168 169 /* We need to do some lowering that requires a link to the sampler */ 170 case PIPE_CAP_NIR_SAMPLERS_AS_DEREF: 171 return 1; 172 173 case PIPE_CAP_NIR_IMAGES_AS_DEREF: 174 return 1; 175 176 case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: 177 /* Divide by 6 because this also applies to cubemaps */ 178 return D3D12_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION / 6; 179 180 case PIPE_CAP_DEPTH_CLIP_DISABLE: 181 return 1; 182 183 case PIPE_CAP_TGSI_TEXCOORD: 184 return 1; 185 186 case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: 187 return 1; 188 189 case PIPE_CAP_VERTEX_COLOR_UNCLAMPED: 190 return 1; 191 192 case PIPE_CAP_GLSL_FEATURE_LEVEL: 193 return 420; 194 case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY: 195 return 420; 196 case PIPE_CAP_ESSL_FEATURE_LEVEL: 197 return 310; 198 199 case PIPE_CAP_COMPUTE: 200 return 1; 201 202 case PIPE_CAP_TEXTURE_MULTISAMPLE: 203 return 1; 204 205 case PIPE_CAP_CUBE_MAP_ARRAY: 206 return 1; 207 208 case PIPE_CAP_TEXTURE_BUFFER_OBJECTS: 209 return 1; 210 211 case PIPE_CAP_TEXTURE_TRANSFER_MODES: 212 return 0; /* unsure */ 213 214 case PIPE_CAP_ENDIANNESS: 215 return PIPE_ENDIAN_NATIVE; /* unsure */ 216 217 case PIPE_CAP_MAX_VIEWPORTS: 218 return D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; 219 220 case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES: 221 return 1; 222 223 case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS: 224 return 4; 225 226 case PIPE_CAP_FS_COORD_PIXEL_CENTER_HALF_INTEGER: 227 case PIPE_CAP_FS_COORD_ORIGIN_UPPER_LEFT: 228 return 1; 229 230 case PIPE_CAP_FS_FACE_IS_INTEGER_SYSVAL: 231 return 1; 232 233 case PIPE_CAP_ACCELERATED: 234 return screen->vendor_id != HW_VENDOR_MICROSOFT; 235 236 case PIPE_CAP_VIDEO_MEMORY: 237 return d3d12_get_video_mem(pscreen); 238 239 case PIPE_CAP_UMA: 240 return screen->architecture.UMA; 241 242 case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE: 243 return 2048; /* FIXME: no clue how to query this */ 244 245 case PIPE_CAP_TEXTURE_FLOAT_LINEAR: 246 case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR: 247 return 1; 248 249 case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT: 250 return D3D12_RAW_UAV_SRV_BYTE_ALIGNMENT; 251 252 case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: 253 return D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT; 254 255 case PIPE_CAP_PCI_GROUP: 256 case PIPE_CAP_PCI_BUS: 257 case PIPE_CAP_PCI_DEVICE: 258 case PIPE_CAP_PCI_FUNCTION: 259 return 0; /* TODO: figure these out */ 260 261 case PIPE_CAP_FLATSHADE: 262 case PIPE_CAP_ALPHA_TEST: 263 case PIPE_CAP_TWO_SIDED_COLOR: 264 case PIPE_CAP_CLIP_PLANES: 265 return 0; 266 267 case PIPE_CAP_SHADER_STENCIL_EXPORT: 268 return screen->opts.PSSpecifiedStencilRefSupported; 269 270 case PIPE_CAP_SEAMLESS_CUBE_MAP: 271 case PIPE_CAP_TEXTURE_QUERY_LOD: 272 case PIPE_CAP_VS_INSTANCEID: 273 case PIPE_CAP_TGSI_TEX_TXF_LZ: 274 case PIPE_CAP_OCCLUSION_QUERY: 275 case PIPE_CAP_POINT_SPRITE: 276 case PIPE_CAP_VIEWPORT_TRANSFORM_LOWERED: 277 case PIPE_CAP_PSIZ_CLAMPED: 278 case PIPE_CAP_BLEND_EQUATION_SEPARATE: 279 case PIPE_CAP_CONDITIONAL_RENDER: 280 case PIPE_CAP_CONDITIONAL_RENDER_INVERTED: 281 case PIPE_CAP_QUERY_TIMESTAMP: 282 case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: 283 case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY: 284 case PIPE_CAP_IMAGE_STORE_FORMATTED: 285 case PIPE_CAP_GLSL_TESS_LEVELS_AS_INPUTS: 286 return 1; 287 288 case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS: 289 return D3D12_SO_BUFFER_SLOT_COUNT; 290 291 case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS: 292 case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS: 293 return D3D12_SO_OUTPUT_COMPONENT_COUNT; 294 295 /* Geometry shader output. */ 296 case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES: 297 return D3D12_GS_MAX_OUTPUT_VERTEX_COUNT_ACROSS_INSTANCES; 298 case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS: 299 return D3D12_REQ_GS_INVOCATION_32BIT_OUTPUT_COMPONENT_LIMIT; 300 301 case PIPE_CAP_MAX_VARYINGS: 302 /* Subtract one so that implicit position can be added */ 303 return D3D12_PS_INPUT_REGISTER_COUNT - 1; 304 305 case PIPE_CAP_NIR_COMPACT_ARRAYS: 306 return 1; 307 308 case PIPE_CAP_MAX_COMBINED_SHADER_OUTPUT_RESOURCES: 309 if (screen->max_feature_level <= D3D_FEATURE_LEVEL_11_0) 310 return D3D12_PS_CS_UAV_REGISTER_COUNT; 311 if (screen->opts.ResourceBindingTier <= D3D12_RESOURCE_BINDING_TIER_2) 312 return D3D12_UAV_SLOT_COUNT; 313 return 0; 314 315 case PIPE_CAP_START_INSTANCE: 316 case PIPE_CAP_DRAW_PARAMETERS: 317 case PIPE_CAP_DRAW_INDIRECT: 318 case PIPE_CAP_MULTI_DRAW_INDIRECT: 319 case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS: 320 case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT: 321 case PIPE_CAP_SAMPLE_SHADING: 322 case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME: 323 case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS: 324 case PIPE_CAP_INT64: 325 case PIPE_CAP_INT64_DIVMOD: 326 case PIPE_CAP_DOUBLES: 327 case PIPE_CAP_DEVICE_RESET_STATUS_QUERY: 328 case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR: 329 case PIPE_CAP_MEMOBJ: 330 case PIPE_CAP_FENCE_SIGNAL: 331 case PIPE_CAP_TIMELINE_SEMAPHORE_IMPORT: 332 case PIPE_CAP_CLIP_HALFZ: 333 return 1; 334 335 case PIPE_CAP_MAX_VERTEX_STREAMS: 336 return D3D12_SO_BUFFER_SLOT_COUNT; 337 338 case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS: 339 /* This is asking about varyings, not total registers, so remove the 2 tess factor registers. */ 340 return D3D12_HS_OUTPUT_PATCH_CONSTANT_REGISTER_COUNT - 2; 341 342 default: 343 return u_pipe_screen_get_param_defaults(pscreen, param); 344 } 345} 346 347static float 348d3d12_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param) 349{ 350 switch (param) { 351 case PIPE_CAPF_MIN_LINE_WIDTH: 352 case PIPE_CAPF_MIN_LINE_WIDTH_AA: 353 case PIPE_CAPF_MIN_POINT_SIZE: 354 case PIPE_CAPF_MIN_POINT_SIZE_AA: 355 return 1; 356 357 case PIPE_CAPF_POINT_SIZE_GRANULARITY: 358 case PIPE_CAPF_LINE_WIDTH_GRANULARITY: 359 return 0.1; 360 361 case PIPE_CAPF_MAX_LINE_WIDTH: 362 case PIPE_CAPF_MAX_LINE_WIDTH_AA: 363 return 1.0f; /* no clue */ 364 365 case PIPE_CAPF_MAX_POINT_SIZE: 366 case PIPE_CAPF_MAX_POINT_SIZE_AA: 367 return D3D12_MAX_POINT_SIZE; 368 369 case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY: 370 return D3D12_MAX_MAXANISOTROPY; 371 372 case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS: 373 return 15.99f; 374 375 case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE: 376 case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE: 377 case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY: 378 return 0.0f; /* not implemented */ 379 380 default: 381 unreachable("unknown pipe_capf"); 382 } 383 384 return 0.0; 385} 386 387static int 388d3d12_get_shader_param(struct pipe_screen *pscreen, 389 enum pipe_shader_type shader, 390 enum pipe_shader_cap param) 391{ 392 struct d3d12_screen *screen = d3d12_screen(pscreen); 393 394 switch (param) { 395 case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: 396 case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: 397 case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: 398 case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: 399 case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: 400 return INT_MAX; 401 return 0; 402 403 case PIPE_SHADER_CAP_MAX_INPUTS: 404 switch (shader) { 405 case PIPE_SHADER_VERTEX: return D3D12_VS_INPUT_REGISTER_COUNT; 406 case PIPE_SHADER_FRAGMENT: return D3D12_PS_INPUT_REGISTER_COUNT; 407 case PIPE_SHADER_GEOMETRY: return D3D12_GS_INPUT_REGISTER_COUNT; 408 case PIPE_SHADER_TESS_CTRL: return D3D12_HS_CONTROL_POINT_PHASE_INPUT_REGISTER_COUNT; 409 case PIPE_SHADER_TESS_EVAL: return D3D12_DS_INPUT_CONTROL_POINT_REGISTER_COUNT; 410 case PIPE_SHADER_COMPUTE: return 0; 411 default: unreachable("Unexpected shader"); 412 } 413 break; 414 415 case PIPE_SHADER_CAP_MAX_OUTPUTS: 416 switch (shader) { 417 case PIPE_SHADER_VERTEX: return D3D12_VS_OUTPUT_REGISTER_COUNT; 418 case PIPE_SHADER_FRAGMENT: return D3D12_PS_OUTPUT_REGISTER_COUNT; 419 case PIPE_SHADER_GEOMETRY: return D3D12_GS_OUTPUT_REGISTER_COUNT; 420 case PIPE_SHADER_TESS_CTRL: return D3D12_HS_CONTROL_POINT_PHASE_OUTPUT_REGISTER_COUNT; 421 case PIPE_SHADER_TESS_EVAL: return D3D12_DS_OUTPUT_REGISTER_COUNT; 422 case PIPE_SHADER_COMPUTE: return 0; 423 default: unreachable("Unexpected shader"); 424 } 425 break; 426 427 case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: 428 if (screen->opts.ResourceBindingTier == D3D12_RESOURCE_BINDING_TIER_1) 429 return 16; 430 return PIPE_MAX_SAMPLERS; 431 432 case PIPE_SHADER_CAP_MAX_CONST_BUFFER0_SIZE: 433 return 65536; 434 435 case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: 436 return 13; /* 15 - 2 for lowered uniforms and state vars*/ 437 438 case PIPE_SHADER_CAP_MAX_TEMPS: 439 return INT_MAX; 440 441 case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: 442 case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: 443 case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: 444 case PIPE_SHADER_CAP_SUBROUTINES: 445 return 0; /* not implemented */ 446 447 case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: 448 case PIPE_SHADER_CAP_INTEGERS: 449 return 1; 450 451 case PIPE_SHADER_CAP_INT64_ATOMICS: 452 case PIPE_SHADER_CAP_FP16: 453 return 0; /* not implemented */ 454 455 case PIPE_SHADER_CAP_PREFERRED_IR: 456 return PIPE_SHADER_IR_NIR; 457 458 case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED: 459 return 0; /* not implemented */ 460 461 case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS: 462 /* Note: This is wrong, but this is the max value that 463 * TC can support to avoid overflowing an array. 464 */ 465 return PIPE_MAX_SAMPLERS; 466 467 case PIPE_SHADER_CAP_DROUND_SUPPORTED: 468 case PIPE_SHADER_CAP_DFRACEXP_DLDEXP_SUPPORTED: 469 return 0; /* not implemented */ 470 471 case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE: 472 return 0; /* no idea */ 473 474 case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS: 475 return 476 (screen->max_feature_level >= D3D_FEATURE_LEVEL_11_1 || 477 screen->opts.ResourceBindingTier >= D3D12_RESOURCE_BINDING_TIER_3) ? 478 PIPE_MAX_SHADER_BUFFERS : D3D12_PS_CS_UAV_REGISTER_COUNT; 479 480 case PIPE_SHADER_CAP_SUPPORTED_IRS: 481 return 1 << PIPE_SHADER_IR_NIR; 482 483 case PIPE_SHADER_CAP_MAX_SHADER_IMAGES: 484 if (!screen->support_shader_images) 485 return 0; 486 return 487 (screen->max_feature_level >= D3D_FEATURE_LEVEL_11_1 || 488 screen->opts.ResourceBindingTier >= D3D12_RESOURCE_BINDING_TIER_3) ? 489 PIPE_MAX_SHADER_IMAGES : D3D12_PS_CS_UAV_REGISTER_COUNT; 490 491 case PIPE_SHADER_CAP_LDEXP_SUPPORTED: 492 case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS: 493 case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS: 494 case PIPE_SHADER_CAP_CONT_SUPPORTED: 495 return 0; /* not implemented */ 496 497 /* should only get here on unhandled cases */ 498 default: return 0; 499 } 500} 501 502static int 503d3d12_get_compute_param(struct pipe_screen *pscreen, 504 enum pipe_shader_ir ir, 505 enum pipe_compute_cap cap, 506 void *ret) 507{ 508 switch (cap) { 509 case PIPE_COMPUTE_CAP_MAX_GRID_SIZE: { 510 uint64_t *grid = (uint64_t *)ret; 511 grid[0] = grid[1] = grid[2] = D3D12_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION; 512 return sizeof(uint64_t) * 3; 513 } 514 case PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE: { 515 uint64_t *block = (uint64_t *)ret; 516 block[0] = D3D12_CS_THREAD_GROUP_MAX_X; 517 block[1] = D3D12_CS_THREAD_GROUP_MAX_Y; 518 block[2] = D3D12_CS_THREAD_GROUP_MAX_Z; 519 return sizeof(uint64_t) * 3; 520 } 521 case PIPE_COMPUTE_CAP_MAX_VARIABLE_THREADS_PER_BLOCK: 522 case PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK: 523 *(uint64_t *)ret = D3D12_CS_THREAD_GROUP_MAX_THREADS_PER_GROUP; 524 return sizeof(uint64_t); 525 case PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE: 526 *(uint64_t *)ret = D3D12_CS_TGSM_REGISTER_COUNT /*DWORDs*/ * 4; 527 return sizeof(uint64_t); 528 default: 529 return 0; 530 } 531} 532 533static bool 534d3d12_is_format_supported(struct pipe_screen *pscreen, 535 enum pipe_format format, 536 enum pipe_texture_target target, 537 unsigned sample_count, 538 unsigned storage_sample_count, 539 unsigned bind) 540{ 541 struct d3d12_screen *screen = d3d12_screen(pscreen); 542 543 if (MAX2(1, sample_count) != MAX2(1, storage_sample_count)) 544 return false; 545 546 if (target == PIPE_BUFFER) { 547 /* Replace emulated vertex element formats for the tests */ 548 format = d3d12_emulated_vtx_format(format); 549 } else { 550 /* Allow 3-comp 32 bit formats only for BOs (needed for ARB_tbo_rgb32) */ 551 if ((format == PIPE_FORMAT_R32G32B32_FLOAT || 552 format == PIPE_FORMAT_R32G32B32_SINT || 553 format == PIPE_FORMAT_R32G32B32_UINT)) 554 return false; 555 } 556 557 /* Don't advertise alpha/luminance_alpha formats because they can't be used 558 * for render targets (except A8_UNORM) and can't be emulated by R/RG formats. 559 * Let the state tracker choose an RGBA format instead. For YUV formats, we 560 * want the state tracker to lower these to individual planes. */ 561 if (format != PIPE_FORMAT_A8_UNORM && 562 (util_format_is_alpha(format) || 563 util_format_is_luminance_alpha(format) || 564 util_format_is_yuv(format))) 565 return false; 566 567 if (format == PIPE_FORMAT_NONE) { 568 /* For UAV-only rendering, aka ARB_framebuffer_no_attachments */ 569 switch (sample_count) { 570 case 0: 571 case 1: 572 case 4: 573 case 8: 574 case 16: 575 return true; 576 default: 577 return false; 578 } 579 } 580 581 DXGI_FORMAT dxgi_format = d3d12_get_format(format); 582 if (dxgi_format == DXGI_FORMAT_UNKNOWN) 583 return false; 584 585 enum D3D12_FORMAT_SUPPORT1 dim_support = D3D12_FORMAT_SUPPORT1_NONE; 586 switch (target) { 587 case PIPE_TEXTURE_1D: 588 case PIPE_TEXTURE_1D_ARRAY: 589 dim_support = D3D12_FORMAT_SUPPORT1_TEXTURE1D; 590 break; 591 case PIPE_TEXTURE_2D: 592 case PIPE_TEXTURE_RECT: 593 case PIPE_TEXTURE_2D_ARRAY: 594 dim_support = D3D12_FORMAT_SUPPORT1_TEXTURE2D; 595 break; 596 case PIPE_TEXTURE_3D: 597 dim_support = D3D12_FORMAT_SUPPORT1_TEXTURE3D; 598 break; 599 case PIPE_TEXTURE_CUBE: 600 case PIPE_TEXTURE_CUBE_ARRAY: 601 dim_support = D3D12_FORMAT_SUPPORT1_TEXTURECUBE; 602 break; 603 case PIPE_BUFFER: 604 dim_support = D3D12_FORMAT_SUPPORT1_BUFFER; 605 break; 606 default: 607 unreachable("Unknown target"); 608 } 609 610 D3D12_FEATURE_DATA_FORMAT_SUPPORT fmt_info; 611 fmt_info.Format = d3d12_get_resource_rt_format(format); 612 if (FAILED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, 613 &fmt_info, sizeof(fmt_info)))) 614 return false; 615 616 if (!(fmt_info.Support1 & dim_support)) 617 return false; 618 619 if (target == PIPE_BUFFER) { 620 if (bind & PIPE_BIND_VERTEX_BUFFER && 621 !(fmt_info.Support1 & D3D12_FORMAT_SUPPORT1_IA_VERTEX_BUFFER)) 622 return false; 623 624 if (bind & PIPE_BIND_INDEX_BUFFER) { 625 if (format != PIPE_FORMAT_R16_UINT && 626 format != PIPE_FORMAT_R32_UINT) 627 return false; 628 } 629 630 if (sample_count > 0) 631 return false; 632 } else { 633 /* all other targets are texture-targets */ 634 if (bind & PIPE_BIND_RENDER_TARGET && 635 !(fmt_info.Support1 & D3D12_FORMAT_SUPPORT1_RENDER_TARGET)) 636 return false; 637 638 if (bind & PIPE_BIND_BLENDABLE && 639 !(fmt_info.Support1 & D3D12_FORMAT_SUPPORT1_BLENDABLE)) 640 return false; 641 642 if (bind & PIPE_BIND_SHADER_IMAGE && 643 (fmt_info.Support2 & (D3D12_FORMAT_SUPPORT2_UAV_TYPED_LOAD | D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE)) != 644 (D3D12_FORMAT_SUPPORT2_UAV_TYPED_LOAD | D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE)) 645 return false; 646 647 D3D12_FEATURE_DATA_FORMAT_SUPPORT fmt_info_sv; 648 if (util_format_is_depth_or_stencil(format)) { 649 fmt_info_sv.Format = d3d12_get_resource_srv_format(format, target); 650 if (FAILED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, 651 &fmt_info_sv, sizeof(fmt_info_sv)))) 652 return false; 653 } else 654 fmt_info_sv = fmt_info; 655 656#ifdef _WIN32 657 if (bind & PIPE_BIND_DISPLAY_TARGET && 658 (!(fmt_info.Support1 & D3D12_FORMAT_SUPPORT1_DISPLAY) || 659 // Disable formats that don't support flip model 660 dxgi_format == DXGI_FORMAT_B8G8R8X8_UNORM || 661 dxgi_format == DXGI_FORMAT_B5G5R5A1_UNORM || 662 dxgi_format == DXGI_FORMAT_B5G6R5_UNORM || 663 dxgi_format == DXGI_FORMAT_B4G4R4A4_UNORM)) 664 return false; 665#endif 666 667 if (bind & PIPE_BIND_DEPTH_STENCIL && 668 !(fmt_info.Support1 & D3D12_FORMAT_SUPPORT1_DEPTH_STENCIL)) 669 return false; 670 671 if (sample_count > 0) { 672 if (!(fmt_info_sv.Support1 & D3D12_FORMAT_SUPPORT1_MULTISAMPLE_LOAD)) 673 return false; 674 675 if (!util_is_power_of_two_nonzero(sample_count)) 676 return false; 677 678 if (bind & PIPE_BIND_SHADER_IMAGE) 679 return false; 680 681 D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS ms_info = {}; 682 ms_info.Format = dxgi_format; 683 ms_info.SampleCount = sample_count; 684 if (FAILED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, 685 &ms_info, 686 sizeof(ms_info))) || 687 !ms_info.NumQualityLevels) 688 return false; 689 } 690 } 691 return true; 692} 693 694void 695d3d12_deinit_screen(struct d3d12_screen *screen) 696{ 697 if (screen->rtv_pool) { 698 d3d12_descriptor_pool_free(screen->rtv_pool); 699 screen->rtv_pool = nullptr; 700 } 701 if (screen->dsv_pool) { 702 d3d12_descriptor_pool_free(screen->dsv_pool); 703 screen->dsv_pool = nullptr; 704 } 705 if (screen->view_pool) { 706 d3d12_descriptor_pool_free(screen->view_pool); 707 screen->view_pool = nullptr; 708 } 709 if (screen->readback_slab_bufmgr) { 710 screen->readback_slab_bufmgr->destroy(screen->readback_slab_bufmgr); 711 screen->readback_slab_bufmgr = nullptr; 712 } 713 if (screen->slab_bufmgr) { 714 screen->slab_bufmgr->destroy(screen->slab_bufmgr); 715 screen->slab_bufmgr = nullptr; 716 } 717 if (screen->cache_bufmgr) { 718 screen->cache_bufmgr->destroy(screen->cache_bufmgr); 719 screen->cache_bufmgr = nullptr; 720 } 721 if (screen->bufmgr) { 722 screen->bufmgr->destroy(screen->bufmgr); 723 screen->bufmgr = nullptr; 724 } 725 d3d12_deinit_residency(screen); 726 if (screen->fence) { 727 screen->fence->Release(); 728 screen->fence = nullptr; 729 } 730 if (screen->cmdqueue) { 731 screen->cmdqueue->Release(); 732 screen->cmdqueue = nullptr; 733 } 734 if (screen->dev) { 735 screen->dev->Release(); 736 screen->dev = nullptr; 737 } 738} 739 740void 741d3d12_destroy_screen(struct d3d12_screen *screen) 742{ 743 slab_destroy_parent(&screen->transfer_pool); 744 mtx_destroy(&screen->submit_mutex); 745 mtx_destroy(&screen->descriptor_pool_mutex); 746 glsl_type_singleton_decref(); 747 FREE(screen); 748} 749 750static void 751d3d12_flush_frontbuffer(struct pipe_screen * pscreen, 752 struct pipe_context *pctx, 753 struct pipe_resource *pres, 754 unsigned level, unsigned layer, 755 void *winsys_drawable_handle, 756 struct pipe_box *sub_box) 757{ 758 struct d3d12_screen *screen = d3d12_screen(pscreen); 759 struct sw_winsys *winsys = screen->winsys; 760 struct d3d12_resource *res = d3d12_resource(pres); 761 762 if (!winsys || !pctx) 763 return; 764 765 assert(res->dt); 766 void *map = winsys->displaytarget_map(winsys, res->dt, 0); 767 768 if (map) { 769 pctx = threaded_context_unwrap_sync(pctx); 770 pipe_transfer *transfer = nullptr; 771 void *res_map = pipe_texture_map(pctx, pres, level, layer, PIPE_MAP_READ, 0, 0, 772 u_minify(pres->width0, level), 773 u_minify(pres->height0, level), 774 &transfer); 775 if (res_map) { 776 util_copy_rect((ubyte*)map, pres->format, res->dt_stride, 0, 0, 777 transfer->box.width, transfer->box.height, 778 (const ubyte*)res_map, transfer->stride, 0, 0); 779 pipe_texture_unmap(pctx, transfer); 780 } 781 winsys->displaytarget_unmap(winsys, res->dt); 782 } 783 784#ifdef _WIN32 785 // WindowFromDC is Windows-only, and this method requires an HWND, so only use it on Windows 786 ID3D12SharingContract *sharing_contract; 787 if (SUCCEEDED(screen->cmdqueue->QueryInterface(IID_PPV_ARGS(&sharing_contract)))) { 788 ID3D12Resource *d3d12_res = d3d12_resource_resource(res); 789 sharing_contract->Present(d3d12_res, 0, WindowFromDC((HDC)winsys_drawable_handle)); 790 } 791#endif 792 793 winsys->displaytarget_display(winsys, res->dt, winsys_drawable_handle, sub_box); 794} 795 796static ID3D12Debug * 797get_debug_interface() 798{ 799 typedef HRESULT(WINAPI *PFN_D3D12_GET_DEBUG_INTERFACE)(REFIID riid, void **ppFactory); 800 PFN_D3D12_GET_DEBUG_INTERFACE D3D12GetDebugInterface; 801 802 util_dl_library *d3d12_mod = util_dl_open(UTIL_DL_PREFIX "d3d12" UTIL_DL_EXT); 803 if (!d3d12_mod) { 804 debug_printf("D3D12: failed to load D3D12.DLL\n"); 805 return NULL; 806 } 807 808 D3D12GetDebugInterface = (PFN_D3D12_GET_DEBUG_INTERFACE)util_dl_get_proc_address(d3d12_mod, "D3D12GetDebugInterface"); 809 if (!D3D12GetDebugInterface) { 810 debug_printf("D3D12: failed to load D3D12GetDebugInterface from D3D12.DLL\n"); 811 return NULL; 812 } 813 814 ID3D12Debug *debug; 815 if (FAILED(D3D12GetDebugInterface(IID_PPV_ARGS(&debug)))) { 816 debug_printf("D3D12: D3D12GetDebugInterface failed\n"); 817 return NULL; 818 } 819 820 return debug; 821} 822 823static void 824enable_d3d12_debug_layer() 825{ 826 ID3D12Debug *debug = get_debug_interface(); 827 if (debug) { 828 debug->EnableDebugLayer(); 829 debug->Release(); 830 } 831} 832 833static void 834enable_gpu_validation() 835{ 836 ID3D12Debug *debug = get_debug_interface(); 837 ID3D12Debug3 *debug3; 838 if (debug) { 839 if (SUCCEEDED(debug->QueryInterface(IID_PPV_ARGS(&debug3)))) { 840 debug3->SetEnableGPUBasedValidation(true); 841 debug3->Release(); 842 } 843 debug->Release(); 844 } 845} 846 847static ID3D12Device3 * 848create_device(IUnknown *adapter) 849{ 850 typedef HRESULT(WINAPI *PFN_D3D12CREATEDEVICE)(IUnknown*, D3D_FEATURE_LEVEL, REFIID, void**); 851 typedef HRESULT(WINAPI *PFN_D3D12ENABLEEXPERIMENTALFEATURES)(UINT, const IID*, void*, UINT*); 852 PFN_D3D12CREATEDEVICE D3D12CreateDevice; 853 PFN_D3D12ENABLEEXPERIMENTALFEATURES D3D12EnableExperimentalFeatures; 854 855 util_dl_library *d3d12_mod = util_dl_open(UTIL_DL_PREFIX "d3d12" UTIL_DL_EXT); 856 if (!d3d12_mod) { 857 debug_printf("D3D12: failed to load D3D12.DLL\n"); 858 return NULL; 859 } 860 861#ifdef _WIN32 862 if (d3d12_debug & D3D12_DEBUG_EXPERIMENTAL) 863#endif 864 { 865 D3D12EnableExperimentalFeatures = (PFN_D3D12ENABLEEXPERIMENTALFEATURES)util_dl_get_proc_address(d3d12_mod, "D3D12EnableExperimentalFeatures"); 866 if (FAILED(D3D12EnableExperimentalFeatures(1, &D3D12ExperimentalShaderModels, NULL, NULL))) { 867 debug_printf("D3D12: failed to enable experimental shader models\n"); 868 return nullptr; 869 } 870 } 871 872 D3D12CreateDevice = (PFN_D3D12CREATEDEVICE)util_dl_get_proc_address(d3d12_mod, "D3D12CreateDevice"); 873 if (!D3D12CreateDevice) { 874 debug_printf("D3D12: failed to load D3D12CreateDevice from D3D12.DLL\n"); 875 return NULL; 876 } 877 878 ID3D12Device3 *dev; 879 if (SUCCEEDED(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, 880 IID_PPV_ARGS(&dev)))) 881 return dev; 882 883 debug_printf("D3D12: D3D12CreateDevice failed\n"); 884 return NULL; 885} 886 887static bool 888can_attribute_at_vertex(struct d3d12_screen *screen) 889{ 890 switch (screen->vendor_id) { 891 case HW_VENDOR_MICROSOFT: 892 return true; 893 default: 894 return screen->opts3.BarycentricsSupported; 895 } 896} 897 898static bool 899can_shader_image_load_all_formats(struct d3d12_screen *screen) 900{ 901 if (!screen->opts.TypedUAVLoadAdditionalFormats) 902 return false; 903 904 /* All of these are required by ARB_shader_image_load_store */ 905 static const DXGI_FORMAT additional_formats[] = { 906 DXGI_FORMAT_R16G16B16A16_UNORM, 907 DXGI_FORMAT_R16G16B16A16_SNORM, 908 DXGI_FORMAT_R32G32_FLOAT, 909 DXGI_FORMAT_R32G32_UINT, 910 DXGI_FORMAT_R32G32_SINT, 911 DXGI_FORMAT_R10G10B10A2_UNORM, 912 DXGI_FORMAT_R10G10B10A2_UINT, 913 DXGI_FORMAT_R11G11B10_FLOAT, 914 DXGI_FORMAT_R8G8B8A8_SNORM, 915 DXGI_FORMAT_R16G16_FLOAT, 916 DXGI_FORMAT_R16G16_UNORM, 917 DXGI_FORMAT_R16G16_UINT, 918 DXGI_FORMAT_R16G16_SNORM, 919 DXGI_FORMAT_R16G16_SINT, 920 DXGI_FORMAT_R8G8_UNORM, 921 DXGI_FORMAT_R8G8_UINT, 922 DXGI_FORMAT_R8G8_SNORM, 923 DXGI_FORMAT_R8G8_SINT, 924 DXGI_FORMAT_R16_UNORM, 925 DXGI_FORMAT_R16_SNORM, 926 DXGI_FORMAT_R8_SNORM, 927 }; 928 929 for (unsigned i = 0; i < ARRAY_SIZE(additional_formats); ++i) { 930 D3D12_FEATURE_DATA_FORMAT_SUPPORT support = { additional_formats[i] }; 931 if (FAILED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, &support, sizeof(support))) || 932 (support.Support1 & D3D12_FORMAT_SUPPORT1_TYPED_UNORDERED_ACCESS_VIEW) == D3D12_FORMAT_SUPPORT1_NONE || 933 (support.Support2 & (D3D12_FORMAT_SUPPORT2_UAV_TYPED_LOAD | D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE)) != 934 (D3D12_FORMAT_SUPPORT2_UAV_TYPED_LOAD | D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE)) 935 return false; 936 } 937 938 return true; 939} 940 941static void 942d3d12_init_null_srvs(struct d3d12_screen *screen) 943{ 944 for (unsigned i = 0; i < RESOURCE_DIMENSION_COUNT; ++i) { 945 D3D12_SHADER_RESOURCE_VIEW_DESC srv = {}; 946 947 srv.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; 948 srv.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; 949 switch (i) { 950 case RESOURCE_DIMENSION_BUFFER: 951 case RESOURCE_DIMENSION_UNKNOWN: 952 srv.ViewDimension = D3D12_SRV_DIMENSION_BUFFER; 953 srv.Buffer.FirstElement = 0; 954 srv.Buffer.NumElements = 0; 955 srv.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE; 956 srv.Buffer.StructureByteStride = 0; 957 break; 958 case RESOURCE_DIMENSION_TEXTURE1D: 959 srv.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE1D; 960 srv.Texture1D.MipLevels = 1; 961 srv.Texture1D.MostDetailedMip = 0; 962 srv.Texture1D.ResourceMinLODClamp = 0.0f; 963 break; 964 case RESOURCE_DIMENSION_TEXTURE1DARRAY: 965 srv.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE1DARRAY; 966 srv.Texture1DArray.MipLevels = 1; 967 srv.Texture1DArray.ArraySize = 1; 968 srv.Texture1DArray.MostDetailedMip = 0; 969 srv.Texture1DArray.FirstArraySlice = 0; 970 srv.Texture1DArray.ResourceMinLODClamp = 0.0f; 971 break; 972 case RESOURCE_DIMENSION_TEXTURE2D: 973 srv.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; 974 srv.Texture2D.MipLevels = 1; 975 srv.Texture2D.MostDetailedMip = 0; 976 srv.Texture2D.PlaneSlice = 0; 977 srv.Texture2D.ResourceMinLODClamp = 0.0f; 978 break; 979 case RESOURCE_DIMENSION_TEXTURE2DARRAY: 980 srv.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DARRAY; 981 srv.Texture2DArray.MipLevels = 1; 982 srv.Texture2DArray.ArraySize = 1; 983 srv.Texture2DArray.MostDetailedMip = 0; 984 srv.Texture2DArray.FirstArraySlice = 0; 985 srv.Texture2DArray.PlaneSlice = 0; 986 srv.Texture2DArray.ResourceMinLODClamp = 0.0f; 987 break; 988 case RESOURCE_DIMENSION_TEXTURE2DMS: 989 srv.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DMS; 990 break; 991 case RESOURCE_DIMENSION_TEXTURE2DMSARRAY: 992 srv.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY; 993 srv.Texture2DMSArray.ArraySize = 1; 994 srv.Texture2DMSArray.FirstArraySlice = 0; 995 break; 996 case RESOURCE_DIMENSION_TEXTURE3D: 997 srv.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE3D; 998 srv.Texture3D.MipLevels = 1; 999 srv.Texture3D.MostDetailedMip = 0; 1000 srv.Texture3D.ResourceMinLODClamp = 0.0f; 1001 break; 1002 case RESOURCE_DIMENSION_TEXTURECUBE: 1003 srv.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE; 1004 srv.TextureCube.MipLevels = 1; 1005 srv.TextureCube.MostDetailedMip = 0; 1006 srv.TextureCube.ResourceMinLODClamp = 0.0f; 1007 break; 1008 case RESOURCE_DIMENSION_TEXTURECUBEARRAY: 1009 srv.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBEARRAY; 1010 srv.TextureCubeArray.MipLevels = 1; 1011 srv.TextureCubeArray.NumCubes = 1; 1012 srv.TextureCubeArray.MostDetailedMip = 0; 1013 srv.TextureCubeArray.First2DArrayFace = 0; 1014 srv.TextureCubeArray.ResourceMinLODClamp = 0.0f; 1015 break; 1016 } 1017 1018 if (srv.ViewDimension != D3D12_SRV_DIMENSION_UNKNOWN) 1019 { 1020 d3d12_descriptor_pool_alloc_handle(screen->view_pool, &screen->null_srvs[i]); 1021 screen->dev->CreateShaderResourceView(NULL, &srv, screen->null_srvs[i].cpu_handle); 1022 } 1023 } 1024} 1025 1026static void 1027d3d12_init_null_uavs(struct d3d12_screen *screen) 1028{ 1029 for (unsigned i = 0; i < RESOURCE_DIMENSION_COUNT; ++i) { 1030 D3D12_UNORDERED_ACCESS_VIEW_DESC uav = {}; 1031 1032 uav.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; 1033 switch (i) { 1034 case RESOURCE_DIMENSION_BUFFER: 1035 case RESOURCE_DIMENSION_UNKNOWN: 1036 uav.ViewDimension = D3D12_UAV_DIMENSION_BUFFER; 1037 uav.Buffer.FirstElement = 0; 1038 uav.Buffer.NumElements = 0; 1039 uav.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE; 1040 uav.Buffer.StructureByteStride = 0; 1041 uav.Buffer.CounterOffsetInBytes = 0; 1042 break; 1043 case RESOURCE_DIMENSION_TEXTURE1D: 1044 uav.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE1D; 1045 uav.Texture1D.MipSlice = 0; 1046 break; 1047 case RESOURCE_DIMENSION_TEXTURE1DARRAY: 1048 uav.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE1DARRAY; 1049 uav.Texture1DArray.MipSlice = 0; 1050 uav.Texture1DArray.ArraySize = 1; 1051 uav.Texture1DArray.FirstArraySlice = 0; 1052 break; 1053 case RESOURCE_DIMENSION_TEXTURE2D: 1054 uav.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D; 1055 uav.Texture2D.MipSlice = 0; 1056 uav.Texture2D.PlaneSlice = 0; 1057 break; 1058 case RESOURCE_DIMENSION_TEXTURE2DARRAY: 1059 case RESOURCE_DIMENSION_TEXTURECUBE: 1060 case RESOURCE_DIMENSION_TEXTURECUBEARRAY: 1061 uav.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2DARRAY; 1062 uav.Texture2DArray.MipSlice = 0; 1063 uav.Texture2DArray.ArraySize = 1; 1064 uav.Texture2DArray.FirstArraySlice = 0; 1065 uav.Texture2DArray.PlaneSlice = 0; 1066 break; 1067 case RESOURCE_DIMENSION_TEXTURE2DMS: 1068 case RESOURCE_DIMENSION_TEXTURE2DMSARRAY: 1069 break; 1070 case RESOURCE_DIMENSION_TEXTURE3D: 1071 uav.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE3D; 1072 uav.Texture3D.MipSlice = 0; 1073 uav.Texture3D.FirstWSlice = 0; 1074 uav.Texture3D.WSize = 1; 1075 break; 1076 } 1077 1078 if (uav.ViewDimension != D3D12_UAV_DIMENSION_UNKNOWN) 1079 { 1080 d3d12_descriptor_pool_alloc_handle(screen->view_pool, &screen->null_uavs[i]); 1081 screen->dev->CreateUnorderedAccessView(NULL, NULL, &uav, screen->null_uavs[i].cpu_handle); 1082 } 1083 } 1084} 1085 1086static void 1087d3d12_init_null_rtv(struct d3d12_screen *screen) 1088{ 1089 D3D12_RENDER_TARGET_VIEW_DESC rtv = {}; 1090 rtv.Format = DXGI_FORMAT_R8G8B8A8_UNORM; 1091 rtv.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; 1092 rtv.Texture2D.MipSlice = 0; 1093 rtv.Texture2D.PlaneSlice = 0; 1094 d3d12_descriptor_pool_alloc_handle(screen->rtv_pool, &screen->null_rtv); 1095 screen->dev->CreateRenderTargetView(NULL, &rtv, screen->null_rtv.cpu_handle); 1096} 1097 1098static void 1099d3d12_get_adapter_luid(struct pipe_screen *pscreen, char *luid) 1100{ 1101 struct d3d12_screen *screen = d3d12_screen(pscreen); 1102 memcpy(luid, &screen->adapter_luid, PIPE_LUID_SIZE); 1103} 1104 1105static void 1106d3d12_get_device_uuid(struct pipe_screen *pscreen, char *uuid) 1107{ 1108 struct d3d12_screen *screen = d3d12_screen(pscreen); 1109 memcpy(uuid, &screen->device_uuid, PIPE_UUID_SIZE); 1110} 1111 1112static void 1113d3d12_get_driver_uuid(struct pipe_screen *pscreen, char *uuid) 1114{ 1115 struct d3d12_screen *screen = d3d12_screen(pscreen); 1116 memcpy(uuid, &screen->driver_uuid, PIPE_UUID_SIZE); 1117} 1118 1119static uint32_t 1120d3d12_get_node_mask(struct pipe_screen *pscreen) 1121{ 1122 /* This implementation doesn't support linked adapters */ 1123 return 1; 1124} 1125 1126static void 1127d3d12_create_fence_win32(struct pipe_screen *pscreen, struct pipe_fence_handle **pfence, void *handle, const void *name, enum pipe_fd_type type) 1128{ 1129 d3d12_fence_reference((struct d3d12_fence **)pfence, 1130 type == PIPE_FD_TYPE_TIMELINE_SEMAPHORE ? 1131 d3d12_open_fence(d3d12_screen(pscreen), handle, name) : 1132 nullptr); 1133} 1134 1135static void 1136d3d12_set_fence_timeline_value(struct pipe_screen *pscreen, struct pipe_fence_handle *pfence, uint64_t value) 1137{ 1138 d3d12_fence(pfence)->value = value; 1139} 1140 1141void 1142d3d12_init_screen_base(struct d3d12_screen *screen, struct sw_winsys *winsys, LUID *adapter_luid) 1143{ 1144 d3d12_debug = debug_get_option_d3d12_debug(); 1145 1146 screen->winsys = winsys; 1147 if (adapter_luid) 1148 screen->adapter_luid = *adapter_luid; 1149 mtx_init(&screen->descriptor_pool_mutex, mtx_plain); 1150 mtx_init(&screen->submit_mutex, mtx_plain); 1151 1152 list_inithead(&screen->context_list); 1153 1154 screen->base.get_vendor = d3d12_get_vendor; 1155 screen->base.get_device_vendor = d3d12_get_device_vendor; 1156 screen->base.get_param = d3d12_get_param; 1157 screen->base.get_paramf = d3d12_get_paramf; 1158 screen->base.get_shader_param = d3d12_get_shader_param; 1159 screen->base.get_compute_param = d3d12_get_compute_param; 1160 screen->base.is_format_supported = d3d12_is_format_supported; 1161 screen->base.get_compiler_options = d3d12_get_compiler_options; 1162 screen->base.context_create = d3d12_context_create; 1163 screen->base.flush_frontbuffer = d3d12_flush_frontbuffer; 1164 screen->base.get_device_luid = d3d12_get_adapter_luid; 1165 screen->base.get_device_uuid = d3d12_get_device_uuid; 1166 screen->base.get_driver_uuid = d3d12_get_driver_uuid; 1167 screen->base.get_device_node_mask = d3d12_get_node_mask; 1168 screen->base.create_fence_win32 = d3d12_create_fence_win32; 1169 screen->base.set_fence_timeline_value = d3d12_set_fence_timeline_value; 1170} 1171 1172bool 1173d3d12_init_screen(struct d3d12_screen *screen, IUnknown *adapter) 1174{ 1175 assert(screen->base.destroy != nullptr); 1176 1177#ifndef DEBUG 1178 if (d3d12_debug & D3D12_DEBUG_DEBUG_LAYER) 1179#endif 1180 enable_d3d12_debug_layer(); 1181 1182 if (d3d12_debug & D3D12_DEBUG_GPU_VALIDATOR) 1183 enable_gpu_validation(); 1184 1185 screen->dev = create_device(adapter); 1186 1187 if (!screen->dev) { 1188 debug_printf("D3D12: failed to create device\n"); 1189 return false; 1190 } 1191 1192 screen->adapter_luid = GetAdapterLuid(screen->dev); 1193 1194 ID3D12InfoQueue *info_queue; 1195 if (SUCCEEDED(screen->dev->QueryInterface(IID_PPV_ARGS(&info_queue)))) { 1196 D3D12_MESSAGE_SEVERITY severities[] = { 1197 D3D12_MESSAGE_SEVERITY_INFO, 1198 D3D12_MESSAGE_SEVERITY_WARNING, 1199 }; 1200 1201 D3D12_MESSAGE_ID msg_ids[] = { 1202 D3D12_MESSAGE_ID_CLEARRENDERTARGETVIEW_MISMATCHINGCLEARVALUE, 1203 }; 1204 1205 D3D12_INFO_QUEUE_FILTER NewFilter = {}; 1206 NewFilter.DenyList.NumSeverities = ARRAY_SIZE(severities); 1207 NewFilter.DenyList.pSeverityList = severities; 1208 NewFilter.DenyList.NumIDs = ARRAY_SIZE(msg_ids); 1209 NewFilter.DenyList.pIDList = msg_ids; 1210 1211 info_queue->PushStorageFilter(&NewFilter); 1212 info_queue->Release(); 1213 } 1214 1215 if (FAILED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, 1216 &screen->opts, 1217 sizeof(screen->opts)))) { 1218 debug_printf("D3D12: failed to get device options\n"); 1219 return false; 1220 } 1221 if (FAILED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS1, 1222 &screen->opts1, 1223 sizeof(screen->opts1)))) { 1224 debug_printf("D3D12: failed to get device options\n"); 1225 return false; 1226 } 1227 if (FAILED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS2, 1228 &screen->opts2, 1229 sizeof(screen->opts2)))) { 1230 debug_printf("D3D12: failed to get device options\n"); 1231 return false; 1232 } 1233 if (FAILED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS3, 1234 &screen->opts3, 1235 sizeof(screen->opts3)))) { 1236 debug_printf("D3D12: failed to get device options\n"); 1237 return false; 1238 } 1239 if (FAILED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS4, 1240 &screen->opts4, 1241 sizeof(screen->opts4)))) { 1242 debug_printf("D3D12: failed to get device options\n"); 1243 return false; 1244 } 1245 1246 screen->architecture.NodeIndex = 0; 1247 if (FAILED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_ARCHITECTURE, 1248 &screen->architecture, 1249 sizeof(screen->architecture)))) { 1250 debug_printf("D3D12: failed to get device architecture\n"); 1251 return false; 1252 } 1253 1254 D3D12_FEATURE_DATA_FEATURE_LEVELS feature_levels; 1255 static const D3D_FEATURE_LEVEL levels[] = { 1256 D3D_FEATURE_LEVEL_11_0, 1257 D3D_FEATURE_LEVEL_11_1, 1258 D3D_FEATURE_LEVEL_12_0, 1259 D3D_FEATURE_LEVEL_12_1, 1260 }; 1261 feature_levels.NumFeatureLevels = ARRAY_SIZE(levels); 1262 feature_levels.pFeatureLevelsRequested = levels; 1263 if (FAILED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_FEATURE_LEVELS, 1264 &feature_levels, 1265 sizeof(feature_levels)))) { 1266 debug_printf("D3D12: failed to get device feature levels\n"); 1267 return false; 1268 } 1269 screen->max_feature_level = feature_levels.MaxSupportedFeatureLevel; 1270 1271 D3D12_COMMAND_QUEUE_DESC queue_desc; 1272 queue_desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; 1273 queue_desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL; 1274 queue_desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; 1275 queue_desc.NodeMask = 0; 1276 1277 ID3D12Device9 *device9; 1278 if (SUCCEEDED(screen->dev->QueryInterface(&device9))) { 1279 if (FAILED(device9->CreateCommandQueue1(&queue_desc, OpenGLOn12CreatorID, 1280 IID_PPV_ARGS(&screen->cmdqueue)))) 1281 return false; 1282 device9->Release(); 1283 } else { 1284 if (FAILED(screen->dev->CreateCommandQueue(&queue_desc, 1285 IID_PPV_ARGS(&screen->cmdqueue)))) 1286 return false; 1287 } 1288 1289 if (FAILED(screen->dev->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&screen->fence)))) 1290 return false; 1291 1292 if (!d3d12_init_residency(screen)) 1293 return false; 1294 1295 UINT64 timestamp_freq; 1296 if (FAILED(screen->cmdqueue->GetTimestampFrequency(×tamp_freq))) 1297 timestamp_freq = 10000000; 1298 screen->timestamp_multiplier = 1000000000.0 / timestamp_freq; 1299 1300 d3d12_screen_fence_init(&screen->base); 1301 d3d12_screen_resource_init(&screen->base); 1302#ifdef HAVE_GALLIUM_D3D12_VIDEO 1303 d3d12_screen_video_init(&screen->base); 1304#endif 1305 slab_create_parent(&screen->transfer_pool, sizeof(struct d3d12_transfer), 16); 1306 1307 struct pb_desc desc; 1308 desc.alignment = D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT; 1309 desc.usage = (pb_usage_flags)(PB_USAGE_CPU_WRITE | PB_USAGE_GPU_READ); 1310 1311 screen->bufmgr = d3d12_bufmgr_create(screen); 1312 if (!screen->bufmgr) 1313 return false; 1314 1315 screen->cache_bufmgr = pb_cache_manager_create(screen->bufmgr, 0xfffff, 2, 0, 512 * 1024 * 1024); 1316 if (!screen->cache_bufmgr) 1317 return false; 1318 1319 screen->slab_bufmgr = pb_slab_range_manager_create(screen->cache_bufmgr, 16, 1320 D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT, 1321 D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT, 1322 &desc); 1323 if (!screen->slab_bufmgr) 1324 return false; 1325 1326 desc.usage = (pb_usage_flags)(PB_USAGE_CPU_READ_WRITE | PB_USAGE_GPU_WRITE); 1327 screen->readback_slab_bufmgr = pb_slab_range_manager_create(screen->cache_bufmgr, 16, 1328 D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT, 1329 D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT, 1330 &desc); 1331 if (!screen->readback_slab_bufmgr) 1332 return false; 1333 1334 screen->rtv_pool = d3d12_descriptor_pool_new(screen, 1335 D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 1336 64); 1337 screen->dsv_pool = d3d12_descriptor_pool_new(screen, 1338 D3D12_DESCRIPTOR_HEAP_TYPE_DSV, 1339 64); 1340 screen->view_pool = d3d12_descriptor_pool_new(screen, 1341 D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1342 1024); 1343 if (!screen->rtv_pool || !screen->dsv_pool || !screen->view_pool) 1344 return false; 1345 1346 d3d12_init_null_srvs(screen); 1347 d3d12_init_null_uavs(screen); 1348 d3d12_init_null_rtv(screen); 1349 1350 screen->have_load_at_vertex = can_attribute_at_vertex(screen); 1351 screen->support_shader_images = can_shader_image_load_all_formats(screen); 1352 ID3D12Device8 *dev8; 1353 if (SUCCEEDED(screen->dev->QueryInterface(&dev8))) { 1354 dev8->Release(); 1355 screen->support_create_not_resident = true; 1356 } 1357 1358 screen->nir_options = *dxil_get_nir_compiler_options(); 1359 1360 static constexpr uint64_t known_good_warp_version = 10ull << 48 | 22000ull << 16; 1361 if ((screen->vendor_id == HW_VENDOR_MICROSOFT && 1362 screen->driver_version < known_good_warp_version) || 1363 !screen->opts1.Int64ShaderOps) { 1364 /* Work around old versions of WARP that are completely broken for 64bit shifts */ 1365 screen->nir_options.lower_pack_64_2x32_split = false; 1366 screen->nir_options.lower_unpack_64_2x32_split = false; 1367 screen->nir_options.lower_int64_options = (nir_lower_int64_options)~0; 1368 } 1369 1370 if (!screen->opts.DoublePrecisionFloatShaderOps) 1371 screen->nir_options.lower_doubles_options = (nir_lower_doubles_options)~0; 1372 1373 const char *mesa_version = "Mesa " PACKAGE_VERSION MESA_GIT_SHA1; 1374 struct mesa_sha1 sha1_ctx; 1375 uint8_t sha1[SHA1_DIGEST_LENGTH]; 1376 STATIC_ASSERT(PIPE_UUID_SIZE <= sizeof(sha1)); 1377 1378 /* The driver UUID is used for determining sharability of images and memory 1379 * between two instances in separate processes. People who want to 1380 * share memory need to also check the device UUID or LUID so all this 1381 * needs to be is the build-id. 1382 */ 1383 _mesa_sha1_compute(mesa_version, strlen(mesa_version), sha1); 1384 memcpy(screen->driver_uuid, sha1, PIPE_UUID_SIZE); 1385 1386 /* The device UUID uniquely identifies the given device within the machine. */ 1387 _mesa_sha1_init(&sha1_ctx); 1388 _mesa_sha1_update(&sha1_ctx, &screen->vendor_id, sizeof(screen->vendor_id)); 1389 _mesa_sha1_update(&sha1_ctx, &screen->device_id, sizeof(screen->device_id)); 1390 _mesa_sha1_update(&sha1_ctx, &screen->subsys_id, sizeof(screen->subsys_id)); 1391 _mesa_sha1_update(&sha1_ctx, &screen->revision, sizeof(screen->revision)); 1392 _mesa_sha1_final(&sha1_ctx, sha1); 1393 memcpy(screen->device_uuid, sha1, PIPE_UUID_SIZE); 1394 1395 glsl_type_singleton_init_or_ref(); 1396 return true; 1397} 1398