1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright 2011 Joakim Sindholt <opensource@zhasha.com> 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 * on the rights to use, copy, modify, merge, publish, distribute, sub 8bf215546Sopenharmony_ci * license, and/or sell copies of the Software, and to permit persons to whom 9bf215546Sopenharmony_ci * the 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 NON-INFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19bf215546Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20bf215546Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21bf215546Sopenharmony_ci * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 22bf215546Sopenharmony_ci 23bf215546Sopenharmony_ci/* XXX: header order is slightly screwy here */ 24bf215546Sopenharmony_ci#include "loader.h" 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci#include "adapter9.h" 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci#include "pipe-loader/pipe_loader.h" 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci#include "pipe/p_screen.h" 31bf215546Sopenharmony_ci#include "pipe/p_state.h" 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_ci#include "target-helpers/drm_helper.h" 34bf215546Sopenharmony_ci#include "target-helpers/sw_helper.h" 35bf215546Sopenharmony_ci#include "frontend/drm_driver.h" 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci#include "d3dadapter/d3dadapter9.h" 38bf215546Sopenharmony_ci#include "d3dadapter/drm.h" 39bf215546Sopenharmony_ci 40bf215546Sopenharmony_ci#include "util/xmlconfig.h" 41bf215546Sopenharmony_ci#include "util/driconf.h" 42bf215546Sopenharmony_ci 43bf215546Sopenharmony_ci#include "drm-uapi/drm.h" 44bf215546Sopenharmony_ci#include <sys/ioctl.h> 45bf215546Sopenharmony_ci#include <fcntl.h> 46bf215546Sopenharmony_ci#include <stdio.h> 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_ci#define DBG_CHANNEL DBG_ADAPTER 49bf215546Sopenharmony_ci 50bf215546Sopenharmony_ci/* On non-x86 archs, Box86 has issues with thread_submit. */ 51bf215546Sopenharmony_ci#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) 52bf215546Sopenharmony_ci#define DEFAULT_THREADSUBMIT true 53bf215546Sopenharmony_ci#else 54bf215546Sopenharmony_ci#define DEFAULT_THREADSUBMIT false 55bf215546Sopenharmony_ci#endif 56bf215546Sopenharmony_ci 57bf215546Sopenharmony_ciconst driOptionDescription __driConfigOptionsNine[] = { 58bf215546Sopenharmony_ci DRI_CONF_SECTION_PERFORMANCE 59bf215546Sopenharmony_ci DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_1) 60bf215546Sopenharmony_ci DRI_CONF_SECTION_END 61bf215546Sopenharmony_ci DRI_CONF_SECTION_NINE 62bf215546Sopenharmony_ci DRI_CONF_NINE_OVERRIDEVENDOR(-1) 63bf215546Sopenharmony_ci DRI_CONF_NINE_THROTTLE(-2) 64bf215546Sopenharmony_ci DRI_CONF_NINE_THREADSUBMIT(DEFAULT_THREADSUBMIT) 65bf215546Sopenharmony_ci DRI_CONF_NINE_ALLOWDISCARDDELAYEDRELEASE(true) 66bf215546Sopenharmony_ci DRI_CONF_NINE_TEARFREEDISCARD(true) 67bf215546Sopenharmony_ci DRI_CONF_NINE_CSMT(-1) 68bf215546Sopenharmony_ci DRI_CONF_NINE_DYNAMICTEXTUREWORKAROUND(true) 69bf215546Sopenharmony_ci DRI_CONF_NINE_SHADERINLINECONSTANTS(false) 70bf215546Sopenharmony_ci DRI_CONF_NINE_SHMEM_LIMIT() 71bf215546Sopenharmony_ci DRI_CONF_NINE_FORCESWRENDERINGONCPU(false) 72bf215546Sopenharmony_ci DRI_CONF_SECTION_END 73bf215546Sopenharmony_ci DRI_CONF_SECTION_DEBUG 74bf215546Sopenharmony_ci DRI_CONF_OVERRIDE_VRAM_SIZE() 75bf215546Sopenharmony_ci DRI_CONF_SECTION_END 76bf215546Sopenharmony_ci}; 77bf215546Sopenharmony_ci 78bf215546Sopenharmony_cistruct fallback_card_config { 79bf215546Sopenharmony_ci const char *name; 80bf215546Sopenharmony_ci unsigned vendor_id; 81bf215546Sopenharmony_ci unsigned device_id; 82bf215546Sopenharmony_ci} fallback_cards[] = { 83bf215546Sopenharmony_ci {"NV124", 0x10de, 0x13C2}, /* NVIDIA GeForce GTX 970 */ 84bf215546Sopenharmony_ci {"HAWAII", 0x1002, 0x67b1}, /* AMD Radeon R9 290 */ 85bf215546Sopenharmony_ci {"Haswell Mobile", 0x8086, 0x13C2}, /* Intel Haswell Mobile */ 86bf215546Sopenharmony_ci {"SVGA3D", 0x15ad, 0x0405}, /* VMware SVGA 3D */ 87bf215546Sopenharmony_ci}; 88bf215546Sopenharmony_ci 89bf215546Sopenharmony_ci/* prototypes */ 90bf215546Sopenharmony_civoid 91bf215546Sopenharmony_cid3d_match_vendor_id( D3DADAPTER_IDENTIFIER9* drvid, 92bf215546Sopenharmony_ci unsigned fallback_ven, 93bf215546Sopenharmony_ci unsigned fallback_dev, 94bf215546Sopenharmony_ci const char* fallback_name ); 95bf215546Sopenharmony_ci 96bf215546Sopenharmony_civoid d3d_fill_driver_version(D3DADAPTER_IDENTIFIER9* drvid); 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_civoid d3d_fill_cardname(D3DADAPTER_IDENTIFIER9* drvid); 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_cistruct d3dadapter9drm_context 101bf215546Sopenharmony_ci{ 102bf215546Sopenharmony_ci struct d3dadapter9_context base; 103bf215546Sopenharmony_ci struct pipe_loader_device *dev, *swdev; 104bf215546Sopenharmony_ci int fd; 105bf215546Sopenharmony_ci}; 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_cistatic void 108bf215546Sopenharmony_cidrm_destroy( struct d3dadapter9_context *ctx ) 109bf215546Sopenharmony_ci{ 110bf215546Sopenharmony_ci struct d3dadapter9drm_context *drm = (struct d3dadapter9drm_context *)ctx; 111bf215546Sopenharmony_ci 112bf215546Sopenharmony_ci if (ctx->ref && ctx->hal != ctx->ref) 113bf215546Sopenharmony_ci ctx->ref->destroy(ctx->ref); 114bf215546Sopenharmony_ci /* because ref is a wrapper around hal, freeing ref frees hal too. */ 115bf215546Sopenharmony_ci else if (ctx->hal) 116bf215546Sopenharmony_ci ctx->hal->destroy(ctx->hal); 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_ci if (drm->swdev && drm->swdev != drm->dev) 119bf215546Sopenharmony_ci pipe_loader_release(&drm->swdev, 1); 120bf215546Sopenharmony_ci if (drm->dev) 121bf215546Sopenharmony_ci pipe_loader_release(&drm->dev, 1); 122bf215546Sopenharmony_ci 123bf215546Sopenharmony_ci close(drm->fd); 124bf215546Sopenharmony_ci FREE(ctx); 125bf215546Sopenharmony_ci} 126bf215546Sopenharmony_ci 127bf215546Sopenharmony_cistatic inline void 128bf215546Sopenharmony_ciget_bus_info( int fd, 129bf215546Sopenharmony_ci DWORD *vendorid, 130bf215546Sopenharmony_ci DWORD *deviceid, 131bf215546Sopenharmony_ci DWORD *subsysid, 132bf215546Sopenharmony_ci DWORD *revision ) 133bf215546Sopenharmony_ci{ 134bf215546Sopenharmony_ci int vid, did; 135bf215546Sopenharmony_ci 136bf215546Sopenharmony_ci if (loader_get_pci_id_for_fd(fd, &vid, &did)) { 137bf215546Sopenharmony_ci DBG("PCI info: vendor=0x%04x, device=0x%04x\n", 138bf215546Sopenharmony_ci vid, did); 139bf215546Sopenharmony_ci *vendorid = vid; 140bf215546Sopenharmony_ci *deviceid = did; 141bf215546Sopenharmony_ci *subsysid = 0; 142bf215546Sopenharmony_ci *revision = 0; 143bf215546Sopenharmony_ci } else { 144bf215546Sopenharmony_ci DBG("Unable to detect card. Faking %s\n", fallback_cards[0].name); 145bf215546Sopenharmony_ci *vendorid = fallback_cards[0].vendor_id; 146bf215546Sopenharmony_ci *deviceid = fallback_cards[0].device_id; 147bf215546Sopenharmony_ci *subsysid = 0; 148bf215546Sopenharmony_ci *revision = 0; 149bf215546Sopenharmony_ci } 150bf215546Sopenharmony_ci} 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_cistatic inline void 153bf215546Sopenharmony_ciread_descriptor( struct d3dadapter9_context *ctx, 154bf215546Sopenharmony_ci int fd, int override_vendorid ) 155bf215546Sopenharmony_ci{ 156bf215546Sopenharmony_ci unsigned i; 157bf215546Sopenharmony_ci BOOL found; 158bf215546Sopenharmony_ci D3DADAPTER_IDENTIFIER9 *drvid = &ctx->identifier; 159bf215546Sopenharmony_ci 160bf215546Sopenharmony_ci memset(drvid, 0, sizeof(*drvid)); 161bf215546Sopenharmony_ci get_bus_info(fd, &drvid->VendorId, &drvid->DeviceId, 162bf215546Sopenharmony_ci &drvid->SubSysId, &drvid->Revision); 163bf215546Sopenharmony_ci snprintf(drvid->DeviceName, sizeof(drvid->DeviceName), 164bf215546Sopenharmony_ci "Gallium 0.4 with %s", ctx->hal->get_vendor(ctx->hal)); 165bf215546Sopenharmony_ci snprintf(drvid->Description, sizeof(drvid->Description), 166bf215546Sopenharmony_ci "%s", ctx->hal->get_name(ctx->hal)); 167bf215546Sopenharmony_ci 168bf215546Sopenharmony_ci if (override_vendorid > 0) { 169bf215546Sopenharmony_ci found = FALSE; 170bf215546Sopenharmony_ci /* fill in device_id and card name for fake vendor */ 171bf215546Sopenharmony_ci for (i = 0; i < sizeof(fallback_cards)/sizeof(fallback_cards[0]); i++) { 172bf215546Sopenharmony_ci if (fallback_cards[i].vendor_id == override_vendorid) { 173bf215546Sopenharmony_ci DBG("Faking card '%s' vendor 0x%04x, device 0x%04x\n", 174bf215546Sopenharmony_ci fallback_cards[i].name, 175bf215546Sopenharmony_ci fallback_cards[i].vendor_id, 176bf215546Sopenharmony_ci fallback_cards[i].device_id); 177bf215546Sopenharmony_ci drvid->VendorId = fallback_cards[i].vendor_id; 178bf215546Sopenharmony_ci drvid->DeviceId = fallback_cards[i].device_id; 179bf215546Sopenharmony_ci snprintf(drvid->Description, sizeof(drvid->Description), 180bf215546Sopenharmony_ci "%s", fallback_cards[i].name); 181bf215546Sopenharmony_ci found = TRUE; 182bf215546Sopenharmony_ci break; 183bf215546Sopenharmony_ci } 184bf215546Sopenharmony_ci } 185bf215546Sopenharmony_ci if (!found) { 186bf215546Sopenharmony_ci DBG("Unknown fake vendor 0x%04x! Using detected vendor !\n", override_vendorid); 187bf215546Sopenharmony_ci } 188bf215546Sopenharmony_ci } 189bf215546Sopenharmony_ci /* choose fall-back vendor if necessary to allow 190bf215546Sopenharmony_ci * the following functions to return sane results */ 191bf215546Sopenharmony_ci d3d_match_vendor_id(drvid, fallback_cards[0].vendor_id, fallback_cards[0].device_id, fallback_cards[0].name); 192bf215546Sopenharmony_ci /* fill in driver name and version info */ 193bf215546Sopenharmony_ci d3d_fill_driver_version(drvid); 194bf215546Sopenharmony_ci /* override Description field with Windows like names */ 195bf215546Sopenharmony_ci d3d_fill_cardname(drvid); 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_ci /* this driver isn't WHQL certified */ 198bf215546Sopenharmony_ci drvid->WHQLLevel = 0; 199bf215546Sopenharmony_ci 200bf215546Sopenharmony_ci /* this value is fixed */ 201bf215546Sopenharmony_ci drvid->DeviceIdentifier.Data1 = 0xaeb2cdd4; 202bf215546Sopenharmony_ci drvid->DeviceIdentifier.Data2 = 0x6e41; 203bf215546Sopenharmony_ci drvid->DeviceIdentifier.Data3 = 0x43ea; 204bf215546Sopenharmony_ci drvid->DeviceIdentifier.Data4[0] = 0x94; 205bf215546Sopenharmony_ci drvid->DeviceIdentifier.Data4[1] = 0x1c; 206bf215546Sopenharmony_ci drvid->DeviceIdentifier.Data4[2] = 0x83; 207bf215546Sopenharmony_ci drvid->DeviceIdentifier.Data4[3] = 0x61; 208bf215546Sopenharmony_ci drvid->DeviceIdentifier.Data4[4] = 0xcc; 209bf215546Sopenharmony_ci drvid->DeviceIdentifier.Data4[5] = 0x76; 210bf215546Sopenharmony_ci drvid->DeviceIdentifier.Data4[6] = 0x07; 211bf215546Sopenharmony_ci drvid->DeviceIdentifier.Data4[7] = 0x81; 212bf215546Sopenharmony_ci} 213bf215546Sopenharmony_ci 214bf215546Sopenharmony_cistatic HRESULT WINAPI 215bf215546Sopenharmony_cidrm_create_adapter( int fd, 216bf215546Sopenharmony_ci ID3DAdapter9 **ppAdapter ) 217bf215546Sopenharmony_ci{ 218bf215546Sopenharmony_ci struct d3dadapter9drm_context *ctx = CALLOC_STRUCT(d3dadapter9drm_context); 219bf215546Sopenharmony_ci HRESULT hr; 220bf215546Sopenharmony_ci bool different_device; 221bf215546Sopenharmony_ci driOptionCache defaultInitOptions; 222bf215546Sopenharmony_ci driOptionCache userInitOptions; 223bf215546Sopenharmony_ci int throttling_value_user = -2; 224bf215546Sopenharmony_ci int override_vendorid = -1; 225bf215546Sopenharmony_ci bool sw_rendering; 226bf215546Sopenharmony_ci 227bf215546Sopenharmony_ci if (!ctx) { return E_OUTOFMEMORY; } 228bf215546Sopenharmony_ci 229bf215546Sopenharmony_ci ctx->base.destroy = drm_destroy; 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_ci /* Although the fd is provided from external source, mesa/nine 232bf215546Sopenharmony_ci * takes ownership of it. */ 233bf215546Sopenharmony_ci fd = loader_get_user_preferred_fd(fd, &different_device); 234bf215546Sopenharmony_ci ctx->fd = fd; 235bf215546Sopenharmony_ci ctx->base.linear_framebuffer = different_device; 236bf215546Sopenharmony_ci 237bf215546Sopenharmony_ci if (!pipe_loader_drm_probe_fd(&ctx->dev, fd)) { 238bf215546Sopenharmony_ci ERR("Failed to probe drm fd %d.\n", fd); 239bf215546Sopenharmony_ci FREE(ctx); 240bf215546Sopenharmony_ci close(fd); 241bf215546Sopenharmony_ci return D3DERR_DRIVERINTERNALERROR; 242bf215546Sopenharmony_ci } 243bf215546Sopenharmony_ci 244bf215546Sopenharmony_ci ctx->base.hal = pipe_loader_create_screen(ctx->dev); 245bf215546Sopenharmony_ci if (!ctx->base.hal) { 246bf215546Sopenharmony_ci ERR("Unable to load requested driver.\n"); 247bf215546Sopenharmony_ci drm_destroy(&ctx->base); 248bf215546Sopenharmony_ci return D3DERR_DRIVERINTERNALERROR; 249bf215546Sopenharmony_ci } 250bf215546Sopenharmony_ci 251bf215546Sopenharmony_ci if (!ctx->base.hal->get_param(ctx->base.hal, PIPE_CAP_DMABUF)) { 252bf215546Sopenharmony_ci ERR("The driver is not capable of dma-buf sharing." 253bf215546Sopenharmony_ci "Abandon to load nine state tracker\n"); 254bf215546Sopenharmony_ci drm_destroy(&ctx->base); 255bf215546Sopenharmony_ci return D3DERR_DRIVERINTERNALERROR; 256bf215546Sopenharmony_ci } 257bf215546Sopenharmony_ci 258bf215546Sopenharmony_ci /* Previously was set to PIPE_CAP_MAX_FRAMES_IN_FLIGHT, 259bf215546Sopenharmony_ci * but the change of value of this cap to 1 seems to cause 260bf215546Sopenharmony_ci * regressions. */ 261bf215546Sopenharmony_ci ctx->base.throttling_value = 2; 262bf215546Sopenharmony_ci ctx->base.throttling = ctx->base.throttling_value > 0; 263bf215546Sopenharmony_ci 264bf215546Sopenharmony_ci driParseOptionInfo(&defaultInitOptions, __driConfigOptionsNine, 265bf215546Sopenharmony_ci ARRAY_SIZE(__driConfigOptionsNine)); 266bf215546Sopenharmony_ci driParseConfigFiles(&userInitOptions, &defaultInitOptions, 0, 267bf215546Sopenharmony_ci "nine", NULL, NULL, NULL, 0, NULL, 0); 268bf215546Sopenharmony_ci if (driCheckOption(&userInitOptions, "throttle_value", DRI_INT)) { 269bf215546Sopenharmony_ci throttling_value_user = driQueryOptioni(&userInitOptions, "throttle_value"); 270bf215546Sopenharmony_ci if (throttling_value_user == -1) 271bf215546Sopenharmony_ci ctx->base.throttling = FALSE; 272bf215546Sopenharmony_ci else if (throttling_value_user >= 0) { 273bf215546Sopenharmony_ci ctx->base.throttling = TRUE; 274bf215546Sopenharmony_ci ctx->base.throttling_value = throttling_value_user; 275bf215546Sopenharmony_ci } 276bf215546Sopenharmony_ci } 277bf215546Sopenharmony_ci 278bf215546Sopenharmony_ci ctx->base.vblank_mode = driQueryOptioni(&userInitOptions, "vblank_mode"); 279bf215546Sopenharmony_ci ctx->base.thread_submit = driQueryOptionb(&userInitOptions, "thread_submit"); /* TODO: default to TRUE if different_device */ 280bf215546Sopenharmony_ci override_vendorid = driQueryOptioni(&userInitOptions, "override_vendorid"); 281bf215546Sopenharmony_ci 282bf215546Sopenharmony_ci ctx->base.discard_delayed_release = driQueryOptionb(&userInitOptions, "discard_delayed_release"); 283bf215546Sopenharmony_ci ctx->base.tearfree_discard = driQueryOptionb(&userInitOptions, "tearfree_discard"); 284bf215546Sopenharmony_ci 285bf215546Sopenharmony_ci if (ctx->base.tearfree_discard && !ctx->base.discard_delayed_release) { 286bf215546Sopenharmony_ci ERR("tearfree_discard requires discard_delayed_release\n"); 287bf215546Sopenharmony_ci ctx->base.tearfree_discard = FALSE; 288bf215546Sopenharmony_ci } 289bf215546Sopenharmony_ci 290bf215546Sopenharmony_ci ctx->base.csmt_force = driQueryOptioni(&userInitOptions, "csmt_force"); 291bf215546Sopenharmony_ci ctx->base.dynamic_texture_workaround = driQueryOptionb(&userInitOptions, "dynamic_texture_workaround"); 292bf215546Sopenharmony_ci ctx->base.shader_inline_constants = driQueryOptionb(&userInitOptions, "shader_inline_constants"); 293bf215546Sopenharmony_ci ctx->base.memfd_virtualsizelimit = driQueryOptioni(&userInitOptions, "texture_memory_limit"); 294bf215546Sopenharmony_ci ctx->base.override_vram_size = driQueryOptioni(&userInitOptions, "override_vram_size"); 295bf215546Sopenharmony_ci sw_rendering = driQueryOptionb(&userInitOptions, "force_sw_rendering_on_cpu"); 296bf215546Sopenharmony_ci 297bf215546Sopenharmony_ci driDestroyOptionCache(&userInitOptions); 298bf215546Sopenharmony_ci driDestroyOptionInfo(&defaultInitOptions); 299bf215546Sopenharmony_ci 300bf215546Sopenharmony_ci sw_rendering |= debug_get_bool_option("D3D_ALWAYS_SOFTWARE", false); 301bf215546Sopenharmony_ci /* wrap it to create a software screen that can share resources */ 302bf215546Sopenharmony_ci if (sw_rendering && pipe_loader_sw_probe_wrapped(&ctx->swdev, ctx->base.hal)) 303bf215546Sopenharmony_ci ctx->base.ref = pipe_loader_create_screen(ctx->swdev); 304bf215546Sopenharmony_ci else { 305bf215546Sopenharmony_ci /* Use the hardware for sw rendering */ 306bf215546Sopenharmony_ci ctx->swdev = ctx->dev; 307bf215546Sopenharmony_ci ctx->base.ref = ctx->base.hal; 308bf215546Sopenharmony_ci } 309bf215546Sopenharmony_ci 310bf215546Sopenharmony_ci /* read out PCI info */ 311bf215546Sopenharmony_ci read_descriptor(&ctx->base, fd, override_vendorid); 312bf215546Sopenharmony_ci 313bf215546Sopenharmony_ci /* create and return new ID3DAdapter9 */ 314bf215546Sopenharmony_ci hr = NineAdapter9_new(&ctx->base, (struct NineAdapter9 **)ppAdapter); 315bf215546Sopenharmony_ci if (FAILED(hr)) { 316bf215546Sopenharmony_ci drm_destroy(&ctx->base); 317bf215546Sopenharmony_ci return hr; 318bf215546Sopenharmony_ci } 319bf215546Sopenharmony_ci 320bf215546Sopenharmony_ci return D3D_OK; 321bf215546Sopenharmony_ci} 322bf215546Sopenharmony_ci 323bf215546Sopenharmony_ciconst struct D3DAdapter9DRM drm9_desc = { 324bf215546Sopenharmony_ci .major_version = D3DADAPTER9DRM_MAJOR, 325bf215546Sopenharmony_ci .minor_version = D3DADAPTER9DRM_MINOR, 326bf215546Sopenharmony_ci .create_adapter = drm_create_adapter 327bf215546Sopenharmony_ci}; 328