dx12.cpp 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011
  1. #define HL_NAME(n) dx12_##n
  2. #include <hl.h>
  3. #ifdef HL_WIN_DESKTOP
  4. #include <dxgi.h>
  5. #include <dxgi1_5.h>
  6. #include <d3d12.h>
  7. #include <dxcapi.h>
  8. #endif
  9. #ifdef HL_XBS
  10. #ifdef _GAMING_XBOX_SCARLETT
  11. #include <d3d12_xs.h>
  12. #include <d3dx12_xs.h>
  13. #include <dxcapi_xs.h>
  14. #else
  15. #include <d3d12_x.h>
  16. #include <d3dx12_x.h>
  17. #include <dxcapi_x.h>
  18. #endif
  19. #define IID_PPV_ARGS_OLD(ppType) __uuidof(**(ppType)), IID_PPV_ARGS_Helper(ppType)
  20. #undef IID_PPV_ARGS
  21. #define IID_PPV_ARGS IID_GRAPHICS_PPV_ARGS
  22. #endif
  23. #define DXERR(cmd) { HRESULT __ret = cmd; if( __ret == E_OUTOFMEMORY ) return NULL; if( __ret != S_OK ) ReportDxError(__ret,__LINE__); }
  24. #define CHKERR(cmd) { HRESULT __ret = cmd; if( __ret != S_OK ) ReportDxError(__ret,__LINE__); }
  25. typedef struct {
  26. HWND wnd;
  27. ID3D12CommandQueue *commandQueue;
  28. #ifndef HL_XBS
  29. IDXGIFactory4 *factory;
  30. IDXGIAdapter1 *adapter;
  31. IDXGISwapChain4 *swapchain;
  32. ID3D12Device *device;
  33. ID3D12Debug1 *debug;
  34. ID3D12DebugDevice *debugDevice;
  35. ID3D12InfoQueue *infoQueue;
  36. #else
  37. ID3D12Device2 *device;
  38. ID3D12Debug *debug;
  39. ID3D12DebugDevice *debugDevice;
  40. // SwapChain
  41. UINT swapBufferCount;
  42. UINT backBufferIndex;
  43. ID3D12Resource **swapBuffers;
  44. D3D12XBOX_FRAME_PIPELINE_TOKEN pipelineToken;
  45. // Cached values
  46. IDXGIAdapter *adapter;
  47. #endif
  48. } dx_driver;
  49. static dx_driver *static_driver = NULL;
  50. static int CURRENT_NODEMASK = 0;
  51. void dx12_flush_messages();
  52. static void ReportDxError( HRESULT err, int line ) {
  53. dx12_flush_messages();
  54. hl_error("DXERROR %X line %d",(DWORD)err,line);
  55. }
  56. static void OnDebugMessage(
  57. D3D12_MESSAGE_CATEGORY Category,
  58. D3D12_MESSAGE_SEVERITY Severity,
  59. D3D12_MESSAGE_ID ID,
  60. LPCSTR pDescription,
  61. void *pContext ) {
  62. printf("%s\n", pDescription);
  63. fflush(stdout);
  64. }
  65. HL_PRIM varray *HL_NAME(list_devices)() {
  66. #ifndef HL_XBS
  67. static int MAX_DEVICES = 64;
  68. int index = 0, write = 0;
  69. IDXGIAdapter1 *adapter = NULL;
  70. IDXGIFactory4 *factory = NULL;
  71. varray *arr = hl_alloc_array(&hlt_bytes, MAX_DEVICES);
  72. if( static_driver )
  73. factory = static_driver->factory;
  74. else {
  75. CHKERR(CreateDXGIFactory2(0, IID_PPV_ARGS(&factory)));
  76. }
  77. while( write < MAX_DEVICES && factory->EnumAdapters1(index++,&adapter) != DXGI_ERROR_NOT_FOUND ) {
  78. DXGI_ADAPTER_DESC1 desc;
  79. adapter->GetDesc1(&desc);
  80. if( (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) == 0 )
  81. hl_aptr(arr,uchar*)[write++] = ustrdup(desc.Description);
  82. adapter->Release();
  83. }
  84. if( !static_driver )
  85. factory->Release();
  86. return arr;
  87. #else
  88. varray *arr = hl_alloc_array(&hlt_bytes, 1);
  89. DXGI_ADAPTER_DESC desc;
  90. static_driver->adapter->GetDesc(&desc);
  91. hl_aptr(arr, uchar*)[0] = ustrdup(desc.Description);
  92. return arr;
  93. #endif
  94. }
  95. HL_PRIM dx_driver *HL_NAME(create)( HWND window, int flags, uchar *dev_desc ) {
  96. UINT dxgiFlags = 0;
  97. dx_driver *drv = (dx_driver*)hl_gc_alloc_raw(sizeof(dx_driver));
  98. memset(drv, 0, sizeof(dx_driver));
  99. drv->wnd = window;
  100. if( flags & 1 ) {
  101. ID3D12Debug *debugController;
  102. D3D12GetDebugInterface(IID_PPV_ARGS(&debugController));
  103. debugController->EnableDebugLayer();
  104. #ifndef HL_XBS
  105. debugController->QueryInterface(&drv->debug);
  106. drv->debug->EnableDebugLayer();
  107. drv->debug->SetEnableGPUBasedValidation(true);
  108. dxgiFlags |= DXGI_CREATE_FACTORY_DEBUG;
  109. #else
  110. debugController->QueryInterface(IID_PPV_ARGS(&drv->debug));
  111. #endif
  112. debugController->Release();
  113. }
  114. #ifndef HL_XBS
  115. CHKERR(CreateDXGIFactory2(dxgiFlags, IID_PPV_ARGS(&drv->factory)));
  116. UINT index = 0;
  117. IDXGIAdapter1 *adapter = NULL;
  118. while( drv->factory->EnumAdapters1(index++,&adapter) != DXGI_ERROR_NOT_FOUND ) {
  119. DXGI_ADAPTER_DESC1 desc;
  120. adapter->GetDesc1(&desc);
  121. if( (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) || (dev_desc && !wcsstr(desc.Description,dev_desc)) ) {
  122. adapter->Release();
  123. continue;
  124. }
  125. if( SUCCEEDED(D3D12CreateDevice(adapter,D3D_FEATURE_LEVEL_12_0,IID_PPV_ARGS(&drv->device))) ) {
  126. drv->adapter = adapter;
  127. break;
  128. }
  129. adapter->Release();
  130. }
  131. if( !drv->device )
  132. return NULL;
  133. drv->device->SetName(L"HL_DX12");
  134. if( drv->debug ) {
  135. CHKERR(drv->device->QueryInterface(IID_PPV_ARGS(&drv->debugDevice)));
  136. CHKERR(drv->device->QueryInterface(IID_PPV_ARGS(&drv->infoQueue)));
  137. drv->infoQueue->ClearStoredMessages();
  138. }
  139. #else
  140. D3D12XBOX_CREATE_DEVICE_PARAMETERS params = {};
  141. params.Version = D3D12_SDK_VERSION;
  142. #if defined(_DEBUG)
  143. params.ProcessDebugFlags = D3D12_PROCESS_DEBUG_FLAG_DEBUG_LAYER_ENABLED;
  144. #endif
  145. params.GraphicsCommandQueueRingSizeBytes = static_cast<UINT>(D3D12XBOX_DEFAULT_SIZE_BYTES);
  146. params.GraphicsScratchMemorySizeBytes = static_cast<UINT>(D3D12XBOX_DEFAULT_SIZE_BYTES);
  147. params.ComputeScratchMemorySizeBytes = static_cast<UINT>(D3D12XBOX_DEFAULT_SIZE_BYTES);
  148. params.DisableGeometryShaderAllocations = TRUE;
  149. params.DisableTessellationShaderAllocations = TRUE;
  150. #ifdef _GAMING_XBOX_SCARLETT
  151. params.DisableDXR = TRUE;
  152. params.CreateDeviceFlags = D3D12XBOX_CREATE_DEVICE_FLAG_NONE;
  153. #endif
  154. CHKERR(D3D12XboxCreateDevice(nullptr,&params, IID_PPV_ARGS(&drv->device)))
  155. drv->device->SetName(L"HL_DX12_XBS");
  156. if (drv->debug) {
  157. CHKERR(drv->device->QueryInterface(IID_PPV_ARGS(&drv->debugDevice)));
  158. }
  159. // Prepare for PresentX
  160. {
  161. IDXGIDevice1 *dxgiDevice;
  162. CHKERR(drv->device->QueryInterface(IID_PPV_ARGS(&dxgiDevice)));
  163. IDXGIAdapter *dxgiAdapter;
  164. CHKERR(dxgiDevice->GetAdapter(&dxgiAdapter));
  165. DXGI_ADAPTER_DESC desc;
  166. dxgiAdapter->GetDesc(&desc);
  167. if (dev_desc) {
  168. wcsstr(desc.Description, dev_desc);
  169. }
  170. drv->adapter = dxgiAdapter;
  171. }
  172. #endif
  173. {
  174. D3D12_COMMAND_QUEUE_DESC desc = {};
  175. desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
  176. desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL;
  177. desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
  178. desc.NodeMask = CURRENT_NODEMASK;
  179. CHKERR(drv->device->CreateCommandQueue(&desc, IID_PPV_ARGS(&drv->commandQueue)));
  180. }
  181. static_driver = drv;
  182. return drv;
  183. }
  184. #ifdef HL_XBS
  185. void register_frame_events() {
  186. dx_driver *drv = static_driver;
  187. // Prepare PresentX
  188. IDXGIOutput *dxgiOutput;
  189. CHKERR(drv->adapter->EnumOutputs(0, &dxgiOutput));
  190. // May return S_OK, S_FALSE
  191. HRESULT hr = drv->device->SetFrameIntervalX(dxgiOutput, D3D12XBOX_FRAME_INTERVAL_60_HZ, drv->swapBufferCount - 1u /* Allow n-1 frames of latency */, D3D12XBOX_FRAME_INTERVAL_FLAG_NONE);
  192. if (hr < 0) ReportDxError(hr, __LINE__);
  193. CHKERR(drv->device->ScheduleFrameEventX(D3D12XBOX_FRAME_EVENT_ORIGIN, 0U, nullptr, D3D12XBOX_SCHEDULE_FRAME_EVENT_FLAG_NONE));
  194. // Prepare first pipeline token
  195. drv->pipelineToken = D3D12XBOX_FRAME_PIPELINE_TOKEN_NULL;
  196. CHKERR(drv->device->WaitFrameEventX(D3D12XBOX_FRAME_EVENT_ORIGIN, INFINITE, nullptr, D3D12XBOX_WAIT_FRAME_EVENT_FLAG_NONE, &drv->pipelineToken));
  197. }
  198. #endif
  199. HL_PRIM void HL_NAME(suspend)() {
  200. #ifdef HL_XBS
  201. // Must be called from the render thread
  202. CHKERR(static_driver->commandQueue->SuspendX(0));
  203. #endif
  204. }
  205. HL_PRIM void HL_NAME(resume)() {
  206. #ifdef HL_XBS
  207. CHKERR(static_driver->commandQueue->ResumeX());
  208. register_frame_events();
  209. #endif
  210. }
  211. HL_PRIM void HL_NAME(resize)( int width, int height, int buffer_count, DXGI_FORMAT format ) {
  212. dx_driver *drv = static_driver;
  213. #ifndef HL_XBS
  214. if( drv->swapchain ) {
  215. CHKERR(drv->swapchain->ResizeBuffers(buffer_count, width, height, format, 0));
  216. } else {
  217. DXGI_SWAP_CHAIN_DESC1 desc = {};
  218. desc.Width = width;
  219. desc.Height = height;
  220. desc.Format = format;
  221. desc.BufferCount = buffer_count;
  222. desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
  223. desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
  224. desc.SampleDesc.Count = 1;
  225. IDXGISwapChain1 *swapchain = NULL;
  226. drv->factory->CreateSwapChainForHwnd(drv->commandQueue,drv->wnd,&desc,NULL,NULL,&swapchain);
  227. if( !swapchain ) CHKERR(E_INVALIDARG);
  228. swapchain->QueryInterface(IID_PPV_ARGS(&drv->swapchain));
  229. }
  230. #else
  231. if (drv->swapBuffers) {
  232. free(drv->swapBuffers);
  233. }
  234. // Create swap buffers
  235. CD3DX12_HEAP_PROPERTIES swapChainHeapProperties(D3D12_HEAP_TYPE_DEFAULT);
  236. D3D12_RESOURCE_DESC swapChainBufferDesc = CD3DX12_RESOURCE_DESC::Tex2D(format, width, height,
  237. 1, // This resource has only one texture.
  238. 1 // Use a single mipmap level.
  239. );
  240. swapChainBufferDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
  241. D3D12_CLEAR_VALUE swapChainOptimizedClearValue = {};
  242. swapChainOptimizedClearValue.Format = format;
  243. drv->swapBuffers = (ID3D12Resource**) malloc(sizeof(ID3D12Resource*) * buffer_count);
  244. if (drv->swapBuffers == nullptr)
  245. hl_error("malloc drv->swapBuffers failed");
  246. drv->swapBufferCount = buffer_count;
  247. drv->backBufferIndex = 0;
  248. for (int n = 0; n < buffer_count; n++)
  249. {
  250. drv->device->CreateCommittedResource(&swapChainHeapProperties, D3D12_HEAP_FLAG_ALLOW_DISPLAY, &swapChainBufferDesc, D3D12_RESOURCE_STATE_PRESENT, &swapChainOptimizedClearValue, IID_PPV_ARGS(&drv->swapBuffers[n]));
  251. }
  252. register_frame_events();
  253. #endif
  254. }
  255. HL_PRIM void HL_NAME(present)( bool vsync ) {
  256. dx_driver *drv = static_driver;
  257. #ifndef HL_XBS
  258. UINT syncInterval = vsync ? 1 : 0;
  259. UINT presentFlags = 0;
  260. CHKERR(drv->swapchain->Present(syncInterval, presentFlags));
  261. #else
  262. D3D12XBOX_PRESENT_PLANE_PARAMETERS planeParameters = {};
  263. planeParameters.Token = drv->pipelineToken;
  264. planeParameters.ResourceCount = 1;
  265. planeParameters.ppResources = &drv->swapBuffers[drv->backBufferIndex];
  266. CHKERR(drv->commandQueue->PresentX(1, &planeParameters, nullptr));
  267. drv->backBufferIndex = (drv->backBufferIndex + 1) % drv->swapBufferCount;
  268. // Prepare next pipeline token
  269. drv->pipelineToken = D3D12XBOX_FRAME_PIPELINE_TOKEN_NULL;
  270. CHKERR(drv->device->WaitFrameEventX(D3D12XBOX_FRAME_EVENT_ORIGIN, INFINITE, nullptr, D3D12XBOX_WAIT_FRAME_EVENT_FLAG_NONE, &drv->pipelineToken));
  271. #endif
  272. }
  273. int HL_NAME(get_current_back_buffer_index)() {
  274. #ifndef HL_XBS
  275. return static_driver->swapchain->GetCurrentBackBufferIndex();
  276. #else
  277. return static_driver->backBufferIndex;
  278. #endif
  279. }
  280. void HL_NAME(signal)( ID3D12Fence *fence, int64 value ) {
  281. static_driver->commandQueue->Signal(fence,value);
  282. }
  283. void HL_NAME(flush_messages)() {
  284. #ifndef HL_XBS
  285. dx_driver *drv = static_driver;
  286. if( !drv->infoQueue ) return;
  287. int count = (int)drv->infoQueue->GetNumStoredMessages();
  288. if( !count ) return;
  289. int i;
  290. for(i=0;i<count;i++) {
  291. SIZE_T len = 0;
  292. drv->infoQueue->GetMessage(i, NULL, &len);
  293. D3D12_MESSAGE *msg = (D3D12_MESSAGE*)malloc(len);
  294. if( msg == NULL ) break;
  295. drv->infoQueue->GetMessage(i, msg, &len);
  296. printf("%s\n",msg->pDescription);
  297. free(msg);
  298. fflush(stdout);
  299. }
  300. drv->infoQueue->ClearStoredMessages();
  301. #endif
  302. }
  303. uchar *HL_NAME(get_device_name)() {
  304. DXGI_ADAPTER_DESC desc;
  305. #ifndef HL_XBS
  306. IDXGIAdapter *adapter = NULL;
  307. if( !static_driver ) {
  308. IDXGIFactory4 *factory = NULL;
  309. CreateDXGIFactory2(0, IID_PPV_ARGS(&factory));
  310. if( factory ) factory->EnumAdapters(0,&adapter);
  311. if( !adapter )
  312. return USTR("Unknown");
  313. } else
  314. adapter = static_driver->adapter;
  315. adapter->GetDesc(&desc);
  316. #else
  317. static_driver->adapter->GetDesc(&desc);
  318. #endif
  319. return (uchar*)hl_copy_bytes((vbyte*)desc.Description, (int)(ustrlen((uchar*)desc.Description) + 1) * 2);
  320. }
  321. int64 HL_NAME(get_timestamp_frequency)() {
  322. UINT64 f = 0;
  323. CHKERR(static_driver->commandQueue->GetTimestampFrequency(&f))
  324. return (int64)f;
  325. }
  326. #define _DRIVER _ABSTRACT(dx_driver)
  327. #define _RES _ABSTRACT(dx_resource)
  328. DEFINE_PRIM(_ARR, list_devices, _NO_ARG);
  329. DEFINE_PRIM(_DRIVER, create, _ABSTRACT(dx_window) _I32 _BYTES);
  330. DEFINE_PRIM(_VOID, resize, _I32 _I32 _I32 _I32);
  331. DEFINE_PRIM(_VOID, present, _BOOL);
  332. DEFINE_PRIM(_VOID, suspend, _NO_ARG);
  333. DEFINE_PRIM(_VOID, resume, _NO_ARG);
  334. DEFINE_PRIM(_I32, get_current_back_buffer_index, _NO_ARG);
  335. DEFINE_PRIM(_VOID, signal, _RES _I64);
  336. DEFINE_PRIM(_VOID, flush_messages, _NO_ARG);
  337. DEFINE_PRIM(_BYTES, get_device_name, _NO_ARG);
  338. DEFINE_PRIM(_I64, get_timestamp_frequency, _NO_ARG);
  339. /// --- utilities (from d3dx12.h)
  340. #ifndef HL_XBS
  341. struct CD3DX12_TEXTURE_COPY_LOCATION : public D3D12_TEXTURE_COPY_LOCATION
  342. {
  343. CD3DX12_TEXTURE_COPY_LOCATION() = default;
  344. explicit CD3DX12_TEXTURE_COPY_LOCATION(const D3D12_TEXTURE_COPY_LOCATION &o) noexcept :
  345. D3D12_TEXTURE_COPY_LOCATION(o)
  346. {}
  347. CD3DX12_TEXTURE_COPY_LOCATION(_In_ ID3D12Resource* pRes) noexcept
  348. {
  349. pResource = pRes;
  350. Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
  351. PlacedFootprint = {};
  352. }
  353. CD3DX12_TEXTURE_COPY_LOCATION(_In_ ID3D12Resource* pRes, D3D12_PLACED_SUBRESOURCE_FOOTPRINT const& Footprint) noexcept
  354. {
  355. pResource = pRes;
  356. Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
  357. PlacedFootprint = Footprint;
  358. }
  359. CD3DX12_TEXTURE_COPY_LOCATION(_In_ ID3D12Resource* pRes, UINT Sub) noexcept
  360. {
  361. pResource = pRes;
  362. Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
  363. PlacedFootprint = {};
  364. SubresourceIndex = Sub;
  365. }
  366. };
  367. inline void MemcpySubresource(
  368. _In_ const D3D12_MEMCPY_DEST* pDest,
  369. _In_ const D3D12_SUBRESOURCE_DATA* pSrc,
  370. SIZE_T RowSizeInBytes,
  371. UINT NumRows,
  372. UINT NumSlices) noexcept
  373. {
  374. for (UINT z = 0; z < NumSlices; ++z)
  375. {
  376. auto pDestSlice = static_cast<BYTE*>(pDest->pData) + pDest->SlicePitch * z;
  377. auto pSrcSlice = static_cast<const BYTE*>(pSrc->pData) + pSrc->SlicePitch * LONG_PTR(z);
  378. for (UINT y = 0; y < NumRows; ++y)
  379. {
  380. memcpy(pDestSlice + pDest->RowPitch * y,
  381. pSrcSlice + pSrc->RowPitch * LONG_PTR(y),
  382. RowSizeInBytes);
  383. }
  384. }
  385. }
  386. inline UINT64 UpdateSubresources(
  387. _In_ ID3D12GraphicsCommandList* pCmdList,
  388. _In_ ID3D12Resource* pDestinationResource,
  389. _In_ ID3D12Resource* pIntermediate,
  390. _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
  391. _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources,
  392. UINT64 RequiredSize,
  393. _In_reads_(NumSubresources) const D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts,
  394. _In_reads_(NumSubresources) const UINT* pNumRows,
  395. _In_reads_(NumSubresources) const UINT64* pRowSizesInBytes,
  396. _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData) noexcept
  397. {
  398. // Minor validation
  399. auto IntermediateDesc = pIntermediate->GetDesc();
  400. auto DestinationDesc = pDestinationResource->GetDesc();
  401. if (IntermediateDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER ||
  402. IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset ||
  403. RequiredSize > SIZE_T(-1) ||
  404. (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER &&
  405. (FirstSubresource != 0 || NumSubresources != 1)))
  406. {
  407. return 0;
  408. }
  409. BYTE* pData;
  410. HRESULT hr = pIntermediate->Map(0, nullptr, reinterpret_cast<void**>(&pData));
  411. if (FAILED(hr))
  412. {
  413. return 0;
  414. }
  415. for (UINT i = 0; i < NumSubresources; ++i)
  416. {
  417. if (pRowSizesInBytes[i] > SIZE_T(-1)) return 0;
  418. D3D12_MEMCPY_DEST DestData = { pData + pLayouts[i].Offset, pLayouts[i].Footprint.RowPitch, SIZE_T(pLayouts[i].Footprint.RowPitch) * SIZE_T(pNumRows[i]) };
  419. MemcpySubresource(&DestData, &pSrcData[i], static_cast<SIZE_T>(pRowSizesInBytes[i]), pNumRows[i], pLayouts[i].Footprint.Depth);
  420. }
  421. pIntermediate->Unmap(0, nullptr);
  422. if (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
  423. {
  424. pCmdList->CopyBufferRegion(
  425. pDestinationResource, 0, pIntermediate, pLayouts[0].Offset, pLayouts[0].Footprint.Width);
  426. }
  427. else
  428. {
  429. for (UINT i = 0; i < NumSubresources; ++i)
  430. {
  431. CD3DX12_TEXTURE_COPY_LOCATION Dst(pDestinationResource, i + FirstSubresource);
  432. CD3DX12_TEXTURE_COPY_LOCATION Src(pIntermediate, pLayouts[i]);
  433. pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, nullptr);
  434. }
  435. }
  436. return RequiredSize;
  437. }
  438. inline UINT64 UpdateSubresources(
  439. _In_ ID3D12GraphicsCommandList* pCmdList,
  440. _In_ ID3D12Resource* pDestinationResource,
  441. _In_ ID3D12Resource* pIntermediate,
  442. UINT64 IntermediateOffset,
  443. _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
  444. _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources,
  445. _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData) noexcept
  446. {
  447. UINT64 RequiredSize = 0;
  448. auto MemToAlloc = static_cast<UINT64>(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(UINT) + sizeof(UINT64)) * NumSubresources;
  449. if (MemToAlloc > SIZE_MAX)
  450. {
  451. return 0;
  452. }
  453. void* pMem = HeapAlloc(GetProcessHeap(), 0, static_cast<SIZE_T>(MemToAlloc));
  454. if (pMem == nullptr)
  455. {
  456. return 0;
  457. }
  458. auto pLayouts = static_cast<D3D12_PLACED_SUBRESOURCE_FOOTPRINT*>(pMem);
  459. auto pRowSizesInBytes = reinterpret_cast<UINT64*>(pLayouts + NumSubresources);
  460. auto pNumRows = reinterpret_cast<UINT*>(pRowSizesInBytes + NumSubresources);
  461. auto Desc = pDestinationResource->GetDesc();
  462. static_driver->device->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, pLayouts, pNumRows, pRowSizesInBytes, &RequiredSize);
  463. UINT64 Result = UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, pLayouts, pNumRows, pRowSizesInBytes, pSrcData);
  464. HeapFree(GetProcessHeap(), 0, pMem);
  465. return Result;
  466. }
  467. #endif
  468. // ---- RESOURCES
  469. ID3D12Resource *HL_NAME(get_back_buffer)( int index ) {
  470. ID3D12Resource *buf = NULL;
  471. #ifndef HL_XBS
  472. static_driver->swapchain->GetBuffer(index, IID_PPV_ARGS(&buf));
  473. #else
  474. buf = static_driver->swapBuffers[index];
  475. #endif
  476. return buf;
  477. }
  478. ID3D12Resource *HL_NAME(create_committed_resource)( D3D12_HEAP_PROPERTIES *heapProperties, D3D12_HEAP_FLAGS heapFlags, D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initialState, D3D12_CLEAR_VALUE *clearValue ) {
  479. ID3D12Resource *res = NULL;
  480. #ifdef HL_XBS
  481. // In normal dx, INDIRECT_ARGUMENT is included in GENERIC_READ (but we never use it alone) , so we remove it to obtain GENERIC_READ in xbox
  482. initialState = (D3D12_RESOURCE_STATES)(initialState & ~D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT);
  483. #endif
  484. DXERR(static_driver->device->CreateCommittedResource(heapProperties, heapFlags, desc, initialState, clearValue, IID_PPV_ARGS(&res)));
  485. return res;
  486. }
  487. void HL_NAME(create_render_target_view)( ID3D12Resource *res, D3D12_RENDER_TARGET_VIEW_DESC *desc, D3D12_CPU_DESCRIPTOR_HANDLE descriptor ) {
  488. static_driver->device->CreateRenderTargetView(res,desc,descriptor);
  489. }
  490. void HL_NAME(create_depth_stencil_view)( ID3D12Resource *res, D3D12_DEPTH_STENCIL_VIEW_DESC *desc, D3D12_CPU_DESCRIPTOR_HANDLE descriptor ) {
  491. static_driver->device->CreateDepthStencilView(res,desc,descriptor);
  492. }
  493. void HL_NAME(create_constant_buffer_view)( D3D12_CONSTANT_BUFFER_VIEW_DESC *desc, D3D12_CPU_DESCRIPTOR_HANDLE descriptor ) {
  494. static_driver->device->CreateConstantBufferView(desc,descriptor);
  495. }
  496. void HL_NAME(create_unordered_access_view)( ID3D12Resource *res, ID3D12Resource *counter, D3D12_UNORDERED_ACCESS_VIEW_DESC *desc, D3D12_CPU_DESCRIPTOR_HANDLE descriptor ) {
  497. static_driver->device->CreateUnorderedAccessView(res,counter,desc,descriptor);
  498. }
  499. void HL_NAME(create_sampler)( D3D12_SAMPLER_DESC *desc, D3D12_CPU_DESCRIPTOR_HANDLE descriptor ) {
  500. static_driver->device->CreateSampler(desc,descriptor);
  501. }
  502. void HL_NAME(create_shader_resource_view)( ID3D12Resource *res, D3D12_SHADER_RESOURCE_VIEW_DESC *desc, D3D12_CPU_DESCRIPTOR_HANDLE descriptor ) {
  503. static_driver->device->CreateShaderResourceView(res,desc,descriptor);
  504. }
  505. int64 HL_NAME(resource_get_gpu_virtual_address)( ID3D12Resource *res ) {
  506. return res->GetGPUVirtualAddress();
  507. }
  508. void HL_NAME(resource_release)( IUnknown *res ) {
  509. res->Release();
  510. }
  511. void HL_NAME(resource_set_name)( ID3D12Resource *res, vbyte *name ) {
  512. res->SetName((LPCWSTR)name);
  513. }
  514. void *HL_NAME(resource_map)( ID3D12Resource *res, int subres, D3D12_RANGE *range ) {
  515. void *data = NULL;
  516. DXERR(res->Map(subres, range, &data));
  517. return data;
  518. }
  519. void HL_NAME(resource_unmap)( ID3D12Resource *res, int subres, D3D12_RANGE *range ) {
  520. res->Unmap(subres, range);
  521. }
  522. int64 HL_NAME(get_required_intermediate_size)( ID3D12Resource *res, int first, int count ) {
  523. auto desc = res->GetDesc();
  524. UINT64 size = 0;
  525. #ifndef HL_XBS
  526. static_driver->device->GetCopyableFootprints(&desc, first, count, 0, NULL, NULL, NULL, &size);
  527. #else
  528. D3D12_PLACED_SUBRESOURCE_FOOTPRINT pLayouts;
  529. static_driver->device->GetCopyableFootprints(&desc, first + count - 1, 1, 0, &pLayouts, NULL, NULL, &size);
  530. size += pLayouts.Offset;
  531. #endif
  532. return size;
  533. }
  534. bool HL_NAME(update_sub_resource)( ID3D12GraphicsCommandList *cmd, ID3D12Resource *res, ID3D12Resource *tmp, int64 tmpOffs, int first, int count, D3D12_SUBRESOURCE_DATA *data ) {
  535. #ifdef HL_XBS
  536. tmpOffs = 0;
  537. #endif
  538. return UpdateSubresources(cmd,res,tmp,(UINT64)tmpOffs,(UINT)first,(UINT)count,data) != 0;
  539. }
  540. void HL_NAME(get_copyable_footprints)( D3D12_RESOURCE_DESC *desc, int first, int count, int64 offset, D3D12_PLACED_SUBRESOURCE_FOOTPRINT *layouts, int *numRows, int64 *rowSizes, int64 *totalBytes ) {
  541. static_driver->device->GetCopyableFootprints(desc, first, count, offset, layouts, (UINT*)numRows, (UINT64*)rowSizes, (UINT64*)totalBytes);
  542. }
  543. DEFINE_PRIM(_VOID, create_render_target_view, _RES _STRUCT _I64);
  544. DEFINE_PRIM(_VOID, create_depth_stencil_view, _RES _STRUCT _I64);
  545. DEFINE_PRIM(_VOID, create_shader_resource_view, _RES _STRUCT _I64);
  546. DEFINE_PRIM(_VOID, create_constant_buffer_view, _STRUCT _I64);
  547. DEFINE_PRIM(_VOID, create_unordered_access_view, _RES _RES _STRUCT _I64);
  548. DEFINE_PRIM(_VOID, create_sampler, _STRUCT _I64);
  549. DEFINE_PRIM(_RES, create_committed_resource, _STRUCT _I32 _STRUCT _I32 _STRUCT);
  550. DEFINE_PRIM(_RES, get_back_buffer, _I32);
  551. DEFINE_PRIM(_VOID, resource_release, _RES);
  552. DEFINE_PRIM(_VOID, resource_set_name, _RES _BYTES);
  553. DEFINE_PRIM(_I64, resource_get_gpu_virtual_address, _RES);
  554. DEFINE_PRIM(_BYTES, resource_map, _RES _I32 _STRUCT);
  555. DEFINE_PRIM(_VOID, resource_unmap, _RES _I32 _STRUCT);
  556. DEFINE_PRIM(_I64, get_required_intermediate_size, _RES _I32 _I32);
  557. DEFINE_PRIM(_BOOL, update_sub_resource, _RES _RES _RES _I64 _I32 _I32 _STRUCT);
  558. DEFINE_PRIM(_VOID, get_copyable_footprints, _STRUCT _I32 _I32 _I64 _STRUCT _BYTES _BYTES _BYTES);
  559. // ---- SHADERS
  560. typedef struct {
  561. #ifndef HL_XBS
  562. IDxcLibrary *library;
  563. IDxcCompiler *compiler;
  564. #else
  565. IDxcUtils *utils;
  566. IDxcCompiler3 *compiler;
  567. #endif
  568. } dx_compiler;
  569. dx_compiler *HL_NAME(compiler_create)() {
  570. dx_compiler *comp = (dx_compiler*)hl_gc_alloc_raw(sizeof(dx_compiler));
  571. memset(comp,0,sizeof(dx_compiler));
  572. #ifndef HL_XBS
  573. CHKERR(DxcCreateInstance(CLSID_DxcLibrary, IID_PPV_ARGS(&comp->library)));
  574. CHKERR(DxcCreateInstance(CLSID_DxcCompiler, IID_PPV_ARGS(&comp->compiler)));
  575. #else
  576. CHKERR(DxcCreateInstance(CLSID_DxcUtils, IID_PPV_ARGS_OLD(&comp->utils)));
  577. CHKERR(DxcCreateInstance(CLSID_DxcCompiler, IID_PPV_ARGS_OLD(&comp->compiler)));
  578. #endif
  579. return comp;
  580. }
  581. vbyte *HL_NAME(compiler_compile)( dx_compiler *comp, uchar *source, uchar *profile, varray *args, int *dataLen ) {
  582. IDxcBlobEncoding *blob = NULL;
  583. IDxcOperationResult *result = NULL;
  584. #ifndef HL_XBS
  585. comp->library->CreateBlobWithEncodingFromPinned(source,(int)ustrlen(source)*2,1200/*DXC_CP_UTF16*/,&blob);
  586. #else
  587. comp->utils->CreateBlobFromPinned(source, (int)ustrlen(source) * 2, 1200/*DXC_CP_UTF16*/, &blob);
  588. #endif
  589. if( blob == NULL )
  590. hl_error("Could not create blob");
  591. #ifndef HL_XBS
  592. comp->compiler->Compile(blob,L"",L"main",profile,hl_aptr(args,LPCWSTR),args->size,NULL,0,NULL,&result);
  593. #else
  594. BOOL knownEncoding = FALSE;
  595. UINT32 encoding = 0U;
  596. blob->GetEncoding(&knownEncoding, &encoding);
  597. DxcBuffer dxcBuffer = { blob->GetBufferPointer(), blob->GetBufferSize(), encoding };
  598. std::vector<LPCWSTR> arguments(hl_aptr(args, LPCWSTR), hl_aptr(args, LPCWSTR) + args->size);
  599. arguments.insert(arguments.end(), { L"-E", L"main", L"-T", profile, L"-D", L"__XBOX_DISABLE_PRECOMPILE" });
  600. CHKERR(comp->compiler->Compile(&dxcBuffer, arguments.data(), arguments.size(), NULL, IID_PPV_ARGS_OLD(&result)));
  601. #endif
  602. HRESULT hr;
  603. result->GetStatus(&hr);
  604. if( !SUCCEEDED(hr) ) {
  605. IDxcBlobEncoding *error = NULL;
  606. result->GetErrorBuffer(&error);
  607. uchar *c = hl_to_utf16((char*)error->GetBufferPointer());
  608. blob->Release();
  609. result->Release();
  610. error->Release();
  611. hl_error("%s",c);
  612. }
  613. IDxcBlob *out = NULL;
  614. result->GetResult(&out);
  615. *dataLen = (int)out->GetBufferSize();
  616. vbyte *bytes = hl_copy_bytes((vbyte*)out->GetBufferPointer(), *dataLen);
  617. out->Release();
  618. blob->Release();
  619. result->Release();
  620. return bytes;
  621. }
  622. vbyte *HL_NAME(serialize_root_signature)( D3D12_ROOT_SIGNATURE_DESC *signature, D3D_ROOT_SIGNATURE_VERSION version, int *dataLen ) {
  623. ID3DBlob *data = NULL;
  624. ID3DBlob *error = NULL;
  625. HRESULT r = D3D12SerializeRootSignature(signature,version, &data, &error);
  626. if( !SUCCEEDED(r) ) {
  627. uchar *c = error ? hl_to_utf16((char*)error->GetBufferPointer()) : USTR("Invalid argument");
  628. if( error ) error->Release();
  629. hl_error("%s",c);
  630. }
  631. *dataLen = (int)data->GetBufferSize();
  632. vbyte *bytes = hl_copy_bytes((vbyte*)data->GetBufferPointer(), *dataLen);
  633. data->Release();
  634. return bytes;
  635. }
  636. ID3D12RootSignature *HL_NAME(rootsignature_create)( vbyte *bytes, int len ) {
  637. ID3D12RootSignature *sign = NULL;
  638. DXERR(static_driver->device->CreateRootSignature(CURRENT_NODEMASK, bytes, len, IID_PPV_ARGS(&sign)));
  639. return sign;
  640. }
  641. ID3D12PipelineState *HL_NAME(create_graphics_pipeline_state)( D3D12_GRAPHICS_PIPELINE_STATE_DESC *desc ) {
  642. ID3D12PipelineState *state = NULL;
  643. // if shader is considered invalid, maybe you're missing dxil.dll
  644. DXERR(static_driver->device->CreateGraphicsPipelineState(desc,IID_PPV_ARGS(&state)));
  645. return state;
  646. }
  647. ID3D12PipelineState *HL_NAME(create_compute_pipeline_state)( D3D12_COMPUTE_PIPELINE_STATE_DESC *desc ) {
  648. ID3D12PipelineState *state = NULL;
  649. // if shader is considered invalid, maybe you're missing dxil.dll
  650. DXERR(static_driver->device->CreateComputePipelineState(desc,IID_PPV_ARGS(&state)));
  651. return state;
  652. }
  653. ID3D12CommandSignature *HL_NAME(create_command_signature)( D3D12_COMMAND_SIGNATURE_DESC *desc, ID3D12RootSignature *rootSign ) {
  654. ID3D12CommandSignature *sign = NULL;
  655. DXERR(static_driver->device->CreateCommandSignature(desc,rootSign,IID_PPV_ARGS(&sign)));
  656. return sign;
  657. }
  658. #define _COMPILER _ABSTRACT(dx_compiler)
  659. DEFINE_PRIM(_COMPILER, compiler_create, _NO_ARG);
  660. DEFINE_PRIM(_BYTES, compiler_compile, _COMPILER _BYTES _BYTES _ARR _REF(_I32));
  661. DEFINE_PRIM(_BYTES, serialize_root_signature, _STRUCT _I32 _REF(_I32));
  662. DEFINE_PRIM(_RES, rootsignature_create, _BYTES _I32);
  663. DEFINE_PRIM(_RES, create_graphics_pipeline_state, _STRUCT);
  664. DEFINE_PRIM(_RES, create_compute_pipeline_state, _STRUCT);
  665. DEFINE_PRIM(_RES, create_command_signature, _STRUCT _RES);
  666. // ---- HEAPS
  667. ID3D12DescriptorHeap *HL_NAME(descriptor_heap_create)( D3D12_DESCRIPTOR_HEAP_DESC *desc ) {
  668. ID3D12DescriptorHeap *heap = NULL;
  669. DXERR(static_driver->device->CreateDescriptorHeap(desc,IID_PPV_ARGS(&heap)));
  670. return heap;
  671. }
  672. int HL_NAME(get_descriptor_handle_increment_size)( D3D12_DESCRIPTOR_HEAP_TYPE type ) {
  673. return static_driver->device->GetDescriptorHandleIncrementSize(type);
  674. }
  675. int64 HL_NAME(descriptor_heap_get_handle)( ID3D12DescriptorHeap *heap, bool gpu ) {
  676. UINT64 handle = gpu ? heap->GetGPUDescriptorHandleForHeapStart().ptr : heap->GetCPUDescriptorHandleForHeapStart().ptr;
  677. return handle;
  678. }
  679. ID3D12QueryHeap *HL_NAME(create_query_heap)( D3D12_QUERY_HEAP_DESC *desc ) {
  680. ID3D12QueryHeap *heap = NULL;
  681. DXERR(static_driver->device->CreateQueryHeap(desc,IID_PPV_ARGS(&heap)));
  682. return heap;
  683. }
  684. DEFINE_PRIM(_RES, descriptor_heap_create, _STRUCT);
  685. DEFINE_PRIM(_I32, get_descriptor_handle_increment_size, _I32);
  686. DEFINE_PRIM(_I64, descriptor_heap_get_handle, _RES _BOOL);
  687. DEFINE_PRIM(_RES, create_query_heap, _STRUCT);
  688. // ---- SYNCHRO
  689. ID3D12Fence *HL_NAME(fence_create)( int64 value, D3D12_FENCE_FLAGS flags ) {
  690. ID3D12Fence *f = NULL;
  691. DXERR(static_driver->device->CreateFence(value,flags, IID_PPV_ARGS(&f)));
  692. return f;
  693. }
  694. int64 HL_NAME(fence_get_completed_value)( ID3D12Fence *fence ) {
  695. return (int64)fence->GetCompletedValue();
  696. }
  697. void HL_NAME(fence_set_event)( ID3D12Fence *fence, int64 value, HANDLE event ) {
  698. fence->SetEventOnCompletion(value, event);
  699. }
  700. HANDLE HL_NAME(waitevent_create)( bool initState ) {
  701. return CreateEvent(NULL,FALSE,initState,NULL);
  702. }
  703. bool HL_NAME(waitevent_wait)( HANDLE event, int time ) {
  704. return WaitForSingleObject(event,time) == 0;
  705. }
  706. #define _EVENT _ABSTRACT(dx_event)
  707. DEFINE_PRIM(_RES, fence_create, _I64 _I32);
  708. DEFINE_PRIM(_I64, fence_get_completed_value, _RES);
  709. DEFINE_PRIM(_VOID, fence_set_event, _RES _I64 _EVENT);
  710. DEFINE_PRIM(_EVENT, waitevent_create, _BOOL);
  711. DEFINE_PRIM(_BOOL, waitevent_wait, _EVENT _I32);
  712. // ---- COMMANDS
  713. ID3D12CommandAllocator *HL_NAME(command_allocator_create)( D3D12_COMMAND_LIST_TYPE type ) {
  714. ID3D12CommandAllocator *a = NULL;
  715. DXERR(static_driver->device->CreateCommandAllocator(type,IID_PPV_ARGS(&a)));
  716. return a;
  717. }
  718. void HL_NAME(command_allocator_reset)( ID3D12CommandAllocator *a ) {
  719. CHKERR(a->Reset());
  720. }
  721. ID3D12GraphicsCommandList *HL_NAME(command_list_create)( D3D12_COMMAND_LIST_TYPE type, ID3D12CommandAllocator *alloc, ID3D12PipelineState *initState ) {
  722. ID3D12GraphicsCommandList *l = NULL;
  723. DXERR(static_driver->device->CreateCommandList(CURRENT_NODEMASK,type,alloc,initState,IID_PPV_ARGS(&l)));
  724. return l;
  725. }
  726. void HL_NAME(command_list_close)( ID3D12GraphicsCommandList *l ) {
  727. CHKERR(l->Close());
  728. }
  729. void HL_NAME(command_list_reset)( ID3D12GraphicsCommandList *l, ID3D12CommandAllocator *alloc, ID3D12PipelineState *state ) {
  730. CHKERR(l->Reset(alloc,state));
  731. }
  732. void HL_NAME(command_list_execute)( ID3D12GraphicsCommandList *l ) {
  733. ID3D12CommandList* const commandLists[] = { l };
  734. static_driver->commandQueue->ExecuteCommandLists(1, commandLists);
  735. }
  736. void HL_NAME(command_list_resource_barrier)( ID3D12GraphicsCommandList *l, D3D12_RESOURCE_BARRIER *barrier ) {
  737. l->ResourceBarrier(1,barrier);
  738. }
  739. void HL_NAME(command_list_clear_render_target_view)( ID3D12GraphicsCommandList *l, D3D12_CPU_DESCRIPTOR_HANDLE view, FLOAT *colors ) {
  740. l->ClearRenderTargetView(view,colors,0,NULL);
  741. }
  742. void HL_NAME(command_list_clear_depth_stencil_view)( ID3D12GraphicsCommandList *l, D3D12_CPU_DESCRIPTOR_HANDLE view, D3D12_CLEAR_FLAGS flags, FLOAT depth, int stencil ) {
  743. l->ClearDepthStencilView(view,flags,depth,(UINT8)stencil,0,NULL);
  744. }
  745. void HL_NAME(command_list_draw_instanced)( ID3D12GraphicsCommandList *l, int vertexCountPerInstance, int instanceCount, int startVertexLocation, int startInstanceLocation ) {
  746. l->DrawInstanced(vertexCountPerInstance, instanceCount, startVertexLocation, startInstanceLocation);
  747. }
  748. void HL_NAME(command_list_draw_indexed_instanced)( ID3D12GraphicsCommandList *l, int indexCountPerInstance, int instanceCount, int startIndexLocation, int baseVertexLocation, int startInstanceLocation ) {
  749. l->DrawIndexedInstanced(indexCountPerInstance, instanceCount, startIndexLocation, baseVertexLocation, startInstanceLocation);
  750. }
  751. void HL_NAME(command_list_set_graphics_root_signature)( ID3D12GraphicsCommandList *l, ID3D12RootSignature *sign ) {
  752. l->SetGraphicsRootSignature(sign);
  753. }
  754. void HL_NAME(command_list_set_graphics_root32_bit_constants)( ID3D12GraphicsCommandList *l, int index, int numValues, void *data, int destOffset ) {
  755. l->SetGraphicsRoot32BitConstants(index, numValues, data, destOffset);
  756. }
  757. void HL_NAME(command_list_set_pipeline_state)( ID3D12GraphicsCommandList *l, ID3D12PipelineState *pipe ) {
  758. l->SetPipelineState(pipe);
  759. }
  760. void HL_NAME(command_list_ia_set_vertex_buffers)( ID3D12GraphicsCommandList *l, int startSlot, int numViews, D3D12_VERTEX_BUFFER_VIEW *views ) {
  761. l->IASetVertexBuffers(startSlot, numViews, views);
  762. }
  763. void HL_NAME(command_list_ia_set_index_buffer)( ID3D12GraphicsCommandList *l, D3D12_INDEX_BUFFER_VIEW *view ) {
  764. l->IASetIndexBuffer(view);
  765. }
  766. void HL_NAME(command_list_ia_set_primitive_topology)( ID3D12GraphicsCommandList *l, D3D12_PRIMITIVE_TOPOLOGY topo ) {
  767. l->IASetPrimitiveTopology(topo);
  768. }
  769. void HL_NAME(command_list_copy_buffer_region)( ID3D12GraphicsCommandList *l, ID3D12Resource *dst, int64 dstOffset, ID3D12Resource *src, int64 srcOffset, int64 numBytes ) {
  770. l->CopyBufferRegion(dst, dstOffset, src, srcOffset, numBytes);
  771. }
  772. void HL_NAME(command_list_copy_texture_region)( ID3D12GraphicsCommandList *l, D3D12_TEXTURE_COPY_LOCATION *dst, int dstX, int dstY, int dstZ, D3D12_TEXTURE_COPY_LOCATION *src, D3D12_BOX *srcBox ) {
  773. l->CopyTextureRegion(dst, dstX, dstY, dstZ, src, srcBox);
  774. }
  775. void HL_NAME(command_list_om_set_render_targets)( ID3D12GraphicsCommandList *l, int count, D3D12_CPU_DESCRIPTOR_HANDLE *handles, BOOL flag, D3D12_CPU_DESCRIPTOR_HANDLE *depthStencils ) {
  776. l->OMSetRenderTargets(count,handles,flag,depthStencils);
  777. }
  778. void HL_NAME(command_list_om_set_stencil_ref)( ID3D12GraphicsCommandList *l, int value ) {
  779. l->OMSetStencilRef(value);
  780. }
  781. void HL_NAME(command_list_rs_set_viewports)( ID3D12GraphicsCommandList *l, int count, D3D12_VIEWPORT *viewports ) {
  782. l->RSSetViewports(count, viewports);
  783. }
  784. void HL_NAME(command_list_rs_set_scissor_rects)( ID3D12GraphicsCommandList *l, int count, D3D12_RECT *rects ) {
  785. l->RSSetScissorRects(count, rects);
  786. }
  787. void HL_NAME(command_list_set_descriptor_heaps)( ID3D12GraphicsCommandList *l, varray *heaps ) {
  788. l->SetDescriptorHeaps(heaps->size,hl_aptr(heaps,ID3D12DescriptorHeap*));
  789. }
  790. void HL_NAME(command_list_set_graphics_root_constant_buffer_view)( ID3D12GraphicsCommandList *l, int index, D3D12_GPU_VIRTUAL_ADDRESS address ) {
  791. l->SetGraphicsRootConstantBufferView(index,address);
  792. }
  793. void HL_NAME(command_list_set_graphics_root_descriptor_table)( ID3D12GraphicsCommandList *l, int index, D3D12_GPU_DESCRIPTOR_HANDLE handle ) {
  794. l->SetGraphicsRootDescriptorTable(index,handle);
  795. }
  796. void HL_NAME(command_list_set_graphics_root_shader_resource_view)( ID3D12GraphicsCommandList *l, int index, D3D12_GPU_VIRTUAL_ADDRESS handle ) {
  797. l->SetGraphicsRootShaderResourceView(index,handle);
  798. }
  799. void HL_NAME(command_list_set_graphics_root_unordered_access_view)( ID3D12GraphicsCommandList *l, int index, D3D12_GPU_VIRTUAL_ADDRESS handle ) {
  800. l->SetGraphicsRootUnorderedAccessView(index,handle);
  801. }
  802. void HL_NAME(command_list_execute_indirect)( ID3D12GraphicsCommandList *l, ID3D12CommandSignature *sign, int maxCommandCount, ID3D12Resource *args, int64 argsOffset, ID3D12Resource *count, int64 countOffset ) {
  803. l->ExecuteIndirect(sign, maxCommandCount, args, argsOffset, count, countOffset);
  804. }
  805. void HL_NAME(command_list_begin_query)( ID3D12GraphicsCommandList *l, ID3D12QueryHeap *heap, D3D12_QUERY_TYPE type, int index ) {
  806. l->BeginQuery(heap, type, index);
  807. }
  808. void HL_NAME(command_list_end_query)( ID3D12GraphicsCommandList *l, ID3D12QueryHeap *heap, D3D12_QUERY_TYPE type, int index ) {
  809. l->EndQuery(heap, type, index);
  810. }
  811. void HL_NAME(command_list_resolve_query_data)( ID3D12GraphicsCommandList *l, ID3D12QueryHeap *heap, D3D12_QUERY_TYPE type, int index, int count, ID3D12Resource *dest, int64 offset ) {
  812. l->ResolveQueryData(heap,type,index,count,dest,offset);
  813. }
  814. void HL_NAME(command_list_set_predication)( ID3D12GraphicsCommandList *l, ID3D12Resource *res, int64 offset, D3D12_PREDICATION_OP op ) {
  815. l->SetPredication(res,offset,op);
  816. }
  817. void HL_NAME(command_list_set_compute_root_signature)( ID3D12GraphicsCommandList *l, ID3D12RootSignature *sign ) {
  818. l->SetComputeRootSignature(sign);
  819. }
  820. void HL_NAME(command_list_set_compute_root32_bit_constants)( ID3D12GraphicsCommandList *l, int index, int numValues, void *data, int destOffset ) {
  821. l->SetComputeRoot32BitConstants(index, numValues, data, destOffset);
  822. }
  823. void HL_NAME(command_list_set_compute_root_constant_buffer_view)( ID3D12GraphicsCommandList *l, int index, D3D12_GPU_VIRTUAL_ADDRESS address ) {
  824. l->SetComputeRootConstantBufferView(index,address);
  825. }
  826. void HL_NAME(command_list_set_compute_root_descriptor_table)( ID3D12GraphicsCommandList *l, int index, D3D12_GPU_DESCRIPTOR_HANDLE handle ) {
  827. l->SetComputeRootDescriptorTable(index,handle);
  828. }
  829. void HL_NAME(command_list_set_compute_root_shader_resource_view)( ID3D12GraphicsCommandList *l, int index, D3D12_GPU_VIRTUAL_ADDRESS handle ) {
  830. l->SetComputeRootShaderResourceView(index,handle);
  831. }
  832. void HL_NAME(command_list_set_compute_root_unordered_access_view)( ID3D12GraphicsCommandList *l, int index, D3D12_GPU_VIRTUAL_ADDRESS handle ) {
  833. l->SetComputeRootUnorderedAccessView(index,handle);
  834. }
  835. void HL_NAME(command_list_dispatch)( ID3D12GraphicsCommandList *l, int x, int y, int z ) {
  836. l->Dispatch(x,y,z);
  837. }
  838. DEFINE_PRIM(_RES, command_allocator_create, _I32);
  839. DEFINE_PRIM(_VOID, command_allocator_reset, _RES);
  840. DEFINE_PRIM(_RES, command_list_create, _I32 _RES _RES);
  841. DEFINE_PRIM(_VOID, command_list_close, _RES);
  842. DEFINE_PRIM(_VOID, command_list_reset, _RES _RES _RES);
  843. DEFINE_PRIM(_VOID, command_list_resource_barrier, _RES _STRUCT);
  844. DEFINE_PRIM(_VOID, command_list_execute, _RES);
  845. DEFINE_PRIM(_VOID, command_list_clear_render_target_view, _RES _I64 _STRUCT);
  846. DEFINE_PRIM(_VOID, command_list_clear_depth_stencil_view, _RES _I64 _I32 _F32 _I32);
  847. DEFINE_PRIM(_VOID, command_list_draw_instanced, _RES _I32 _I32 _I32 _I32);
  848. DEFINE_PRIM(_VOID, command_list_draw_indexed_instanced, _RES _I32 _I32 _I32 _I32 _I32);
  849. DEFINE_PRIM(_VOID, command_list_set_graphics_root_signature, _RES _RES);
  850. DEFINE_PRIM(_VOID, command_list_set_graphics_root32_bit_constants, _RES _I32 _I32 _BYTES _I32);
  851. DEFINE_PRIM(_VOID, command_list_set_graphics_root_constant_buffer_view, _RES _I32 _I64);
  852. DEFINE_PRIM(_VOID, command_list_set_graphics_root_descriptor_table, _RES _I32 _I64);
  853. DEFINE_PRIM(_VOID, command_list_set_graphics_root_shader_resource_view, _RES _I32 _I64);
  854. DEFINE_PRIM(_VOID, command_list_set_graphics_root_unordered_access_view, _RES _I32 _I64);
  855. DEFINE_PRIM(_VOID, command_list_set_descriptor_heaps, _RES _ARR);
  856. DEFINE_PRIM(_VOID, command_list_set_pipeline_state, _RES _RES);
  857. DEFINE_PRIM(_VOID, command_list_ia_set_vertex_buffers, _RES _I32 _I32 _STRUCT);
  858. DEFINE_PRIM(_VOID, command_list_ia_set_index_buffer, _RES _STRUCT);
  859. DEFINE_PRIM(_VOID, command_list_ia_set_primitive_topology, _RES _I32);
  860. DEFINE_PRIM(_VOID, command_list_copy_buffer_region, _RES _RES _I64 _RES _I64 _I64);
  861. DEFINE_PRIM(_VOID, command_list_copy_texture_region, _RES _STRUCT _I32 _I32 _I32 _STRUCT _STRUCT);
  862. DEFINE_PRIM(_VOID, command_list_om_set_render_targets, _RES _I32 _BYTES _I32 _BYTES);
  863. DEFINE_PRIM(_VOID, command_list_om_set_stencil_ref, _RES _I32);
  864. DEFINE_PRIM(_VOID, command_list_rs_set_viewports, _RES _I32 _STRUCT);
  865. DEFINE_PRIM(_VOID, command_list_rs_set_scissor_rects, _RES _I32 _STRUCT);
  866. DEFINE_PRIM(_VOID, command_list_execute_indirect, _RES _RES _I32 _RES _I64 _RES _I64);
  867. DEFINE_PRIM(_VOID, command_list_begin_query, _RES _RES _I32 _I32);
  868. DEFINE_PRIM(_VOID, command_list_end_query, _RES _RES _I32 _I32);
  869. DEFINE_PRIM(_VOID, command_list_resolve_query_data, _RES _RES _I32 _I32 _I32 _RES _I64);
  870. DEFINE_PRIM(_VOID, command_list_set_predication, _RES _RES _I64 _I32);
  871. DEFINE_PRIM(_VOID, command_list_set_compute_root_signature, _RES _RES);
  872. DEFINE_PRIM(_VOID, command_list_set_compute_root32_bit_constants, _RES _I32 _I32 _BYTES _I32);
  873. DEFINE_PRIM(_VOID, command_list_set_compute_root_constant_buffer_view, _RES _I32 _I64);
  874. DEFINE_PRIM(_VOID, command_list_set_compute_root_descriptor_table, _RES _I32 _I64);
  875. DEFINE_PRIM(_VOID, command_list_set_compute_root_shader_resource_view, _RES _I32 _I64);
  876. DEFINE_PRIM(_VOID, command_list_set_compute_root_unordered_access_view, _RES _I32 _I64);
  877. DEFINE_PRIM(_VOID, command_list_dispatch, _RES _I32 _I32 _I32);
  878. //command_list_clear_unordered_access_view_float,
  879. //command_list_clear_unordered_access_view_uint,