Home > Net >  DX12) Part of the Constants buffer is cut off
DX12) Part of the Constants buffer is cut off

Time:04-06

enter image description here

enter image description here

This is my Constant buffer for Object Drawing. actually, gWorld and gOldWorld have correct values, but gCubemapOn, gMotionBlurOn, gRimLightOn values are going wrong.

gCubemapOn must be TRUE and it looks like, but actually that value is 65537. and gRimLightOn must be TRUE, but as you see, actual value is FALSE.

The code below is how I use Constant Buffer.

template<typename Cnst>
class ConstantBuffer
{
public:
    ConstantBuffer(ID3D12Device* device, UINT count, bool isConstant=true)
    {   
        if (isConstant)
            mByteSize = (sizeof(Cnst)   255) & ~255;
        else
            mByteSize = sizeof(Cnst);

        ThrowIfFailed(device->CreateCommittedResource(
            &Extension::HeapProperties(D3D12_HEAP_TYPE_UPLOAD),
            D3D12_HEAP_FLAG_NONE,
            &Extension::BufferResourceDesc(D3D12_RESOURCE_DIMENSION_BUFFER, mByteSize * count),
            D3D12_RESOURCE_STATE_GENERIC_READ,
            nullptr, IID_PPV_ARGS(&mUploadBuffer)));

        ThrowIfFailed(mUploadBuffer->Map(0, nullptr, (void**)(&mData)));
    }
    ConstantBuffer(const ConstantBuffer& rhs) = delete;
    ConstantBuffer& operator=(const ConstantBuffer& rhs) = delete;
    virtual ~ConstantBuffer()
    {
        if (mUploadBuffer)
            mUploadBuffer->Unmap(0, nullptr);
        mData = nullptr;
    }

    D3D12_GPU_VIRTUAL_ADDRESS GetGPUVirtualAddress(int idx) const
    {
        return mUploadBuffer->GetGPUVirtualAddress()   idx * mByteSize;
    }

    void CopyData(int index, const Cnst& data)
    {
        memcpy(&mData[index * mByteSize], &data, sizeof(Cnst));
    }

    UINT GetByteSize() const
    {
        return mByteSize;
    }

private:
    ComPtr<ID3D12Resource> mUploadBuffer = nullptr;
    BYTE* mData = nullptr;
    UINT mByteSize = 0;
};

and this is how I Update Constant Buffer

void Pipeline::UpdateConstants()
{
    UINT matOffset = 0;
    for (int i = 0; i < mRenderObjects.size(); i  )
    {
        mObjectCB->CopyData(i, mRenderObjects[i]->GetObjectConstants());
        mRenderObjects[i]->UpdateMatConstants(mMaterialCB.get(), matOffset);        
        matOffset  = mRenderObjects[i]->GetMeshCount();
    }
}
ObjectConstants GameObject::GetObjectConstants()
{
    ObjectConstants objCnst = {};
    if (mReflected)
    {
        objCnst.World = Matrix4x4::Transpose(Matrix4x4::Multiply(mWorld, mReflectMatrix));
        objCnst.oldWorld = Matrix4x4::Transpose(Matrix4x4::Multiply(mOldWorld, mReflectMatrix));
    }
    else
    {
        objCnst.World = Matrix4x4::Transpose(mWorld);
        objCnst.oldWorld = Matrix4x4::Transpose(mOldWorld);
    }
    objCnst.cubemapOn = mCubemapOn;
    objCnst.motionBlurOn = mMotionBlurOn;
    objCnst.rimLightOn = mRimLightOn;

    return objCnst;
}
struct ObjectConstants
{
    XMFLOAT4X4 World;
    XMFLOAT4X4 oldWorld;
    bool cubemapOn;
    bool motionBlurOn;
    bool rimLightOn;
};

CodePudding user response:

I believe this is the same problem as seen here. HLSL bool is 4 bytes and C bool is 1 byte. If you declare your CPU struct as

struct ObjectConstants
{
    XMFLOAT4X4 World;
    XMFLOAT4X4 oldWorld;
    int32_t cubemapOn;
    int32_t motionBlurOn;
    int32_t rimLightOn;
};

it should work.

  • Related