SetGraphicsRootConstantBufferview: Pointer 190513344 неверно выровнен. Как исправить эту ошибку?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 SetGraphicsRootConstantBufferview: Pointer 190513344 неверно выровнен. Как исправить эту ошибку?

Сообщение Anonymous »

код:

Код: Выделить всё

void RenderShadowMaps::Render(D3D12_GPU_VIRTUAL_ADDRESS lightGPUVirtualAdress, ID3D12GraphicsCommandList* commandList)
{
commandList->SetGraphicsRootSignature(m_rootSignature);
commandList->SetPipelineState(m_PSO);
commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

commandList->SetGraphicsRootConstantBufferView(0, LightConstantBufferSingleton::instance()->getLightCountUploadHeap()->GetGPUVirtualAddress());
commandList->SetGraphicsRootConstantBufferView(1, LightConstantBufferSingleton::instance()->getMainUploadHeap()->GetGPUVirtualAddress());
commandList->SetGraphicsRootConstantBufferView(2, lightGPUVirtualAdress);

//...
}
< /code>
строка, вызывающая ошибку. У меня есть массив огней, и мне нужно получить доступ к светам индивидуально: < /p>
    commandList->SetGraphicsRootConstantBufferView(2, lightGPUVirtualAdress);
Как вычисляется LightgpuvirtualAdress?

Код: Выделить всё

std::vector LightConstantBuffer::getMainLightGPUVirtualAddresses(const Scene::BaseScene& scene)
{
const auto& lights = scene.getLights();
_ASSERT(lights.size());

std::vector ret;
ret.reserve(lights.size());

for (uint32_t i = 0u; i < lights.size(); ++i)
{
ret.push_back(m_mainLightCBUploadHeap->GetGPUVirtualAddress() + i * sizeof(DX12Light));
}

return ret;
}
Здесь dx12light struct: [/b]

Код: Выделить всё

__declspec(align(16)) struct DX12Light
{
DirectX::XMFLOAT4 position;
DirectX::XMFLOAT4 direction;
DirectX::XMFLOAT4 color;

DirectX::XMFLOAT4X4 transform1;
DirectX::XMFLOAT4X4 transform2;

FLOAT range;
INT type;
INT linearIdx;
};
< /code>
Буфер света: < /p>
struct LightMainCB
{
DX12Light lights[Graphics::Light::MaxLightsPerScene];
};
< /code>
so hlsl side (постоянный буфер на данный момент, возможно, переключится на структурированный буфер в будущем): < /p>
struct DX12Light
{
float4 position;
float4 direction;
float4 color;

float4x4 transform1;
float4x4 transform2;

float range;
int type;
int linearIdx;
};

cbuffer LightCountCB : register(b0)
{
int NbLights;
};

cbuffer LightMainCB : register(b1)
{
DX12Light Lights[MAX_LIGHTS];
};
< /code>
Я разделил количество света и освещение на 2 буфера, думая, что он решит ошибку, но это не так. HRESULT hr = D3D12Device->CreateCommittedResource(&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
D3D12_HEAP_FLAG_NONE,
&CD3DX12_RESOURCE_DESC::Buffer(MainLightCBAlignedSize),
D3D12_RESOURCE_STATE_GENERIC_READ,
nullptr,
IID_PPV_ARGS(&m_mainLightCBUploadHeap));
//#define _ALIGN_SIZE(x) (sizeof(x) + (D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT - 1)) & ~(D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT - 1)
//const nbUint32 MainLightCBAlignedSize = _ALIGN_SIZE(LightMainCB);

_ASSERT(SUCCEEDED(hr));
m_mainLightCBUploadHeap->SetName(L"Main lights constant buffer upload heap");

hr = m_mainLightCBUploadHeap->Map(0, &ReadRangeGPUOnly, reinterpret_cast(&m_mainLightCBGPUAddress));
_ASSERT(SUCCEEDED(hr));
Что я делаю неправильно с выравниванием?

Код: Выделить всё

struct DX12Light
{
DirectX::XMFLOAT4 position;
DirectX::XMFLOAT4 direction;
DirectX::XMFLOAT4 color;

DirectX::XMFLOAT4X4 transform1;
DirectX::XMFLOAT4X4 transform2;

FLOAT range;
INT type;
INT linearIdx;

INT padding[17];
};
Ошибка исчезла, но мое освещение, которое зацикливается на массиве света. Вот как обновляются огни от хоста на устройство: < /p>

Код: Выделить всё

void LightConstantBuffer::updateLight(const Scene::BaseScene& scene, const EntityIdentifier& lightId, ID3D12GraphicsCommandList* commandList)
{
const EntityIdentifierArray& lights = scene.getLights();

int lightLinearIdx = 0;

for (const auto& entityId : lights)
{
if (entityId == lightId)
{
updateLightEntry(scene, lightId, lightLinearIdx);// m_mainLightTransientBUffer.lights[lightLinearIdx] is updated here.
memcpy(m_mainLightCBGPUAddress + lightLinearIdx * sizeof(DX12Light), &m_mainLightTransientBUffer.lights[lightLinearIdx], sizeof(DX12Light));

break;
}

++lightLinearIdx;
}
}
с этим освещением работает должным образом [/b], но когда мне нужно получить доступ к светам индивидуально (рендеринг теневой карты), как упоминалось ранее.>

Подробнее здесь: https://stackoverflow.com/questions/796 ... ligned-how
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»