diff --git a/include/drm-uapi/d3dkmthk.h b/include/drm-uapi/d3dkmthk.h new file mode 100644 index 0000000000000..db40e8ff40b0b --- /dev/null +++ b/include/drm-uapi/d3dkmthk.h @@ -0,0 +1,1794 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ + +/* + * Copyright (c) 2019, Microsoft Corporation. + * + * Author: + * Iouri Tarassov + * + * Dxgkrnl Graphics Driver + * User mode WDDM interface definitions + * + */ + +#ifndef _D3DKMTHK_H +#define _D3DKMTHK_H + +/* + * This structure matches the definition of D3DKMTHANDLE in Windows. + * The handle is opaque in user mode. It is used by user mode applications to + * represent kernel mode objects, created by dxgkrnl. + */ +struct d3dkmthandle { + union { + struct { + __u32 instance : 6; + __u32 index : 24; + __u32 unique : 2; + }; + __u32 v; + }; +}; + +/* + * VM bus messages return Windows' NTSTATUS, which is integer and only negative + * value indicates a failure. A positive number is a success and needs to be + * returned to user mode as the IOCTL return code. Negative status codes are + * converted to Linux error codes. + */ +struct ntstatus { + union { + struct { + int code : 16; + int facility : 13; + int customer : 1; + int severity : 2; + }; + int v; + }; +}; + +/* + * Matches the Windows LUID definition. + * LUID is a locally unique identifier (similar to GUID, but not global), + * which is guaranteed to be unique intil the computer is rebooted. + */ +struct winluid { + __u32 a; + __u32 b; +}; + +#define D3DDDI_MAX_WRITTEN_PRIMARIES 16 + +#define D3DKMT_CREATEALLOCATION_MAX 1024 +#define D3DKMT_MAKERESIDENT_ALLOC_MAX (1024 * 10) +#define D3DKMT_ADAPTERS_MAX 64 +#define D3DDDI_MAX_BROADCAST_CONTEXT 64 +#define D3DDDI_MAX_OBJECT_WAITED_ON 32 +#define D3DDDI_MAX_OBJECT_SIGNALED 32 + +struct d3dkmt_adapterinfo { + struct d3dkmthandle adapter_handle; + struct winluid adapter_luid; + __u32 num_sources; + __u32 present_move_regions_preferred; +}; + +struct d3dkmt_enumadapters2 { + __u32 num_adapters; + __u32 reserved; +#ifdef __KERNEL__ + struct d3dkmt_adapterinfo *adapters; +#else + __u64 *adapters; +#endif +}; + +struct d3dkmt_closeadapter { + struct d3dkmthandle adapter_handle; +}; + +struct d3dkmt_openadapterfromluid { + struct winluid adapter_luid; + struct d3dkmthandle adapter_handle; +}; + +struct d3dddi_allocationlist { + struct d3dkmthandle allocation; + union { + struct { + __u32 write_operation :1; + __u32 do_not_retire_instance :1; + __u32 offer_priority :3; + __u32 reserved :27; + }; + __u32 value; + }; +}; + +struct d3dddi_patchlocationlist { + __u32 allocation_index; + union { + struct { + __u32 slot_id:24; + __u32 reserved:8; + }; + __u32 value; + }; + __u32 driver_id; + __u32 allocation_offset; + __u32 patch_offset; + __u32 split_offset; +}; + +struct d3dkmt_createdeviceflags { + __u32 legacy_mode:1; + __u32 request_vSync:1; + __u32 disable_gpu_timeout:1; + __u32 gdi_device:1; + __u32 reserved:28; +}; + +struct d3dkmt_createdevice { + struct d3dkmthandle adapter; + __u32 reserved3; + struct d3dkmt_createdeviceflags flags; + struct d3dkmthandle device; +#ifdef __KERNEL__ + void *command_buffer; +#else + __u64 command_buffer; +#endif + __u32 command_buffer_size; + __u32 reserved; +#ifdef __KERNEL__ + struct d3dddi_allocationlist *allocation_list; +#else + __u64 allocation_list; +#endif + __u32 allocation_list_size; + __u32 reserved1; +#ifdef __KERNEL__ + struct d3dddi_patchlocationlist *patch_location_list; +#else + __u64 patch_location_list; +#endif + __u32 patch_location_list_size; + __u32 reserved2; +}; + +struct d3dkmt_destroydevice { + struct d3dkmthandle device; +}; + +enum d3dkmt_clienthint { + _D3DKMT_CLIENTHNT_UNKNOWN = 0, + _D3DKMT_CLIENTHINT_OPENGL = 1, + _D3DKMT_CLIENTHINT_CDD = 2, + _D3DKMT_CLIENTHINT_DX7 = 7, + _D3DKMT_CLIENTHINT_DX8 = 8, + _D3DKMT_CLIENTHINT_DX9 = 9, + _D3DKMT_CLIENTHINT_DX10 = 10, +}; + +struct d3dddi_createcontextflags { + union { + struct { + __u32 null_rendering:1; + __u32 initial_data:1; + __u32 disable_gpu_timeout:1; + __u32 synchronization_only:1; + __u32 hw_queue_supported:1; + __u32 reserved:27; + }; + __u32 value; + }; +}; + +struct d3dkmt_destroycontext { + struct d3dkmthandle context; +}; + +struct d3dkmt_createcontextvirtual { + struct d3dkmthandle device; + __u32 node_ordinal; + __u32 engine_affinity; + struct d3dddi_createcontextflags flags; +#ifdef __KERNEL__ + void *priv_drv_data; +#else + __u64 priv_drv_data; +#endif + __u32 priv_drv_data_size; + enum d3dkmt_clienthint client_hint; + struct d3dkmthandle context; +}; + +struct d3dddi_createhwqueueflags { + union { + struct { + __u32 disable_gpu_timeout:1; + __u32 reserved:31; + }; + __u32 value; + }; +}; + +enum d3dddi_pagingqueue_priority { + _D3DDDI_PAGINGQUEUE_PRIORITY_BELOW_NORMAL = -1, + _D3DDDI_PAGINGQUEUE_PRIORITY_NORMAL = 0, + _D3DDDI_PAGINGQUEUE_PRIORITY_ABOVE_NORMAL = 1, +}; + +struct d3dkmt_createpagingqueue { + struct d3dkmthandle device; + enum d3dddi_pagingqueue_priority priority; + struct d3dkmthandle paging_queue; + struct d3dkmthandle sync_object; +#ifdef __KERNEL__ + void *fence_cpu_virtual_address; +#else + __u64 fence_cpu_virtual_address; +#endif + __u32 physical_adapter_index; +}; + +struct d3dddi_destroypagingqueue { + struct d3dkmthandle paging_queue; +}; + +enum d3dddi_knownescapetype { + _D3DDDI_DRIVERESCAPETYPE_TRANSLATEALLOCATIONHANDLE = 0, + _D3DDDI_DRIVERESCAPETYPE_TRANSLATERESOURCEHANDLE = 1, + _D3DDDI_DRIVERESCAPETYPE_CPUEVENTUSAGE = 2, + _D3DDDI_DRIVERESCAPETYPE_BUILDTESTCOMMANDBUFFER = 3, +}; + +struct d3dddi_translate_allocation_handle { + enum d3dddi_knownescapetype escape_type; + struct d3dkmthandle allocation; +}; + +struct d3dddi_testcommand { + char buffer[72]; +}; + +#define D3DDDI_MAXTESTBUFFERSIZE 4096 +#define D3DDDI_MAXTESTBUFFERPRIVATEDRIVERDATASIZE 1024 + +struct d3dddi_buildtestcommandbuffer { + enum d3dddi_knownescapetype escape_type; + struct d3dkmthandle device; + struct d3dkmthandle context; + __u32 flags; + struct d3dddi_testcommand command; + void *dma_buffer; + void *dma_buffer_priv_data; + __u32 dma_buffer_size; + __u32 dma_buffer_priv_data_size; +}; + +enum d3dkmt_escapetype { + _D3DKMT_ESCAPE_DRIVERPRIVATE = 0, + _D3DKMT_ESCAPE_VIDMM = 1, + _D3DKMT_ESCAPE_VIDSCH = 3, + _D3DKMT_ESCAPE_DEVICE = 4, + _D3DKMT_ESCAPE_DRT_TEST = 8, +}; + +struct d3dddi_escapeflags { + union { + struct { + __u32 hardware_access:1; + __u32 device_status_query:1; + __u32 change_frame_latency:1; + __u32 no_adapter_synchronization:1; + __u32 reserved:1; + __u32 virtual_machine_data:1; + __u32 driver_known_escape:1; + __u32 driver_common_escape:1; + __u32 reserved2:24; + }; + __u32 value; + }; +}; + +struct d3dkmt_escape { + struct d3dkmthandle adapter; + struct d3dkmthandle device; + enum d3dkmt_escapetype type; + struct d3dddi_escapeflags flags; +#ifdef __KERNEL__ + void *priv_drv_data; +#else + __u64 priv_drv_data; +#endif + __u32 priv_drv_data_size; + struct d3dkmthandle context; +}; + +enum dxgk_render_pipeline_stage { + _DXGK_RENDER_PIPELINE_STAGE_UNKNOWN = 0, + _DXGK_RENDER_PIPELINE_STAGE_INPUT_ASSEMBLER = 1, + _DXGK_RENDER_PIPELINE_STAGE_VERTEX_SHADER = 2, + _DXGK_RENDER_PIPELINE_STAGE_GEOMETRY_SHADER = 3, + _DXGK_RENDER_PIPELINE_STAGE_STREAM_OUTPUT = 4, + _DXGK_RENDER_PIPELINE_STAGE_RASTERIZER = 5, + _DXGK_RENDER_PIPELINE_STAGE_PIXEL_SHADER = 6, + _DXGK_RENDER_PIPELINE_STAGE_OUTPUT_MERGER = 7, +}; + +enum dxgk_page_fault_flags { + _DXGK_PAGE_FAULT_WRITE = 0x1, + _DXGK_PAGE_FAULT_FENCE_INVALID = 0x2, + _DXGK_PAGE_FAULT_ADAPTER_RESET_REQUIRED = 0x4, + _DXGK_PAGE_FAULT_ENGINE_RESET_REQUIRED = 0x8, + _DXGK_PAGE_FAULT_FATAL_HARDWARE_ERROR = 0x10, + _DXGK_PAGE_FAULT_IOMMU = 0x20, + _DXGK_PAGE_FAULT_HW_CONTEXT_VALID = 0x40, + _DXGK_PAGE_FAULT_PROCESS_HANDLE_VALID = 0x80, +}; + +enum dxgk_general_error_code { + _DXGK_GENERAL_ERROR_PAGE_FAULT = 0, + _DXGK_GENERAL_ERROR_INVALID_INSTRUCTION = 1, +}; + +struct dxgk_fault_error_code { + union { + struct { + __u32 is_device_specific_code:1; + enum dxgk_general_error_code general_error_code:31; + }; + struct { + __u32 is_device_specific_code_reserved_bit:1; + __u32 device_specific_code:31; + }; + }; +}; + +struct d3dkmt_devicereset_state { + union { + struct { + __u32 desktop_switched:1; + __u32 reserved:31; + }; + __u32 value; + }; +}; + +struct d3dkmt_devicepagefault_state { + __u64 faulted_primitive_api_sequence_number; + enum dxgk_render_pipeline_stage faulted_pipeline_stage; + __u32 faulted_bind_table_entry; + enum dxgk_page_fault_flags page_fault_flags; + struct dxgk_fault_error_code fault_error_code; + __u64 faulted_virtual_address; +}; + +enum d3dkmt_deviceexecution_state { + _D3DKMT_DEVICEEXECUTION_ACTIVE = 1, + _D3DKMT_DEVICEEXECUTION_RESET = 2, + _D3DKMT_DEVICEEXECUTION_HUNG = 3, + _D3DKMT_DEVICEEXECUTION_STOPPED = 4, + _D3DKMT_DEVICEEXECUTION_ERROR_OUTOFMEMORY = 5, + _D3DKMT_DEVICEEXECUTION_ERROR_DMAFAULT = 6, + _D3DKMT_DEVICEEXECUTION_ERROR_DMAPAGEFAULT = 7, +}; + +enum d3dkmt_devicestate_type { + _D3DKMT_DEVICESTATE_EXECUTION = 1, + _D3DKMT_DEVICESTATE_PRESENT = 2, + _D3DKMT_DEVICESTATE_RESET = 3, + _D3DKMT_DEVICESTATE_PRESENT_DWM = 4, + _D3DKMT_DEVICESTATE_PAGE_FAULT = 5, + _D3DKMT_DEVICESTATE_PRESENT_QUEUE = 6, +}; + +struct d3dkmt_getdevicestate { + struct d3dkmthandle device; + enum d3dkmt_devicestate_type state_type; + union { + enum d3dkmt_deviceexecution_state execution_state; + struct d3dkmt_devicereset_state reset_state; + struct d3dkmt_devicepagefault_state page_fault_state; + char alignment[48]; + }; +}; + +enum d3dkmdt_gdisurfacetype { + _D3DKMDT_GDISURFACE_INVALID = 0, + _D3DKMDT_GDISURFACE_TEXTURE = 1, + _D3DKMDT_GDISURFACE_STAGING_CPUVISIBLE = 2, + _D3DKMDT_GDISURFACE_STAGING = 3, + _D3DKMDT_GDISURFACE_LOOKUPTABLE = 4, + _D3DKMDT_GDISURFACE_EXISTINGSYSMEM = 5, + _D3DKMDT_GDISURFACE_TEXTURE_CPUVISIBLE = 6, + _D3DKMDT_GDISURFACE_TEXTURE_CROSSADAPTER = 7, + _D3DKMDT_GDISURFACE_TEXTURE_CPUVISIBLE_CROSSADAPTER = 8, +}; + +struct d3dddi_rational { + __u32 numerator; + __u32 denominator; +}; + +enum d3dddiformat { + _D3DDDIFMT_UNKNOWN = 0, +}; + +struct d3dkmdt_gdisurfacedata { + __u32 width; + __u32 height; + __u32 format; + enum d3dkmdt_gdisurfacetype type; + __u32 flags; + __u32 pitch; +}; + +struct d3dkmdt_stagingsurfacedata { + __u32 width; + __u32 height; + __u32 pitch; +}; + +struct d3dkmdt_sharedprimarysurfacedata { + __u32 width; + __u32 height; + enum d3dddiformat format; + struct d3dddi_rational refresh_rate; + __u32 vidpn_source_id; +}; + +struct d3dkmdt_shadowsurfacedata { + __u32 width; + __u32 height; + enum d3dddiformat format; + __u32 pitch; +}; + +enum d3dkmdt_standardallocationtype { + _D3DKMDT_STANDARDALLOCATION_SHAREDPRIMARYSURFACE = 1, + _D3DKMDT_STANDARDALLOCATION_SHADOWSURFACE = 2, + _D3DKMDT_STANDARDALLOCATION_STAGINGSURFACE = 3, + _D3DKMDT_STANDARDALLOCATION_GDISURFACE = 4, +}; + +struct d3dddi_synchronizationobject_flags { + union { + struct { + __u32 shared:1; + __u32 nt_security_sharing:1; + __u32 cross_adapter:1; + __u32 top_of_pipeline:1; + __u32 no_signal:1; + __u32 no_wait:1; + __u32 no_signal_max_value_on_tdr:1; + __u32 no_gpu_access:1; + __u32 reserved:23; + }; + __u32 value; + }; +}; + +enum d3dddi_synchronizationobject_type { + _D3DDDI_SYNCHRONIZATION_MUTEX = 1, + _D3DDDI_SEMAPHORE = 2, + _D3DDDI_FENCE = 3, + _D3DDDI_CPU_NOTIFICATION = 4, + _D3DDDI_MONITORED_FENCE = 5, + _D3DDDI_PERIODIC_MONITORED_FENCE = 6, + _D3DDDI_SYNCHRONIZATION_TYPE_LIMIT +}; + +struct d3dddi_synchronizationobjectinfo2 { + enum d3dddi_synchronizationobject_type type; + struct d3dddi_synchronizationobject_flags flags; + union { + struct { + __u32 initial_state; + } synchronization_mutex; + + struct { + __u32 max_count; + __u32 initial_count; + } semaphore; + + struct { + __u64 fence_value; + } fence; + + struct { + __u64 event; + } cpu_notification; + + struct { + __u64 initial_fence_value; +#ifdef __KERNEL__ + void *fence_cpu_virtual_address; +#else + __u64 *fence_cpu_virtual_address; +#endif + __u64 fence_gpu_virtual_address; + __u32 engine_affinity; + } monitored_fence; + + struct { + struct d3dkmthandle adapter; + __u32 vidpn_target_id; + __u64 time; +#ifdef __KERNEL__ + void *fence_cpu_virtual_address; +#else + __u64 fence_cpu_virtual_address; +#endif + __u64 fence_gpu_virtual_address; + __u32 engine_affinity; + } periodic_monitored_fence; + + struct { + __u64 reserved[8]; + } reserved; + }; + struct d3dkmthandle shared_handle; +}; + +struct d3dkmt_createsynchronizationobject2 { + struct d3dkmthandle device; + __u32 reserved; + struct d3dddi_synchronizationobjectinfo2 info; + struct d3dkmthandle sync_object; + __u32 reserved1; +}; + +struct d3dkmt_waitforsynchronizationobject2 { + struct d3dkmthandle context; + __u32 object_count; + struct d3dkmthandle object_array[D3DDDI_MAX_OBJECT_WAITED_ON]; + union { + struct { + __u64 fence_value; + } fence; + __u64 reserved[8]; + }; +}; + +struct d3dddicb_signalflags { + union { + struct { + __u32 signal_at_submission:1; + __u32 enqueue_cpu_event:1; + __u32 allow_fence_rewind:1; + __u32 reserved:28; + __u32 DXGK_SIGNAL_FLAG_INTERNAL0:1; + }; + __u32 value; + }; +}; + +struct d3dkmt_signalsynchronizationobject2 { + struct d3dkmthandle context; + __u32 object_count; + struct d3dkmthandle object_array[D3DDDI_MAX_OBJECT_SIGNALED]; + struct d3dddicb_signalflags flags; + __u32 context_count; + struct d3dkmthandle contexts[D3DDDI_MAX_BROADCAST_CONTEXT]; + union { + struct { + __u64 fence_value; + } fence; + __u64 cpu_event_handle; + __u64 reserved[8]; + }; +}; + +struct d3dddi_waitforsynchronizationobjectfromcpu_flags { + union { + struct { + __u32 wait_any:1; + __u32 reserved:31; + }; + __u32 value; + }; +}; + +struct d3dkmt_waitforsynchronizationobjectfromcpu { + struct d3dkmthandle device; + __u32 object_count; +#ifdef __KERNEL__ + struct d3dkmthandle *objects; + __u64 *fence_values; +#else + __u64 objects; + __u64 fence_values; +#endif + __u64 async_event; + struct d3dddi_waitforsynchronizationobjectfromcpu_flags flags; +}; + +struct d3dkmt_signalsynchronizationobjectfromcpu { + struct d3dkmthandle device; + __u32 object_count; +#ifdef __KERNEL__ + struct d3dkmthandle *objects; + __u64 *fence_values; +#else + __u64 objects; + __u64 fence_values; +#endif + struct d3dddicb_signalflags flags; +}; + +struct d3dkmt_waitforsynchronizationobjectfromgpu { + struct d3dkmthandle context; + __u32 object_count; +#ifdef __KERNEL__ + struct d3dkmthandle *objects; +#else + __u64 objects; +#endif + union { +#ifdef __KERNEL__ + __u64 *monitored_fence_values; +#else + __u64 monitored_fence_values; +#endif + __u64 fence_value; + __u64 reserved[8]; + }; +}; + +struct d3dkmt_signalsynchronizationobjectfromgpu { + struct d3dkmthandle context; + __u32 object_count; +#ifdef __KERNEL__ + struct d3dkmthandle *objects; +#else + __u64 objects; +#endif + union { +#ifdef __KERNEL__ + __u64 *monitored_fence_values; +#else + __u64 monitored_fence_values; +#endif + __u64 reserved[8]; + }; +}; + +struct d3dkmt_signalsynchronizationobjectfromgpu2 { + __u32 object_count; + __u32 reserved1; +#ifdef __KERNEL__ + struct d3dkmthandle *objects; +#else + __u64 objects; +#endif + struct d3dddicb_signalflags flags; + __u32 context_count; +#ifdef __KERNEL__ + struct d3dkmthandle *contexts; +#else + __u64 contexts; +#endif + union { + __u64 fence_value; + __u64 cpu_event_handle; +#ifdef __KERNEL__ + __u64 *monitored_fence_values; +#else + __u64 monitored_fence_values; +#endif + __u64 reserved[8]; + }; +}; + +struct d3dkmt_destroysynchronizationobject { + struct d3dkmthandle sync_object; +}; + +struct d3dkmt_submitcommandflags { + __u32 null_rendering:1; + __u32 present_redirected:1; + __u32 reserved:30; +}; + +struct d3dkmt_submitcommand { + __u64 command_buffer; + __u32 command_length; + struct d3dkmt_submitcommandflags flags; + __u64 present_history_token; + __u32 broadcast_context_count; + struct d3dkmthandle broadcast_context[D3DDDI_MAX_BROADCAST_CONTEXT]; + __u32 reserved; +#ifdef __KERNEL__ + void *priv_drv_data; +#else + __u64 priv_drv_data; +#endif + __u32 priv_drv_data_size; + __u32 num_primaries; + struct d3dkmthandle written_primaries[D3DDDI_MAX_WRITTEN_PRIMARIES]; + __u32 num_history_buffers; + __u32 reserved1; +#ifdef __KERNEL__ + struct d3dkmthandle *history_buffer_array; +#else + __u64 history_buffer_array; +#endif +}; + +struct d3dkmt_submitcommandtohwqueue { + struct d3dkmthandle hwqueue; + __u32 reserved; + __u64 hwqueue_progress_fence_id; + __u64 command_buffer; + __u32 command_length; + __u32 priv_drv_data_size; +#ifdef __KERNEL__ + void *priv_drv_data; +#else + __u64 priv_drv_data; +#endif + __u32 num_primaries; + __u32 reserved1; +#ifdef __KERNEL__ + struct d3dkmthandle *written_primaries; +#else + __u64 written_primaries; +#endif +}; + +struct d3dkmt_setcontextschedulingpriority { + struct d3dkmthandle context; + int priority; +}; + +struct d3dkmt_setcontextinprocessschedulingpriority { + struct d3dkmthandle context; + int priority; +}; + +struct d3dkmt_getcontextschedulingpriority { + struct d3dkmthandle context; + int priority; +}; + +struct d3dkmt_getcontextinprocessschedulingpriority { + struct d3dkmthandle context; + int priority; +}; + +struct d3dkmt_setallocationpriority { + struct d3dkmthandle device; + struct d3dkmthandle resource; +#ifdef __KERNEL__ + const struct d3dkmthandle *allocation_list; +#else + __u64 allocation_list; +#endif + __u32 allocation_count; + __u32 reserved; +#ifdef __KERNEL__ + const __u32 *priorities; +#else + __u64 priorities; +#endif +}; + +struct d3dkmt_getallocationpriority { + struct d3dkmthandle device; + struct d3dkmthandle resource; +#ifdef __KERNEL__ + const struct d3dkmthandle *allocation_list; +#else + __u64 allocation_list; +#endif + __u32 allocation_count; + __u32 reserved; +#ifdef __KERNEL__ + __u32 *priorities; +#else + __u64 priorities; +#endif +}; + +enum d3dkmt_allocationresidencystatus { + _D3DKMT_ALLOCATIONRESIDENCYSTATUS_RESIDENTINGPUMEMORY = 1, + _D3DKMT_ALLOCATIONRESIDENCYSTATUS_RESIDENTINSHAREDMEMORY = 2, + _D3DKMT_ALLOCATIONRESIDENCYSTATUS_NOTRESIDENT = 3, +}; + +struct d3dkmt_queryallocationresidency { + struct d3dkmthandle device; + struct d3dkmthandle resource; +#ifdef __KERNEL__ + struct d3dkmthandle *allocations; +#else + __u64 allocations; +#endif + __u32 allocation_count; + __u32 reserved; +#ifdef __KERNEL__ + enum d3dkmt_allocationresidencystatus *residency_status; +#else + __u64 residency_status; +#endif +}; + +struct d3dddicb_lock2flags { + union { + struct { + __u32 reserved:32; + }; + __u32 value; + }; +}; + +struct d3dkmt_lock2 { + struct d3dkmthandle device; + struct d3dkmthandle allocation; + struct d3dddicb_lock2flags flags; + __u32 reserved; +#ifdef __KERNEL__ + void *data; +#else + __u64 data; +#endif +}; + +struct d3dkmt_unlock2 { + struct d3dkmthandle device; + struct d3dkmthandle allocation; +}; + +enum d3dkmt_device_error_reason { + _D3DKMT_DEVICE_ERROR_REASON_GENERIC = 0x80000000, + _D3DKMT_DEVICE_ERROR_REASON_DRIVER_ERROR = 0x80000006, +}; + +struct d3dkmt_markdeviceaserror { + struct d3dkmthandle device; + enum d3dkmt_device_error_reason reason; +}; + +enum d3dkmt_standardallocationtype { + _D3DKMT_STANDARDALLOCATIONTYPE_EXISTINGHEAP = 1, + _D3DKMT_STANDARDALLOCATIONTYPE_CROSSADAPTER = 2, +}; + +struct d3dkmt_standardallocation_existingheap { + __u64 size; +}; + +struct d3dkmt_createstandardallocationflags { + union { + struct { + __u32 reserved:32; + }; + __u32 value; + }; +}; + +struct d3dkmt_createstandardallocation { + enum d3dkmt_standardallocationtype type; + __u32 reserved; + struct d3dkmt_standardallocation_existingheap existing_heap_data; + struct d3dkmt_createstandardallocationflags flags; + __u32 reserved1; +}; + +struct d3dddi_allocationinfo2 { + struct d3dkmthandle allocation; +#ifdef __KERNEL__ + const void *sysmem; +#else + __u64 sysmem; +#endif +#ifdef __KERNEL__ + void *priv_drv_data; +#else + __u64 priv_drv_data; +#endif + __u32 priv_drv_data_size; + __u32 vidpn_source_id; + union { + struct { + __u32 primary:1; + __u32 stereo:1; + __u32 override_priority:1; + __u32 reserved:29; + }; + __u32 value; + } flags; + __u64 gpu_virtual_address; + union { + __u32 priority; + __u64 unused; + }; + __u64 reserved[5]; +}; + +struct d3dkmt_createallocationflags { + union { + struct { + __u32 create_resource:1; + __u32 create_shared:1; + __u32 non_secure:1; + __u32 create_protected:1; + __u32 restrict_shared_access:1; + __u32 existing_sysmem:1; + __u32 nt_security_sharing:1; + __u32 read_only:1; + __u32 create_write_combined:1; + __u32 create_cached:1; + __u32 swap_chain_back_buffer:1; + __u32 cross_adapter:1; + __u32 open_cross_adapter:1; + __u32 partial_shared_creation:1; + __u32 zeroed:1; + __u32 write_watch:1; + __u32 standard_allocation:1; + __u32 existing_section:1; + __u32 reserved:14; + }; + __u32 value; + }; +}; + +struct d3dkmt_createallocation { + struct d3dkmthandle device; + struct d3dkmthandle resource; + struct d3dkmthandle global_share; + __u32 reserved; +#ifdef __KERNEL__ + const void *private_runtime_data; +#else + __u64 private_runtime_data; +#endif + __u32 private_runtime_data_size; + __u32 reserved1; + union { +#ifdef __KERNEL__ + struct d3dkmt_createstandardallocation *standard_allocation; + const void *priv_drv_data; +#else + __u64 standard_allocation; + __u64 priv_drv_data; +#endif + }; + __u32 priv_drv_data_size; + __u32 alloc_count; +#ifdef __KERNEL__ + struct d3dddi_allocationinfo2 *allocation_info; +#else + __u64 allocation_info; +#endif + struct d3dkmt_createallocationflags flags; + __u32 reserved2; + __u64 private_runtime_resource_handle; +}; + +struct d3dddicb_destroyallocation2flags { + union { + struct { + __u32 assume_not_in_use:1; + __u32 synchronous_destroy:1; + __u32 reserved:29; + __u32 system_use_only:1; + }; + __u32 value; + }; +}; + +struct d3dkmt_destroyallocation2 { + struct d3dkmthandle device; + struct d3dkmthandle resource; +#ifdef __KERNEL__ + const struct d3dkmthandle *allocations; +#else + __u64 allocations; +#endif + __u32 alloc_count; + struct d3dddicb_destroyallocation2flags flags; +}; + +struct d3dddi_makeresident_flags { + union { + struct { + __u32 cant_trim_further:1; + __u32 must_succeed:1; + __u32 reserved:30; + }; + __u32 value; + }; +}; + +struct d3dddi_makeresident { + struct d3dkmthandle paging_queue; + __u32 alloc_count; +#ifdef __KERNEL__ + const struct d3dkmthandle *allocation_list; + const __u32 *priority_list; +#else + __u64 allocation_list; + __u64 priority_list; +#endif + struct d3dddi_makeresident_flags flags; + __u64 paging_fence_value; + __u64 num_bytes_to_trim; +}; + +struct d3dddi_evict_flags { + union { + struct { + __u32 evict_only_if_necessary:1; + __u32 not_written_to:1; + __u32 reserved:30; + }; + __u32 value; + }; +}; + +struct d3dkmt_evict { + struct d3dkmthandle device; + __u32 alloc_count; +#ifdef __KERNEL__ + const struct d3dkmthandle *allocations; +#else + __u64 allocations; +#endif + struct d3dddi_evict_flags flags; + __u32 reserved; + __u64 num_bytes_to_trim; +}; + +struct d3dddigpuva_protection_type { + union { + struct { + __u64 write:1; + __u64 execute:1; + __u64 zero:1; + __u64 no_access:1; + __u64 system_use_only:1; + __u64 reserved:59; + }; + __u64 value; + }; +}; + +enum d3dddi_updategpuvirtualaddress_operation_type { + _D3DDDI_UPDATEGPUVIRTUALADDRESS_MAP = 0, + _D3DDDI_UPDATEGPUVIRTUALADDRESS_UNMAP = 1, + _D3DDDI_UPDATEGPUVIRTUALADDRESS_COPY = 2, + _D3DDDI_UPDATEGPUVIRTUALADDRESS_MAP_PROTECT = 3, +}; + +struct d3dddi_updategpuvirtualaddress_operation { + enum d3dddi_updategpuvirtualaddress_operation_type operation; + union { + struct { + __u64 base_address; + __u64 size; + struct d3dkmthandle allocation; + __u64 allocation_offset; + __u64 allocation_size; + } map; + struct { + __u64 base_address; + __u64 size; + struct d3dkmthandle allocation; + __u64 allocation_offset; + __u64 allocation_size; + struct d3dddigpuva_protection_type protection; + __u64 driver_protection; + } map_protect; + struct { + __u64 base_address; + __u64 size; + struct d3dddigpuva_protection_type protection; + } unmap; + struct { + __u64 source_address; + __u64 size; + __u64 dest_address; + } copy; + }; +}; + +enum d3dddigpuva_reservation_type { + _D3DDDIGPUVA_RESERVE_NO_ACCESS = 0, + _D3DDDIGPUVA_RESERVE_ZERO = 1, + _D3DDDIGPUVA_RESERVE_NO_COMMIT = 2 +}; + +struct d3dkmt_updategpuvirtualaddress { + struct d3dkmthandle device; + struct d3dkmthandle context; + struct d3dkmthandle fence_object; + __u32 num_operations; +#ifdef __KERNEL__ + struct d3dddi_updategpuvirtualaddress_operation *operations; +#else + __u64 operations; +#endif + __u32 reserved0; + __u32 reserved1; + __u64 reserved2; + __u64 fence_value; + union { + struct { + __u32 do_not_wait:1; + __u32 reserved:31; + }; + __u32 value; + } flags; + __u32 reserved3; +}; + +struct d3dddi_mapgpuvirtualaddress { + struct d3dkmthandle paging_queue; + __u64 base_address; + __u64 minimum_address; + __u64 maximum_address; + struct d3dkmthandle allocation; + __u64 offset_in_pages; + __u64 size_in_pages; + struct d3dddigpuva_protection_type protection; + __u64 driver_protection; + __u32 reserved0; + __u64 reserved1; + __u64 virtual_address; + __u64 paging_fence_value; +}; + +struct d3dddi_reservegpuvirtualaddress { + struct d3dkmthandle adapter; + __u64 base_address; + __u64 minimum_address; + __u64 maximum_address; + __u64 size; + enum d3dddigpuva_reservation_type reservation_type; + __u64 driver_protection; + __u64 virtual_address; + __u64 paging_fence_value; +}; + +struct d3dkmt_freegpuvirtualaddress { + struct d3dkmthandle adapter; + __u32 reserved; + __u64 base_address; + __u64 size; +}; + +enum d3dkmt_memory_segment_group { + _D3DKMT_MEMORY_SEGMENT_GROUP_LOCAL = 0, + _D3DKMT_MEMORY_SEGMENT_GROUP_NON_LOCAL = 1 +}; + +struct d3dkmt_queryvideomemoryinfo { + __u64 process; + struct d3dkmthandle adapter; + enum d3dkmt_memory_segment_group memory_segment_group; + __u64 budget; + __u64 current_usage; + __u64 current_reservation; + __u64 available_for_reservation; + __u32 physical_adapter_index; +}; + +struct d3dkmt_adaptertype { + union { + struct { + __u32 render_supported:1; + __u32 display_supported:1; + __u32 software_device:1; + __u32 post_device:1; + __u32 hybrid_discrete:1; + __u32 hybrid_integrated:1; + __u32 indirect_display_device:1; + __u32 paravirtualized:1; + __u32 acg_supported:1; + __u32 support_set_timings_from_vidpn:1; + __u32 detachable:1; + __u32 compute_only:1; + __u32 prototype:1; + __u32 reserved:19; + }; + __u32 value; + }; +}; + +enum kmtqueryadapterinfotype { + _KMTQAITYPE_UMDRIVERPRIVATE = 0, + _KMTQAITYPE_ADAPTERTYPE = 15, + _KMTQAITYPE_ADAPTERTYPE_RENDER = 57 +}; + +struct d3dkmt_queryadapterinfo { + struct d3dkmthandle adapter; + enum kmtqueryadapterinfotype type; +#ifdef __KERNEL__ + void *private_data; +#else + __u64 private_data; +#endif + __u32 private_data_size; +}; + +#pragma pack(push, 1) + +struct dxgk_gpuclockdata_flags { + union { + struct { + __u32 context_management_processor:1; + __u32 reserved:31; + }; + __u32 value; + }; +}; + +struct dxgk_gpuclockdata { + __u64 gpu_frequency; + __u64 gpu_clock_counter; + __u64 cpu_clock_counter; + struct dxgk_gpuclockdata_flags flags; +} __packed; + +struct d3dkmt_queryclockcalibration { + struct d3dkmthandle adapter; + __u32 node_ordinal; + __u32 physical_adapter_index; + struct dxgk_gpuclockdata clock_data; +}; + +#pragma pack(pop) + +struct d3dkmt_flushheaptransitions { + struct d3dkmthandle adapter; +}; + +struct d3dddi_openallocationinfo2 { + struct d3dkmthandle allocation; +#ifdef __KERNEL__ + void *priv_drv_data; +#else + __u64 priv_drv_data; +#endif + __u32 priv_drv_data_size; + __u64 gpu_va; + __u64 reserved[6]; +}; + +struct d3dddi_updateallocproperty_flags { + union { + struct { + __u32 accessed_physically:1; + __u32 reserved:31; + }; + __u32 value; + }; +}; + +struct d3dddi_segmentpreference { + union { + struct { + __u32 segment_id0:5; + __u32 direction0:1; + __u32 segment_id1:5; + __u32 direction1:1; + __u32 segment_id2:5; + __u32 direction2:1; + __u32 segment_id3:5; + __u32 direction3:1; + __u32 segment_id4:5; + __u32 direction4:1; + __u32 reserved:2; + }; + __u32 value; + }; +}; + +struct d3dddi_updateallocproperty { + struct d3dkmthandle paging_queue; + struct d3dkmthandle allocation; + __u32 supported_segment_set; + struct d3dddi_segmentpreference preferred_segment; + struct d3dddi_updateallocproperty_flags flags; + __u64 paging_fence_value; + union { + struct { + __u32 set_accessed_physically:1; + __u32 set_supported_segmentSet:1; + __u32 set_preferred_segment:1; + __u32 reserved:29; + }; + __u32 property_mask_value; + }; +}; + +enum d3dkmt_offer_priority { + _D3DKMT_OFFER_PRIORITY_LOW = 1, + _D3DKMT_OFFER_PRIORITY_NORMAL = 2, + _D3DKMT_OFFER_PRIORITY_HIGH = 3, + _D3DKMT_OFFER_PRIORITY_AUTO = 4, +}; + +struct d3dkmt_offer_flags { + union { + struct { + __u32 offer_immediately:1; + __u32 allow_decommit:1; + __u32 reserved:30; + }; + __u32 value; + }; +}; + +struct d3dkmt_offerallocations { + struct d3dkmthandle device; + __u32 reserved; +#ifdef __KERNEL__ + struct d3dkmthandle *resources; + const struct d3dkmthandle *allocations; +#else + __u64 resources; + __u64 allocations; +#endif + __u32 allocation_count; + enum d3dkmt_offer_priority priority; + struct d3dkmt_offer_flags flags; + __u32 reserved1; +}; + +enum d3dddi_reclaim_result { + _D3DDDI_RECLAIM_RESULT_OK = 0, + _D3DDDI_RECLAIM_RESULT_DISCARDED = 1, + _D3DDDI_RECLAIM_RESULT_NOT_COMMITTED = 2, +}; + +struct d3dkmt_reclaimallocations2 { + struct d3dkmthandle paging_queue; + __u32 allocation_count; +#ifdef __KERNEL__ + struct d3dkmthandle *resources; + struct d3dkmthandle *allocations; +#else + __u64 resources; + __u64 allocations; +#endif + union { +#ifdef __KERNEL__ + __u32 *discarded; + enum d3dddi_reclaim_result *results; +#else + __u64 discarded; + __u64 results; +#endif + }; + __u64 paging_fence_value; +}; + +struct d3dkmt_changevideomemoryreservation { + __u64 process; + struct d3dkmthandle adapter; + enum d3dkmt_memory_segment_group memory_segment_group; + __u64 reservation; + __u32 physical_adapter_index; +}; + +struct d3dkmt_createhwqueue { + struct d3dkmthandle context; + struct d3dddi_createhwqueueflags flags; + __u32 priv_drv_data_size; + __u32 reserved; +#ifdef __KERNEL__ + void *priv_drv_data; +#else + __u64 priv_drv_data; +#endif + struct d3dkmthandle queue; + struct d3dkmthandle queue_progress_fence; +#ifdef __KERNEL__ + void *queue_progress_fence_cpu_va; +#else + __u64 queue_progress_fence_cpu_va; +#endif + __u64 queue_progress_fence_gpu_va; +}; + +struct d3dkmt_destroyhwqueue { + struct d3dkmthandle queue; +}; + +struct d3dkmt_submitwaitforsyncobjectstohwqueue { + struct d3dkmthandle hwqueue; + __u32 object_count; +#ifdef __KERNEL__ + struct d3dkmthandle *objects; + __u64 *fence_values; +#else + __u64 objects; + __u64 fence_values; +#endif +}; + +struct d3dkmt_submitsignalsyncobjectstohwqueue { + struct d3dddicb_signalflags flags; + __u32 hwqueue_count; +#ifdef __KERNEL__ + struct d3dkmthandle *hwqueues; +#else + __u64 hwqueues; +#endif + __u32 object_count; + __u32 reserved; +#ifdef __KERNEL__ + struct d3dkmthandle *objects; + __u64 *fence_values; +#else + __u64 objects; + __u64 fence_values; +#endif +}; + +struct d3dkmt_opensyncobjectfromnthandle2 { + __u64 nt_handle; + struct d3dkmthandle device; + struct d3dddi_synchronizationobject_flags flags; + struct d3dkmthandle sync_object; + __u32 reserved1; + union { + struct { +#ifdef __KERNEL__ + void *fence_value_cpu_va; +#else + __u64 fence_value_cpu_va; +#endif + __u64 fence_value_gpu_va; + __u32 engine_affinity; + } monitored_fence; + __u64 reserved[8]; + }; +}; + +struct d3dkmt_openresourcefromnthandle { + struct d3dkmthandle device; + __u32 reserved; + __u64 nt_handle; + __u32 allocation_count; + __u32 reserved1; +#ifdef __KERNEL__ + struct d3dddi_openallocationinfo2 *open_alloc_info; +#else + __u64 open_alloc_info; +#endif + int private_runtime_data_size; + __u32 reserved2; +#ifdef __KERNEL__ + void *private_runtime_data; +#else + __u64 private_runtime_data; +#endif + __u32 resource_priv_drv_data_size; + __u32 reserved3; +#ifdef __KERNEL__ + void *resource_priv_drv_data; +#else + __u64 resource_priv_drv_data; +#endif + __u32 total_priv_drv_data_size; +#ifdef __KERNEL__ + void *total_priv_drv_data; +#else + __u64 total_priv_drv_data; +#endif + struct d3dkmthandle resource; + struct d3dkmthandle keyed_mutex; +#ifdef __KERNEL__ + void *keyed_mutex_private_data; +#else + __u64 keyed_mutex_private_data; +#endif + __u32 keyed_mutex_private_data_size; + struct d3dkmthandle sync_object; +}; + +struct d3dkmt_queryresourceinfofromnthandle { + struct d3dkmthandle device; + __u32 reserved; + __u64 nt_handle; +#ifdef __KERNEL__ + void *private_runtime_data; +#else + __u64 private_runtime_data; +#endif + __u32 private_runtime_data_size; + __u32 total_priv_drv_data_size; + __u32 resource_priv_drv_data_size; + __u32 allocation_count; +}; + +struct d3dkmt_shareobjects { + __u32 object_count; + __u32 reserved; +#ifdef __KERNEL__ + const struct d3dkmthandle *objects; + void *object_attr; /* security attributes */ +#else + __u64 objects; + __u64 object_attr; +#endif + __u32 desired_access; + __u32 reserved1; +#ifdef __KERNEL__ + __u64 *shared_handle; /* output file descriptors */ +#else + __u64 shared_handle; +#endif +}; + +union d3dkmt_enumadapters_filter { + struct { + __u64 include_compute_only:1; + __u64 include_display_only:1; + __u64 reserved:62; + }; + __u64 value; +}; + +struct d3dkmt_enumadapters3 { + union d3dkmt_enumadapters_filter filter; + __u32 adapter_count; + __u32 reserved; +#ifdef __KERNEL__ + struct d3dkmt_adapterinfo *adapters; +#else + __u64 adapters; +#endif +}; + +enum d3dkmt_querystatistics_type { + _D3DKMT_QUERYSTATISTICS_ADAPTER = 0, + _D3DKMT_QUERYSTATISTICS_PROCESS = 1, + _D3DKMT_QUERYSTATISTICS_PROCESS_ADAPTER = 2, + _D3DKMT_QUERYSTATISTICS_SEGMENT = 3, + _D3DKMT_QUERYSTATISTICS_PROCESS_SEGMENT = 4, + _D3DKMT_QUERYSTATISTICS_NODE = 5, + _D3DKMT_QUERYSTATISTICS_PROCESS_NODE = 6, + _D3DKMT_QUERYSTATISTICS_VIDPNSOURCE = 7, + _D3DKMT_QUERYSTATISTICS_PROCESS_VIDPNSOURCE = 8, + _D3DKMT_QUERYSTATISTICS_PROCESS_SEGMENT_GROUP = 9, + _D3DKMT_QUERYSTATISTICS_PHYSICAL_ADAPTER = 10, +}; + +struct d3dkmt_querystatistics_result { + char size[0x308]; +}; + +struct d3dkmt_querystatistics { + union { + struct { + enum d3dkmt_querystatistics_type type; + struct winluid adapter_luid; + __u64 process; + struct d3dkmt_querystatistics_result result; + }; + char size[0x328]; + }; +}; + +struct d3dkmt_shareobjectwithhost { + struct d3dkmthandle device_handle; + struct d3dkmthandle object_handle; + __u64 reserved; + __u64 object_vail_nt_handle; +}; + +struct d3dkmt_createsyncfile { + struct d3dkmthandle device; + struct d3dkmthandle monitored_fence; + __u64 fence_value; + __u64 sync_file_handle; /* out */ +}; + +struct d3dkmt_waitsyncfile { + __u64 sync_file_handle; + struct d3dkmthandle context; + __u32 reserved; +}; + +struct d3dkmt_opensyncobjectfromsyncfile { + __u64 sync_file_handle; + struct d3dkmthandle device; + struct d3dkmthandle syncobj; /* out */ + __u64 fence_value; /* out */ +#ifdef __KERNEL__ + void *fence_value_cpu_va; /* out */ +#else + __u64 fence_value_cpu_va; /* out */ +#endif + __u64 fence_value_gpu_va; /* out */ +}; + +struct d3dkmt_enumprocesses { + struct winluid adapter_luid; +#ifdef __KERNEL__ + __u32 *buffer; +#else + __u64 buffer; +#endif + __u64 buffer_count; +}; + +enum dxgk_feature_id { + _DXGK_FEATURE_HWSCH = 0, + _DXGK_FEATURE_PAGE_BASED_MEMORY_MANAGER = 32, + _DXGK_FEATURE_KERNEL_MODE_TESTING = 33, + _DXGK_FEATURE_MAX +}; + +struct dxgk_isfeatureenabled_result { + __u16 version; + union { + struct { + __u16 enabled : 1; + __u16 known_feature : 1; + __u16 supported_by_driver : 1; + __u16 supported_on_config : 1; + __u16 reserved : 12; + }; + __u16 value; + }; +}; + +struct d3dkmt_isfeatureenabled { + struct d3dkmthandle adapter; + enum dxgk_feature_id feature_id; + struct dxgk_isfeatureenabled_result result; +}; + +struct d3dkmt_invalidatecache { + struct d3dkmthandle device; + struct d3dkmthandle allocation; + __u64 offset; + __u64 length; +}; + +/* + * Dxgkrnl Graphics Port Driver ioctl definitions + * + */ + +#define LX_DXOPENADAPTERFROMLUID \ + _IOWR(0x47, 0x01, struct d3dkmt_openadapterfromluid) +#define LX_DXCREATEDEVICE \ + _IOWR(0x47, 0x02, struct d3dkmt_createdevice) +#define LX_DXCREATECONTEXTVIRTUAL \ + _IOWR(0x47, 0x04, struct d3dkmt_createcontextvirtual) +#define LX_DXDESTROYCONTEXT \ + _IOWR(0x47, 0x05, struct d3dkmt_destroycontext) +#define LX_DXCREATEALLOCATION \ + _IOWR(0x47, 0x06, struct d3dkmt_createallocation) +#define LX_DXCREATEPAGINGQUEUE \ + _IOWR(0x47, 0x07, struct d3dkmt_createpagingqueue) +#define LX_DXRESERVEGPUVIRTUALADDRESS \ + _IOWR(0x47, 0x08, struct d3dddi_reservegpuvirtualaddress) +#define LX_DXQUERYADAPTERINFO \ + _IOWR(0x47, 0x09, struct d3dkmt_queryadapterinfo) +#define LX_DXQUERYVIDEOMEMORYINFO \ + _IOWR(0x47, 0x0a, struct d3dkmt_queryvideomemoryinfo) +#define LX_DXMAKERESIDENT \ + _IOWR(0x47, 0x0b, struct d3dddi_makeresident) +#define LX_DXMAPGPUVIRTUALADDRESS \ + _IOWR(0x47, 0x0c, struct d3dddi_mapgpuvirtualaddress) +#define LX_DXESCAPE \ + _IOWR(0x47, 0x0d, struct d3dkmt_escape) +#define LX_DXGETDEVICESTATE \ + _IOWR(0x47, 0x0e, struct d3dkmt_getdevicestate) +#define LX_DXSUBMITCOMMAND \ + _IOWR(0x47, 0x0f, struct d3dkmt_submitcommand) +#define LX_DXCREATESYNCHRONIZATIONOBJECT \ + _IOWR(0x47, 0x10, struct d3dkmt_createsynchronizationobject2) +#define LX_DXSIGNALSYNCHRONIZATIONOBJECT \ + _IOWR(0x47, 0x11, struct d3dkmt_signalsynchronizationobject2) +#define LX_DXWAITFORSYNCHRONIZATIONOBJECT \ + _IOWR(0x47, 0x12, struct d3dkmt_waitforsynchronizationobject2) +#define LX_DXDESTROYALLOCATION2 \ + _IOWR(0x47, 0x13, struct d3dkmt_destroyallocation2) +#define LX_DXENUMADAPTERS2 \ + _IOWR(0x47, 0x14, struct d3dkmt_enumadapters2) +#define LX_DXCLOSEADAPTER \ + _IOWR(0x47, 0x15, struct d3dkmt_closeadapter) +#define LX_DXCHANGEVIDEOMEMORYRESERVATION \ + _IOWR(0x47, 0x16, struct d3dkmt_changevideomemoryreservation) +#define LX_DXCREATEHWQUEUE \ + _IOWR(0x47, 0x18, struct d3dkmt_createhwqueue) +#define LX_DXDESTROYHWQUEUE \ + _IOWR(0x47, 0x1b, struct d3dkmt_destroyhwqueue) +#define LX_DXDESTROYPAGINGQUEUE \ + _IOWR(0x47, 0x1c, struct d3dddi_destroypagingqueue) +#define LX_DXDESTROYDEVICE \ + _IOWR(0x47, 0x19, struct d3dkmt_destroydevice) +#define LX_DXDESTROYSYNCHRONIZATIONOBJECT \ + _IOWR(0x47, 0x1d, struct d3dkmt_destroysynchronizationobject) +#define LX_DXEVICT \ + _IOWR(0x47, 0x1e, struct d3dkmt_evict) +#define LX_DXFLUSHHEAPTRANSITIONS \ + _IOWR(0x47, 0x1f, struct d3dkmt_flushheaptransitions) +#define LX_DXFREEGPUVIRTUALADDRESS \ + _IOWR(0x47, 0x20, struct d3dkmt_freegpuvirtualaddress) +#define LX_DXGETCONTEXTINPROCESSSCHEDULINGPRIORITY \ + _IOWR(0x47, 0x21, struct d3dkmt_getcontextinprocessschedulingpriority) +#define LX_DXGETCONTEXTSCHEDULINGPRIORITY \ + _IOWR(0x47, 0x22, struct d3dkmt_getcontextschedulingpriority) +#define LX_DXINVALIDATECACHE \ + _IOWR(0x47, 0x24, struct d3dkmt_invalidatecache) +#define LX_DXLOCK2 \ + _IOWR(0x47, 0x25, struct d3dkmt_lock2) +#define LX_DXMARKDEVICEASERROR \ + _IOWR(0x47, 0x26, struct d3dkmt_markdeviceaserror) +#define LX_DXOFFERALLOCATIONS \ + _IOWR(0x47, 0x27, struct d3dkmt_offerallocations) +#define LX_DXQUERYALLOCATIONRESIDENCY \ + _IOWR(0x47, 0x2a, struct d3dkmt_queryallocationresidency) +#define LX_DXRECLAIMALLOCATIONS2 \ + _IOWR(0x47, 0x2c, struct d3dkmt_reclaimallocations2) +#define LX_DXSETALLOCATIONPRIORITY \ + _IOWR(0x47, 0x2e, struct d3dkmt_setallocationpriority) +#define LX_DXSETCONTEXTINPROCESSSCHEDULINGPRIORITY \ + _IOWR(0x47, 0x2f, struct d3dkmt_setcontextinprocessschedulingpriority) +#define LX_DXSETCONTEXTSCHEDULINGPRIORITY \ + _IOWR(0x47, 0x30, struct d3dkmt_setcontextschedulingpriority) +#define LX_DXSIGNALSYNCHRONIZATIONOBJECTFROMCPU \ + _IOWR(0x47, 0x31, struct d3dkmt_signalsynchronizationobjectfromcpu) +#define LX_DXSIGNALSYNCHRONIZATIONOBJECTFROMGPU \ + _IOWR(0x47, 0x32, struct d3dkmt_signalsynchronizationobjectfromgpu) +#define LX_DXSIGNALSYNCHRONIZATIONOBJECTFROMGPU2 \ + _IOWR(0x47, 0x33, struct d3dkmt_signalsynchronizationobjectfromgpu2) +#define LX_DXSUBMITCOMMANDTOHWQUEUE \ + _IOWR(0x47, 0x34, struct d3dkmt_submitcommandtohwqueue) +#define LX_DXSUBMITSIGNALSYNCOBJECTSTOHWQUEUE \ + _IOWR(0x47, 0x35, struct d3dkmt_submitsignalsyncobjectstohwqueue) +#define LX_DXSUBMITWAITFORSYNCOBJECTSTOHWQUEUE \ + _IOWR(0x47, 0x36, struct d3dkmt_submitwaitforsyncobjectstohwqueue) +#define LX_DXUNLOCK2 \ + _IOWR(0x47, 0x37, struct d3dkmt_unlock2) +#define LX_DXUPDATEALLOCPROPERTY \ + _IOWR(0x47, 0x38, struct d3dddi_updateallocproperty) +#define LX_DXUPDATEGPUVIRTUALADDRESS \ + _IOWR(0x47, 0x39, struct d3dkmt_updategpuvirtualaddress) +#define LX_DXWAITFORSYNCHRONIZATIONOBJECTFROMCPU \ + _IOWR(0x47, 0x3a, struct d3dkmt_waitforsynchronizationobjectfromcpu) +#define LX_DXWAITFORSYNCHRONIZATIONOBJECTFROMGPU \ + _IOWR(0x47, 0x3b, struct d3dkmt_waitforsynchronizationobjectfromgpu) +#define LX_DXGETALLOCATIONPRIORITY \ + _IOWR(0x47, 0x3c, struct d3dkmt_getallocationpriority) +#define LX_DXQUERYCLOCKCALIBRATION \ + _IOWR(0x47, 0x3d, struct d3dkmt_queryclockcalibration) +#define LX_DXENUMADAPTERS3 \ + _IOWR(0x47, 0x3e, struct d3dkmt_enumadapters3) +#define LX_DXSHAREOBJECTS \ + _IOWR(0x47, 0x3f, struct d3dkmt_shareobjects) +#define LX_DXOPENSYNCOBJECTFROMNTHANDLE2 \ + _IOWR(0x47, 0x40, struct d3dkmt_opensyncobjectfromnthandle2) +#define LX_DXQUERYRESOURCEINFOFROMNTHANDLE \ + _IOWR(0x47, 0x41, struct d3dkmt_queryresourceinfofromnthandle) +#define LX_DXOPENRESOURCEFROMNTHANDLE \ + _IOWR(0x47, 0x42, struct d3dkmt_openresourcefromnthandle) +#define LX_DXQUERYSTATISTICS \ + _IOWR(0x47, 0x43, struct d3dkmt_querystatistics) +#define LX_DXSHAREOBJECTWITHHOST \ + _IOWR(0x47, 0x44, struct d3dkmt_shareobjectwithhost) +#define LX_DXCREATESYNCFILE \ + _IOWR(0x47, 0x45, struct d3dkmt_createsyncfile) +#define LX_DXWAITSYNCFILE \ + _IOWR(0x47, 0x46, struct d3dkmt_waitsyncfile) +#define LX_DXOPENSYNCOBJECTFROMSYNCFILE \ + _IOWR(0x47, 0x47, struct d3dkmt_opensyncobjectfromsyncfile) +#define LX_DXENUMPROCESSES \ + _IOWR(0x47, 0x48, struct d3dkmt_enumprocesses) +#define LX_ISFEATUREENABLED \ + _IOWR(0x47, 0x49, struct d3dkmt_isfeatureenabled) + +#endif /* _D3DKMTHK_H */ diff --git a/meson_options.txt b/meson_options.txt index 92ffd1d6c40bb..d75691d7fbc4b 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -233,7 +233,7 @@ option( 'freedreno-kmds', type : 'array', value : ['msm'], - choices : ['msm', 'kgsl', 'virtio'], + choices : ['msm', 'kgsl', 'virtio', 'wsl'], description : 'List of kernel-mode drivers to enable for freedreno ' + 'gallium and vulkan driver', ) diff --git a/src/freedreno/decode/meson.build b/src/freedreno/decode/meson.build index 062798fe65474..56f4b4c75fe04 100644 --- a/src/freedreno/decode/meson.build +++ b/src/freedreno/decode/meson.build @@ -71,7 +71,7 @@ if dep_libarchive.found() ) foreach kmd : freedreno_kmds - if not (kmd in ['kgsl', 'msm']) + if not (kmd in ['kgsl', 'msm', 'wsl']) warning('replay not supported for ' + kmd + ' KMD') continue endif @@ -88,7 +88,10 @@ if dep_libarchive.found() if kmd == 'kgsl' replay_flags += '-DFD_REPLAY_KGSL' elif kmd == 'msm' + replay_flags += '-DFD_REPLAY_MSM' replay_deps += dep_libdrm + elif kmd == 'wsl' + replay_flags += '-DFD_REPLAY_WSL' endif replay = executable( diff --git a/src/freedreno/decode/replay.c b/src/freedreno/decode/replay.c index eefecb1505dbc..68614d41203a5 100644 --- a/src/freedreno/decode/replay.c +++ b/src/freedreno/decode/replay.c @@ -18,11 +18,14 @@ #include #include #include -#if !FD_REPLAY_KGSL +#if FD_REPLAY_KGSL +#include "../vulkan/msm_kgsl.h" +#elif FD_REPLAY_MSM #include #include "drm-uapi/msm_drm.h" -#else -#include "../vulkan/msm_kgsl.h" +#elif FD_REPLAY_WSL +#define __KERNEL__ +#include "drm-uapi/d3dkmthk.h" #endif #include @@ -69,7 +72,7 @@ static const uint64_t FAKE_ADDRESS_SPACE_SIZE = 1024 * 1024 * 1024; static int handle_file(const char *filename, uint32_t first_submit, uint32_t last_submit, uint32_t submit_to_override, - const char *cmdstreamgen); + uint64_t base_addr, const char *cmdstreamgen); static void print_usage(const char *name) @@ -83,6 +86,7 @@ print_usage(const char *name) "\t-g --generator=path - executable which generate cmdstream for override\n" "\t-f --first=submit - first submit № to replay\n" "\t-l --last=submit - last submit № to replay\n" + "\t-a --address=address - base iova address on WSL\n" "\t-h, --help - show this message\n" , name); /* clang-format on */ @@ -96,6 +100,7 @@ static const struct option opts[] = { { "generator", required_argument, 0, 'g' }, { "first", required_argument, 0, 'f' }, { "last", required_argument, 0, 'l' }, + { "address", required_argument, 0, 'a' }, { "help", no_argument, 0, 'h' }, }; /* clang-format on */ @@ -109,9 +114,10 @@ main(int argc, char **argv) uint32_t submit_to_override = -1; uint32_t first_submit = 0; uint32_t last_submit = -1; + uint64_t base_addr = 0; const char *cmdstreamgen = NULL; - while ((c = getopt_long(argc, argv, "e:o:g:f:l:h", opts, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "e:o:g:f:l:a:h", opts, NULL)) != -1) { switch (c) { case 0: /* option that set a flag, nothing to do */ @@ -131,6 +137,9 @@ main(int argc, char **argv) case 'l': last_submit = strtoul(optarg, NULL, 0); break; + case 'a': + base_addr = strtoull(optarg, NULL, 0); + break; case 'h': default: print_usage(argv[0]); @@ -139,7 +148,7 @@ main(int argc, char **argv) while (optind < argc) { ret = handle_file(argv[optind], first_submit, last_submit, - submit_to_override, cmdstreamgen); + submit_to_override, base_addr, cmdstreamgen); if (ret) { fprintf(stderr, "error reading: %s\n", argv[optind]); fprintf(stderr, "continuing..\n"); @@ -193,11 +202,24 @@ struct device { void *va_map; uint64_t va_iova; + struct u_vector wrbufs; + #ifdef FD_REPLAY_KGSL uint32_t context_id; #endif - struct u_vector wrbufs; +#ifdef FD_REPLAY_WSL + struct d3dkmthandle device; + struct d3dkmthandle context; + + /* We don't know at the moment a good way to wait for submission to complete + * on WSL, so we could use our own fences. + */ + uint64_t fence_iova; + uint64_t fence_ib_iova; + volatile uint32_t *fence; + uint32_t *fence_ib; +#endif }; void buffer_mem_free(struct device *dev, struct buffer *buf); @@ -365,7 +387,7 @@ device_dump_wrbuf(struct device *dev) } } -#if !FD_REPLAY_KGSL +#if FD_REPLAY_MSM static inline void get_abs_timeout(struct drm_msm_timespec *tv, uint64_t ns) { @@ -376,7 +398,7 @@ get_abs_timeout(struct drm_msm_timespec *tv, uint64_t ns) } static struct device * -device_create() +device_create(uint64_t base_addr) { struct device *dev = calloc(sizeof(struct device), 1); @@ -656,7 +678,7 @@ buffer_mem_free(struct device *dev, struct buffer *buf) util_vma_heap_free(&dev->vma, buf->iova, buf->size); } -#else +#elif FD_REPLAY_KGSL static int safe_ioctl(int fd, unsigned long request, void *arg) { @@ -670,7 +692,7 @@ safe_ioctl(int fd, unsigned long request, void *arg) } static struct device * -device_create() +device_create(uint64_t base_addr) { struct device *dev = calloc(sizeof(struct device), 1); @@ -789,6 +811,368 @@ buffer_mem_free(struct device *dev, struct buffer *buf) { util_vma_heap_free(&dev->vma, buf->iova, buf->size); } +#else + +static int +safe_ioctl(int fd, unsigned long request, void *arg) +{ + int ret; + + do { + ret = ioctl(fd, request, arg); + } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); + + return ret; +} + +struct alloc_priv_info { + __u32 struct_size; + char _pad0[4]; + __u32 unk0; // 1 + char _pad1[4]; + __u64 size; + __u32 alignment; + char _pad2[20]; + __u64 allocated_size; + __u32 unk1; // 1 + char _pad4[8]; /* offset: 60*/ + __u32 unk2; // 61 + char _pad5[76]; + __u32 unk3; /* offset: 148 */ // 1 + char _pad6[8]; + __u32 unk4; /* offset: 160 */ // 1 + char _pad7[44]; + __u32 unk5; /* offset: 208 */ // 3 + char _pad8[16]; + __u32 size_2; /* offset: 228 */ + __u32 unk6; // 1 + __u32 size_3; + __u32 size_4; + __u32 unk7; /* offset: 244 */ // 1 + char _pad9[56]; +}; +static_assert(sizeof(struct alloc_priv_info) == 304); +static_assert(offsetof(struct alloc_priv_info, unk1) == 56); +static_assert(offsetof(struct alloc_priv_info, unk3) == 148); +static_assert(offsetof(struct alloc_priv_info, unk5) == 208); + +struct submit_priv_ib_info { + char _pad5[4]; + __u32 size_dwords; + __u64 iova; + char _pad6[8]; +} __attribute__((packed)); + +struct submit_priv_data { + __u32 magic0; + char _pad0[4]; + __u32 struct_size; + char _pad1[4]; + /* It seems that priv data can have several sub-datas + * cmdbuf is one of them, after it there is another 8 byte struct + * without anything useful in it. That second data doesn't seem + * important for replaying. + */ + __u32 datas_count; + char _pad2[32]; + struct { + __u32 magic1; + __u32 data_size; + + struct { + __u32 unk1; + __u32 cmdbuf_size; + char _pad3[32]; + __u32 ib_count; + char _pad4[36]; + + struct submit_priv_ib_info ibs[]; + } cmdbuf; + } data0; + + // unsigned char magic2[8]; +} __attribute__((packed)); +static_assert(offsetof(struct submit_priv_data, data0) == 0x34); +static_assert(offsetof(struct submit_priv_data, data0.cmdbuf.ibs) == 0x8c); + +static struct device * +device_create(uint64_t base_addr) +{ + struct device *dev = calloc(sizeof(struct device), 1); + + static const char path[] = "/dev/dxg"; + + dev->fd = open(path, O_RDWR | O_CLOEXEC); + if (dev->fd < 0) { + errx(1, "Cannot open /dev/dxg fd"); + } + + struct d3dkmt_adapterinfo adapters[1]; + struct d3dkmt_enumadapters3 enum_adapters = { + .adapter_count = 1, + .adapters = adapters, + }; + int ret = safe_ioctl(dev->fd, LX_DXENUMADAPTERS3, &enum_adapters); + if (ret) { + errx(1, "LX_DXENUMADAPTERS3 failure"); + } + + if (enum_adapters.adapter_count == 0) { + errx(1, "No adapters found"); + } + + struct winluid adapter_luid = enum_adapters.adapters[0].adapter_luid; + + struct d3dkmt_openadapterfromluid open_adapter = { + .adapter_luid = adapter_luid, + }; + ret = safe_ioctl(dev->fd, LX_DXOPENADAPTERFROMLUID, &open_adapter); + if (ret) { + errx(1, "LX_DXOPENADAPTERFROMLUID failure"); + } + + struct d3dkmthandle adapter = open_adapter.adapter_handle; + + struct d3dkmt_createdevice create_device = { + .adapter = adapter, + }; + ret = safe_ioctl(dev->fd, LX_DXCREATEDEVICE, &create_device); + if (ret) { + errx(1, "LX_DXCREATEDEVICE failure"); + } + + struct d3dkmthandle device = create_device.device; + dev->device = device; + + unsigned char create_context_priv_data[] = { + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + struct d3dkmt_createcontextvirtual create_context = { + .device = device, + .node_ordinal = 0, + .engine_affinity = 1, + .priv_drv_data = create_context_priv_data, + .priv_drv_data_size = sizeof(create_context_priv_data), + .client_hint = 16, + }; + ret = safe_ioctl(dev->fd, LX_DXCREATECONTEXTVIRTUAL, &create_context); + if (ret) { + errx(1, "LX_DXCREATECONTEXTVIRTUAL failure"); + } + + dev->context = create_context.context; + + struct d3dkmt_createpagingqueue create_paging_queue = { + .device = device, + .priority = _D3DDDI_PAGINGQUEUE_PRIORITY_NORMAL, + .physical_adapter_index = 0, + }; + ret = safe_ioctl(dev->fd, LX_DXCREATEPAGINGQUEUE, &create_paging_queue); + if (ret) { + errx(1, "LX_DXCREATEPAGINGQUEUE failure"); + } + struct d3dkmthandle paging_queue = create_paging_queue.paging_queue; + + + uint32_t alloc_size = FAKE_ADDRESS_SPACE_SIZE; + struct alloc_priv_info priv_alloc_info = { + .struct_size = sizeof(struct alloc_priv_info), + .unk0 = 1, + .size = alloc_size, + .alignment = 4096, + .unk1 = 1, + .unk2 = 61, + .unk3 = 1, + .unk4 = 1, + .unk5 = 3, + .size_2 = alloc_size, + .unk6 = 1, + .size_3 = alloc_size, + .size_4 = alloc_size, + .unk7 = 1, + }; + + struct d3dddi_allocationinfo2 alloc_info = { + .priv_drv_data = &priv_alloc_info, + .priv_drv_data_size = sizeof(struct alloc_priv_info), + }; + + struct d3dkmt_createallocation create_allocation = { + .device = device, + .alloc_count = 1, + .allocation_info = &alloc_info, + }; + ret = safe_ioctl(dev->fd, LX_DXCREATEALLOCATION, &create_allocation); + if (ret) { + errx(1, "LX_DXCREATEALLOCATION failure"); + } + + assert(priv_alloc_info.allocated_size == alloc_size); + + struct d3dddi_mapgpuvirtualaddress map_virtual_address = { + .paging_queue = paging_queue, + .base_address = base_addr, + .maximum_address = 18446744073709551615ull, + .allocation = create_allocation.allocation_info[0].allocation, + .size_in_pages = MAX2(alloc_size / 4096, 1), + .protection = { + .write = 1, + .execute = 1, + }, + }; + ret = safe_ioctl(dev->fd, LX_DXMAPGPUVIRTUALADDRESS, &map_virtual_address); + if (ret != 259) { + errx(1, "LX_DXMAPGPUVIRTUALADDRESS failure"); + } + + __u32 priority = 0; + struct d3dddi_makeresident make_resident = { + .paging_queue = paging_queue, + .alloc_count = 1, + .allocation_list = &create_allocation.allocation_info[0].allocation, + .priority_list = &priority, + }; + ret = safe_ioctl(dev->fd, LX_DXMAKERESIDENT, &make_resident); + if (ret != 259) { + errx(1, "LX_DXMAKERESIDENT failure"); + } + + struct d3dkmt_lock2 lock = { + .device = device, + .allocation = create_allocation.allocation_info[0].allocation, + }; + ret = safe_ioctl(dev->fd, LX_DXLOCK2, &lock); + if (ret) { + errx(1, "LX_DXLOCK2 failure"); + } + + dev->va_iova = map_virtual_address.virtual_address; + dev->va_map = lock.data; + + rb_tree_init(&dev->buffers); + util_vma_heap_init(&dev->vma, dev->va_iova, ROUND_DOWN_TO(alloc_size, 4096)); + u_vector_init(&dev->cmdstreams, 8, sizeof(struct cmdstream)); + + printf("Allocated iova at 0x%" PRIx64 "\n", dev->va_iova); + + uint64_t hole_size = 4096; + dev->vma.alloc_high = true; + dev->fence_iova = util_vma_heap_alloc(&dev->vma, hole_size, 4096); + dev->fence_ib_iova = dev->fence_iova + 8; + dev->fence = (uint32_t *) ((uint8_t*)dev->va_map + (dev->fence_iova - dev->va_iova)); + dev->fence_ib = (uint32_t *) ((uint8_t*)dev->va_map + (dev->fence_ib_iova - dev->va_iova)); + dev->vma.alloc_high = false; + + return dev; +} + +static void +device_submit_cmdstreams(struct device *dev) +{ + if (!u_vector_length(&dev->cmdstreams)) { + device_free_buffers(dev); + return; + } + + uint32_t cmdstream_count = u_vector_length(&dev->cmdstreams) + 1; + + uint32_t priv_data_size = + sizeof(struct submit_priv_data) + + cmdstream_count * sizeof(struct submit_priv_ib_info); + + struct submit_priv_data *priv_data = calloc(1, priv_data_size); + priv_data->magic0 = 0xccaabbee; + priv_data->struct_size = priv_data_size; + priv_data->datas_count = 1; + + priv_data->data0.magic1 = 0xfadcab02; + priv_data->data0.data_size = + sizeof(priv_data->data0) + + cmdstream_count * sizeof(struct submit_priv_ib_info); + priv_data->data0.cmdbuf.unk1 = 0xcccc0001; + priv_data->data0.cmdbuf.cmdbuf_size = sizeof(priv_data->data0.cmdbuf) + + cmdstream_count * sizeof(struct submit_priv_ib_info); + priv_data->data0.cmdbuf.ib_count = cmdstream_count; + + struct cmdstream *cmd; + uint32_t idx = 0; + u_vector_foreach(cmd, &dev->cmdstreams) { + priv_data->data0.cmdbuf.ibs[idx].size_dwords = cmd->size / 4; + priv_data->data0.cmdbuf.ibs[idx].iova = cmd->iova; + idx++; + } + + priv_data->data0.cmdbuf.ibs[idx].size_dwords = 4; + priv_data->data0.cmdbuf.ibs[idx].iova = dev->fence_ib_iova; + + *dev->fence = 0x00000000; + dev->fence_ib[0] = pm4_pkt7_hdr(0x3d, 3); // CP_MEM_WRITE + dev->fence_ib[1] = dev->fence_iova; + dev->fence_ib[2] = dev->fence_iova >> 32; + dev->fence_ib[3] = 0xababfcfc; + + // Fill second (empty) data block + // uint32_t *magic_end = (uint32_t *)(((char *) priv_data) + priv_data_size - 8); + // magic_end[0] = 0xfadcab00; + // magic_end[1] = 0x00000008; + + struct d3dkmt_submitcommand submission = { + .command_buffer = priv_data->data0.cmdbuf.ibs[0].iova, + .command_length = priv_data->data0.cmdbuf.ibs[0].size_dwords * sizeof(uint32_t), + .broadcast_context_count = 1, + .broadcast_context[0] = dev->context, + .priv_drv_data_size = priv_data_size, + .priv_drv_data = priv_data, + }; + + int ret = safe_ioctl(dev->fd, LX_DXSUBMITCOMMAND, &submission); + if (ret) { + errx(1, "LX_DXSUBMITCOMMAND failure"); + } + + free(priv_data); + + u_vector_finish(&dev->cmdstreams); + u_vector_init(&dev->cmdstreams, 8, sizeof(struct cmdstream)); + + // TODO: better way to wait + for (unsigned i = 0; i < 1000; i++) { + usleep(1000); + if (*dev->fence != 0) + break; + } + if (*dev->fence == 0) { + errx(1, "Waiting for submission failed! GPU faulted or kernel did not execute this submission."); + } + + device_print_shader_log(dev); + device_print_cp_log(dev); + + device_dump_wrbuf(dev); + + device_free_buffers(dev); +} + +static void +buffer_mem_alloc(struct device *dev, struct buffer *buf) +{ + util_vma_heap_alloc_addr(&dev->vma, buf->iova, buf->size); + + buf->map = ((uint8_t*)dev->va_map) + (buf->iova - dev->va_iova); +} + +void +buffer_mem_free(struct device *dev, struct buffer *buf) +{ + util_vma_heap_free(&dev->vma, buf->iova, buf->size); +} + #endif static void @@ -822,7 +1206,7 @@ override_cmdstream(struct device *dev, struct cmdstream *cs, { #if FD_REPLAY_KGSL static const char *tmpfilename = "/sdcard/Download/cmdstream_override.rd"; -#else +#elif FD_REPLAY_MSM || FD_REPLAY_WSL static const char *tmpfilename = "/tmp/cmdstream_override.rd"; #endif @@ -918,7 +1302,7 @@ override_cmdstream(struct device *dev, struct cmdstream *cs, static int handle_file(const char *filename, uint32_t first_submit, uint32_t last_submit, - uint32_t submit_to_override, const char *cmdstreamgen) + uint32_t submit_to_override, uint64_t base_addr, const char *cmdstreamgen) { struct io *io; int submit = 0; @@ -938,7 +1322,7 @@ handle_file(const char *filename, uint32_t first_submit, uint32_t last_submit, return -1; } - struct device *dev = device_create(); + struct device *dev = device_create(base_addr); struct { unsigned int len;