DirectX12 ⑦ 定数バッファの作成

定数バッファの作成

環境

言語 : C++
開発環境 : Visual Studio 2020
OS : Windows10
CPU : AMD Ryzen5 3600
RAM : 24.0GB
GPU : NVIDIA GeForce GTX 1050

ソースコード

DxStruct.h

#pragma once

#include <DirectXMath.h>
#include <vector>

struct alignas(256) Transform {
    DirectX::XMMATRIX   World;      // ワールド行列
    DirectX::XMMATRIX   View;       // ビュー行列
    DirectX::XMMATRIX   Proj;       // 射影行列
};

struct Vertex {
    DirectX::XMFLOAT3 Position;     //座標
    DirectX::XMFLOAT4 Color;        //色
};

ConstantBuffer.h

#pragma once

#include <d3d12.h>
#include <cstdint>
#include <wrl/client.h>
#include <iostream>

#include "Dx.h"
#include "DxStruct.h"

#pragma comment(lib, "d3d12.lib")

class ConstantBuffer
{
public:
    ConstantBuffer();
    bool CreateConstantBuffer(size_t size);

    D3D12_GPU_VIRTUAL_ADDRESS GetAddress() const;
    D3D12_CONSTANT_BUFFER_VIEW_DESC GetConstantBufferView();

    void* GetPtr() const;

    template<typename T>
    T* GetPtr() {
        return reinterpret_cast<T*>(GetPtr());
    }

private:
    ComPtr<ID3D12Resource> _pBuffer;
    D3D12_CONSTANT_BUFFER_VIEW_DESC _viewDesc;

    void* _ptr;
};

ConstantBuffer.cpp

#include "ConstantBuffer.h"

ConstantBuffer::ConstantBuffer() {
    _viewDesc = {};
    _ptr = nullptr;
}

//定数バッファの作成
bool ConstantBuffer::CreateConstantBuffer(size_t size) {
    size_t align = D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT;
    uint64_t sizeAligned = (size + (align - 1)) & ~(align - 1); //アライメント
    
    //ヒーププロパティ
    D3D12_HEAP_PROPERTIES heapProp = {};
    heapProp.Type = D3D12_HEAP_TYPE_UPLOAD;
    heapProp.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
    heapProp.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
    heapProp.CreationNodeMask = 1;
    heapProp.VisibleNodeMask = 1;

    //バッファの設定
    D3D12_RESOURCE_DESC desc = {};
    desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
    desc.Alignment = 0;
    desc.Width = sizeAligned;
    desc.Height = 1;
    desc.DepthOrArraySize = 1;
    desc.MipLevels = 1;
    desc.Format = DXGI_FORMAT_UNKNOWN;
    desc.SampleDesc.Count = 1;
    desc.SampleDesc.Quality = 0;
    desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
    desc.Flags = D3D12_RESOURCE_FLAG_NONE;

    //バッファの作成
    HRESULT hResult;
    hResult = dx->GetDevice()->CreateCommittedResource(&heapProp, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(_pBuffer.GetAddressOf()));
    if (FAILED(hResult)) {
        std::cout << "Failed to create ConstantBuffer" << std::endl;
        return false;
    }

    //マッピング
    hResult = _pBuffer->Map(0, nullptr, &_ptr);
    if (FAILED(hResult)) {
        std::cout << "Failed mapping ConstantBuffer" << std::endl;
        return false;
    }

    _viewDesc = {};
    _viewDesc.BufferLocation = _pBuffer->GetGPUVirtualAddress();
    _viewDesc.SizeInBytes = uint32_t(sizeAligned);

    return true;
}

//アドレスを取得
D3D12_GPU_VIRTUAL_ADDRESS ConstantBuffer::GetAddress() const {
    return _viewDesc.BufferLocation;
}

//バッファビューを取得
D3D12_CONSTANT_BUFFER_VIEW_DESC ConstantBuffer::GetConstantBufferView() {
    return _viewDesc;
}

//ポインタを取得
void* ConstantBuffer::GetPtr() const {
    return _ptr;
}

参考資料

書籍

サイト

qiita.com

learn.microsoft.com