vkCmdUpdateBuffer: Make a copy of the data.
"Buffer updates performed with vkCmdUpdateBuffer first copy the data into command buffer memory when the command is recorded (which requires additional storage and may incur an additional allocation), and then copy the data from the command buffer into dstBuffer when the command is executed on a device."
Bug: b/133127573
Bug: b/118619338
Bug: b/118383648
Change-Id: I8ba9bcdd6bf9e5b4f7e181c6fc379595a1d32e2a
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/31839
Presubmit-Ready: Ben Clayton <bclayton@google.com>
Tested-by: Ben Clayton <bclayton@google.com>
Reviewed-by: Chris Forbes <chrisforbes@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/src/Vulkan/VkCommandBuffer.cpp b/src/Vulkan/VkCommandBuffer.cpp
index 92f5a6a..90d1afa 100644
--- a/src/Vulkan/VkCommandBuffer.cpp
+++ b/src/Vulkan/VkCommandBuffer.cpp
@@ -783,21 +783,20 @@
struct UpdateBuffer : public CommandBuffer::Command
{
- UpdateBuffer(VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void* pData) :
- dstBuffer(dstBuffer), dstOffset(dstOffset), dataSize(dataSize), pData(pData)
+ UpdateBuffer(VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const uint8_t* pData) :
+ dstBuffer(dstBuffer), dstOffset(dstOffset), data(pData, &pData[dataSize])
{
}
void play(CommandBuffer::ExecutionState& executionState) override
{
- Cast(dstBuffer)->update(dstOffset, dataSize, pData);
+ Cast(dstBuffer)->update(dstOffset, data.size(), data.data());
}
private:
VkBuffer dstBuffer;
VkDeviceSize dstOffset;
- VkDeviceSize dataSize;
- const void* pData;
+ std::vector<uint8_t> data; // FIXME (b/119409619): replace this vector by an allocator so we can control all memory allocations
};
struct ClearColorImage : public CommandBuffer::Command
@@ -1468,7 +1467,7 @@
{
ASSERT(state == RECORDING);
- addCommand<UpdateBuffer>(dstBuffer, dstOffset, dataSize, pData);
+ addCommand<UpdateBuffer>(dstBuffer, dstOffset, dataSize, reinterpret_cast<const uint8_t*>(pData));
}
void CommandBuffer::fillBuffer(VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data)