Cache buffer device address.

This commit is contained in:
Skyth 2024-10-07 21:01:46 +03:00
parent c07b827a5e
commit 53f4f1058f

View file

@ -178,6 +178,14 @@ struct UploadBuffer
std::unique_ptr<RenderBuffer> buffer; std::unique_ptr<RenderBuffer> buffer;
uint8_t* memory = nullptr; uint8_t* memory = nullptr;
uint64_t deviceAddress = 0;
};
struct UploadAllocation
{
RenderBufferReference bufferReference;
uint8_t* memory = nullptr;
uint64_t deviceAddress = 0;
}; };
struct UploadAllocator struct UploadAllocator
@ -186,7 +194,7 @@ struct UploadAllocator
uint32_t index = 0; uint32_t index = 0;
uint32_t offset = 0; uint32_t offset = 0;
std::pair<RenderBufferReference, uint8_t*> allocate(uint32_t size, uint32_t alignment) UploadAllocation allocate(uint32_t size, uint32_t alignment)
{ {
assert(size <= UploadBuffer::SIZE); assert(size <= UploadBuffer::SIZE);
@ -206,22 +214,23 @@ struct UploadAllocator
{ {
buffer.buffer = g_device->createBuffer(RenderBufferDesc::UploadBuffer(UploadBuffer::SIZE, RenderBufferFlag::CONSTANT | RenderBufferFlag::VERTEX | RenderBufferFlag::INDEX)); buffer.buffer = g_device->createBuffer(RenderBufferDesc::UploadBuffer(UploadBuffer::SIZE, RenderBufferFlag::CONSTANT | RenderBufferFlag::VERTEX | RenderBufferFlag::INDEX));
buffer.memory = reinterpret_cast<uint8_t*>(buffer.buffer->map()); buffer.memory = reinterpret_cast<uint8_t*>(buffer.buffer->map());
buffer.deviceAddress = buffer.buffer->getDeviceAddress();
} }
auto ref = buffer.buffer->at(offset); auto ref = buffer.buffer->at(offset);
offset += size; offset += size;
return { ref, buffer.memory + ref.offset }; return { ref, buffer.memory + ref.offset, buffer.deviceAddress + ref.offset };
} }
template<bool TByteSwap, typename T> template<bool TByteSwap, typename T>
RenderBufferReference allocate(const T* memory, uint32_t size, uint32_t alignment) UploadAllocation allocate(const T* memory, uint32_t size, uint32_t alignment)
{ {
auto result = allocate(size, alignment); auto result = allocate(size, alignment);
if constexpr (TByteSwap) if constexpr (TByteSwap)
{ {
auto destination = reinterpret_cast<T*>(result.second); auto destination = reinterpret_cast<T*>(result.memory);
for (size_t i = 0; i < size; i += sizeof(T)) for (size_t i = 0; i < size; i += sizeof(T))
{ {
@ -232,10 +241,10 @@ struct UploadAllocator
} }
else else
{ {
memcpy(result.second, memory, size); memcpy(result.memory, memory, size);
} }
return result.first; return result;
} }
void reset() void reset()
@ -1288,17 +1297,12 @@ static void FlushRenderState(GuestDevice* device)
auto& uploadAllocator = g_uploadAllocators[g_frame]; auto& uploadAllocator = g_uploadAllocators[g_frame];
auto setRootDescriptor = [&](RenderBufferReference reference, size_t index) auto setRootDescriptor = [&](const UploadAllocation& allocation, size_t index)
{ {
if (g_vulkan) if (g_vulkan)
{ commandList->setGraphicsPushConstants(0, &allocation.deviceAddress, 8 * index, 8);
uint64_t address = reference.ref->getDeviceAddress() + reference.offset;
commandList->setGraphicsPushConstants(0, &address, 8 * index, 8);
}
else else
{ commandList->setGraphicsRootDescriptor(allocation.bufferReference, index);
commandList->setGraphicsRootDescriptor(reference, index);
}
}; };
if (g_dirtyStates.sharedConstants) if (g_dirtyStates.sharedConstants)
@ -1443,7 +1447,7 @@ static void DrawPrimitiveUP(GuestDevice* device, uint32_t primitiveType, uint32_
auto& vertexBufferView = g_vertexBufferViews[0]; auto& vertexBufferView = g_vertexBufferViews[0];
vertexBufferView.size = primitiveCount * vertexStreamZeroStride; vertexBufferView.size = primitiveCount * vertexStreamZeroStride;
vertexBufferView.buffer = g_uploadAllocators[g_frame].allocate<true>(reinterpret_cast<uint32_t*>(vertexStreamZeroData), vertexBufferView.size, 0x4); vertexBufferView.buffer = g_uploadAllocators[g_frame].allocate<true>(reinterpret_cast<uint32_t*>(vertexStreamZeroData), vertexBufferView.size, 0x4).bufferReference;
g_inputSlots[0].stride = vertexStreamZeroStride; g_inputSlots[0].stride = vertexStreamZeroStride;
g_dirtyStates.vertexStreamFirst = 0; g_dirtyStates.vertexStreamFirst = 0;
@ -1472,7 +1476,7 @@ static void DrawPrimitiveUP(GuestDevice* device, uint32_t primitiveType, uint32_
if (g_quadIndexBuffer == NULL || g_quadCount < quadCount) if (g_quadIndexBuffer == NULL || g_quadCount < quadCount)
{ {
g_quadIndexBuffer = g_uploadAllocators[g_frame].allocate<false>(quadIndexData.data(), triangleCount * 2, 2); g_quadIndexBuffer = g_uploadAllocators[g_frame].allocate<false>(quadIndexData.data(), triangleCount * 2, 2).bufferReference;
g_quadCount = quadCount; g_quadCount = quadCount;
} }