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