DirectX12 - Heap and Resource(堆和资源)

这里是SunshineBooming,GPU公司一枚小小的Driver工程师,主要工作是写DirectX12 Driver,我会持续更新这个DX12 Spec系列,可能比较冷门,但是都是干货和工作中的心得体会,有任何GPU相关的问题都可以在评论区互动,知无不言:

DirectX12 Spec 总目录

1. Heap

1.1 什么是Heap?

  • A memory allocation that enables resource recycling without any kernel
    component’s awareness.
  • 我们都知道GPU驱动渲染图像最终调用的,都是底层Memory中存储的数据,这里Heap就是对于底层Memory存储的抽象。

2. Resource

1.1 什么是Resource?

  • Resources are the D3D concept which abstracts GPU accessible memory. Such memory must be made resident for the GPU to access it, as the operating system virtualizes the GPU and memory for all processes to use.
  • Resource是对于Heap的再抽象。如果说Heap是对应于底层Hearware的概念,那么Resource就是面向User的概念。Heap先分配出实体的Memory,然后再将Resource绑定到Heap上面,Resource和Heap之间则有多种对应关系。
    HeapAndResource

1.2 Resource类型

  • 按照Resource和Heap之间的对应关系,可以将Resource区分成3中类型:Commited Resource/Reserved Resource/Placed Resource。

1.2.1 Committed Resource

  • Committed resources are the most common idea of D3D resources over the generations. Creating such a resource allocates virtual address range, an implicit heap large enough to fit the whole resource, and commits the virtual address range to the physical memory encapsulated by the heap.
  • Resource在创建的时候,与Heap一一对应,而Heap与GPU Memory相对应。也就是说,如果创建一块n字节大小的Committed Resource,GPU Driver则会预留一块n字节大小的GPU Memory。
    CommittedResource

1.2.2 Reserved Resource

  • Reserved resources are equivalent to D3D11 tiled resources. On their creation, only a virtual address range is allocated and not mapped to any heap. The application will map such resources to heaps later.
  • Resource在创建时,并不会绑定到对应的Heap上面,用户可以在API层调用CreateHeap()创建一块Heap,然后调用UpdateTileMappings()接口将Resource与Heap进行绑定。
  • 需要注意的是,一块Reserved Resource中的SubResource可以与不同的Heap进行绑定,也就是Reserved Resource与Heap可以是一对多的映射关系:
    ResercedResource

1.2.3 Placed Resource

  • With places resources you create the heap separately, and then specify where a resource is located within that heap. This lets you have multiple resources packed into a single heap, potentially even overlapping with each other.
  • Resource在创建的时候,需要绑定到对应的Heap上面(事先用CreateHeap()创建好),值得注意的是,Placed Resource与Heap之间可以是多对一的关系,也就是多个Placed Resource可以绑定到同一块Heap上面,每个Placed Resource对应于Heap上面不同的Sub Range,并且这些Sub Range可以Overlap:
    PlacedResource
  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
以下是使用 DirectX 12 编写的 "Hello World" 示例代码: ```cpp #include <windows.h> #include <d3d12.h> #include <dxgi1_4.h> #pragma comment(lib, "d3d12.lib") #pragma comment(lib, "dxgi.lib") int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // 创建窗口 HWND hWnd = CreateWindowEx(0, L"static", L"DirectX12 HelloWorld", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, nullptr, nullptr, hInstance, nullptr); // 初始化 DirectX 12 IDXGIFactory4* dxgiFactory = nullptr; HRESULT hr = CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory)); if (FAILED(hr)) return 1; IDXGIAdapter1* adapter = nullptr; for (UINT adapterIndex = 0; DXGI_ERROR_NOT_FOUND != dxgiFactory->EnumAdapters1(adapterIndex, &adapter); ++adapterIndex) { DXGI_ADAPTER_DESC1 adapterDesc; adapter->GetDesc1(&adapterDesc); if (adapterDesc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) { continue; } // 创建设备 hr = D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&device)); if (FAILED(hr)) return 1; // 退出循环 break; } // 创建命令队列 D3D12_COMMAND_QUEUE_DESC queueDesc = {}; queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; hr = device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&commandQueue)); if (FAILED(hr)) return 1; // 创建交换链 DXGI_MODE_DESC backBufferDesc = {}; backBufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; backBufferDesc.Width = 640; backBufferDesc.Height = 480; backBufferDesc.RefreshRate.Numerator = 60; backBufferDesc.RefreshRate.Denominator = 1; backBufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; backBufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; DXGI_SWAP_CHAIN_DESC swapChainDesc = {}; swapChainDesc.BufferCount = 2; swapChainDesc.BufferDesc = backBufferDesc; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.OutputWindow = hWnd; swapChainDesc.SampleDesc.Count = 1; swapChainDesc.Windowed = TRUE; IDXGISwapChain* swapChain = nullptr; hr = dxgiFactory->CreateSwapChain(commandQueue, &swapChainDesc, &swapChain); if (FAILED(hr)) return 1; // 创建渲染目标视图 ID3D12Resource* backBuffer = nullptr; hr = swapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer)); if (FAILED(hr)) return 1; D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {}; heapDesc.NumDescriptors = 1; heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; ID3D12DescriptorHeap* rtvHeap = nullptr; hr = device->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&rtvHeap)); if (FAILED(hr)) return 1; CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(rtvHeap->GetCPUDescriptorHandleForHeapStart()); device->CreateRenderTargetView(backBuffer, nullptr, rtvHandle); // 渲染循环 MSG msg = {}; while (msg.message != WM_QUIT) { if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } else { // 清除后台缓冲区 float clearColor[] = { 0.0f, 0.2f, 0.4f, 1.0f }; commandList->ClearRenderTargetView(rtvHandle, clearColor, 0, nullptr); // 切换后台缓冲区 hr = swapChain->Present(1, 0); if (FAILED(hr)) return 1; } } return 0; } ``` 这段代码创建了一个包含一个后台缓冲区的窗口,并在该缓冲区内清除颜色并显示它。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值