dx12.cpp 40 KB

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