diff --git a/Common/Data/Collections/FastVec.h b/Common/Data/Collections/FastVec.h index 626090395cd3..41e18e3eac8d 100644 --- a/Common/Data/Collections/FastVec.h +++ b/Common/Data/Collections/FastVec.h @@ -101,6 +101,14 @@ class FastVec { size_ += newItems; } + void resize(size_t size) { + if (size < size_) { + size_ = size; + } else { + // TODO + } + } + private: void IncreaseCapacityTo(size_t newCapacity) { if (newCapacity <= capacity_) @@ -123,7 +131,7 @@ class FastVec { capacity_ = newCapacity; } - T *data_ = nullptr; size_t size_ = 0; size_t capacity_ = 0; + T *data_ = nullptr; }; diff --git a/Common/GPU/Vulkan/VulkanQueueRunner.cpp b/Common/GPU/Vulkan/VulkanQueueRunner.cpp index 2dde7b0527cd..e7670e99445f 100644 --- a/Common/GPU/Vulkan/VulkanQueueRunner.cpp +++ b/Common/GPU/Vulkan/VulkanQueueRunner.cpp @@ -1241,7 +1241,7 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c VKRGraphicsPipeline *lastGraphicsPipeline = nullptr; VKRComputePipeline *lastComputePipeline = nullptr; - auto &commands = step.commands; + const auto &commands = step.commands; // We can do a little bit of state tracking here to eliminate some calls into the driver. // The stencil ones are very commonly mostly redundant so let's eliminate them where possible. diff --git a/Common/GPU/Vulkan/VulkanQueueRunner.h b/Common/GPU/Vulkan/VulkanQueueRunner.h index b92198053a5a..45af407cf538 100644 --- a/Common/GPU/Vulkan/VulkanQueueRunner.h +++ b/Common/GPU/Vulkan/VulkanQueueRunner.h @@ -6,6 +6,7 @@ #include "Common/Thread/Promise.h" #include "Common/Data/Collections/Hashmaps.h" +#include "Common/Data/Collections/FastVec.h" #include "Common/GPU/Vulkan/VulkanContext.h" #include "Common/GPU/Vulkan/VulkanBarrier.h" #include "Common/GPU/Vulkan/VulkanFrameData.h" @@ -153,7 +154,7 @@ struct VKRStep { ~VKRStep() {} VKRStepType stepType; - std::vector commands; + FastVec commands; TinySet preTransitions; TinySet dependencies; const char *tag; diff --git a/Common/GPU/Vulkan/VulkanRenderManager.cpp b/Common/GPU/Vulkan/VulkanRenderManager.cpp index 193bb8af51c8..287eaf236575 100644 --- a/Common/GPU/Vulkan/VulkanRenderManager.cpp +++ b/Common/GPU/Vulkan/VulkanRenderManager.cpp @@ -999,7 +999,7 @@ void VulkanRenderManager::CopyImageToMemorySync(VkImage image, int mipLevel, int queueRunner_.CopyReadbackBuffer(frameData_[vulkan_->GetCurFrame()], nullptr, w, h, destFormat, destFormat, pixelStride, pixels); } -static void RemoveDrawCommands(std::vector *cmds) { +static void RemoveDrawCommands(FastVec *cmds) { // Here we remove any DRAW type commands when we hit a CLEAR. for (auto &c : *cmds) { if (c.cmd == VKRRenderCommand::DRAW || c.cmd == VKRRenderCommand::DRAW_INDEXED) { @@ -1008,7 +1008,7 @@ static void RemoveDrawCommands(std::vector *cmds) { } } -static void CleanupRenderCommands(std::vector *cmds) { +static void CleanupRenderCommands(FastVec *cmds) { size_t lastCommand[(int)VKRRenderCommand::NUM_RENDER_COMMANDS]; memset(lastCommand, -1, sizeof(lastCommand)); diff --git a/Common/GPU/Vulkan/VulkanRenderManager.h b/Common/GPU/Vulkan/VulkanRenderManager.h index a48e82a6696c..c1bb34234aca 100644 --- a/Common/GPU/Vulkan/VulkanRenderManager.h +++ b/Common/GPU/Vulkan/VulkanRenderManager.h @@ -240,7 +240,8 @@ class VulkanRenderManager { void BindPipeline(VKRGraphicsPipeline *pipeline, PipelineFlags flags, VkPipelineLayout pipelineLayout) { _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); _dbg_assert_(pipeline != nullptr); - VkRenderData data{ VKRRenderCommand::BIND_GRAPHICS_PIPELINE }; + VkRenderData &data = curRenderStep_->commands.push_uninitialized(); + data.cmd = VKRRenderCommand::BIND_GRAPHICS_PIPELINE; pipelinesToCheck_.push_back(pipeline); data.graphics_pipeline.pipeline = pipeline; data.graphics_pipeline.pipelineLayout = pipelineLayout; @@ -249,24 +250,24 @@ class VulkanRenderManager { // DebugBreak(); // } curPipelineFlags_ |= flags; - curRenderStep_->commands.push_back(data); } void BindPipeline(VKRComputePipeline *pipeline, PipelineFlags flags, VkPipelineLayout pipelineLayout) { _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); _dbg_assert_(pipeline != nullptr); - VkRenderData data{ VKRRenderCommand::BIND_COMPUTE_PIPELINE }; + VkRenderData &data = curRenderStep_->commands.push_uninitialized(); + data.cmd = VKRRenderCommand::BIND_COMPUTE_PIPELINE; data.compute_pipeline.pipeline = pipeline; data.compute_pipeline.pipelineLayout = pipelineLayout; curPipelineFlags_ |= flags; - curRenderStep_->commands.push_back(data); } void SetViewport(const VkViewport &vp) { _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); _dbg_assert_((int)vp.width >= 0); _dbg_assert_((int)vp.height >= 0); - VkRenderData data{ VKRRenderCommand::VIEWPORT }; + VkRenderData &data = curRenderStep_->commands.push_uninitialized(); + data.cmd = VKRRenderCommand::VIEWPORT; data.viewport.vp.x = vp.x; data.viewport.vp.y = vp.y; data.viewport.vp.width = vp.width; @@ -276,7 +277,6 @@ class VulkanRenderManager { // TODO: This should be fixed at the source. data.viewport.vp.minDepth = clamp_value(vp.minDepth, 0.0f, 1.0f); data.viewport.vp.maxDepth = clamp_value(vp.maxDepth, 0.0f, 1.0f); - curRenderStep_->commands.push_back(data); curStepHasViewport_ = true; } @@ -318,37 +318,37 @@ class VulkanRenderManager { curRenderArea_.Apply(rc); - VkRenderData data{ VKRRenderCommand::SCISSOR }; + VkRenderData &data = curRenderStep_->commands.push_uninitialized(); + data.cmd = VKRRenderCommand::SCISSOR; data.scissor.scissor = rc; - curRenderStep_->commands.push_back(data); curStepHasScissor_ = true; } void SetStencilParams(uint8_t writeMask, uint8_t compareMask, uint8_t refValue) { _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); - VkRenderData data{ VKRRenderCommand::STENCIL }; + VkRenderData &data = curRenderStep_->commands.push_uninitialized(); + data.cmd = VKRRenderCommand::STENCIL; data.stencil.stencilWriteMask = writeMask; data.stencil.stencilCompareMask = compareMask; data.stencil.stencilRef = refValue; - curRenderStep_->commands.push_back(data); } void SetBlendFactor(uint32_t color) { _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); - VkRenderData data{ VKRRenderCommand::BLEND }; + VkRenderData &data = curRenderStep_->commands.push_uninitialized(); + data.cmd = VKRRenderCommand::BLEND; data.blendColor.color = color; - curRenderStep_->commands.push_back(data); } void PushConstants(VkPipelineLayout pipelineLayout, VkShaderStageFlags stages, int offset, int size, void *constants) { _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); _dbg_assert_(size + offset < 40); - VkRenderData data{ VKRRenderCommand::PUSH_CONSTANTS }; + VkRenderData &data = curRenderStep_->commands.push_uninitialized(); + data.cmd = VKRRenderCommand::PUSH_CONSTANTS; data.push.stages = stages; data.push.offset = offset; data.push.size = size; memcpy(data.push.data, constants, size); - curRenderStep_->commands.push_back(data); } void Clear(uint32_t clearColor, float clearZ, int clearStencil, int clearMask); @@ -380,7 +380,8 @@ class VulkanRenderManager { void Draw(VkDescriptorSet descSet, int numUboOffsets, const uint32_t *uboOffsets, VkBuffer vbuffer, int voffset, int count, int offset = 0) { _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER && curStepHasViewport_ && curStepHasScissor_); - VkRenderData data{ VKRRenderCommand::DRAW }; + VkRenderData &data = curRenderStep_->commands.push_uninitialized(); + data.cmd = VKRRenderCommand::DRAW; data.draw.count = count; data.draw.offset = offset; data.draw.ds = descSet; @@ -390,13 +391,13 @@ class VulkanRenderManager { _dbg_assert_(numUboOffsets <= ARRAY_SIZE(data.draw.uboOffsets)); for (int i = 0; i < numUboOffsets; i++) data.draw.uboOffsets[i] = uboOffsets[i]; - curRenderStep_->commands.push_back(data); curRenderStep_->render.numDraws++; } void DrawIndexed(VkDescriptorSet descSet, int numUboOffsets, const uint32_t *uboOffsets, VkBuffer vbuffer, int voffset, VkBuffer ibuffer, int ioffset, int count, int numInstances, VkIndexType indexType) { _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER && curStepHasViewport_ && curStepHasScissor_); - VkRenderData data{ VKRRenderCommand::DRAW_INDEXED }; + VkRenderData &data = curRenderStep_->commands.push_uninitialized(); + data.cmd = VKRRenderCommand::DRAW_INDEXED; data.drawIndexed.count = count; data.drawIndexed.instances = numInstances; data.drawIndexed.ds = descSet; @@ -409,7 +410,6 @@ class VulkanRenderManager { for (int i = 0; i < numUboOffsets; i++) data.drawIndexed.uboOffsets[i] = uboOffsets[i]; data.drawIndexed.indexType = indexType; - curRenderStep_->commands.push_back(data); curRenderStep_->render.numDraws++; } @@ -417,9 +417,9 @@ class VulkanRenderManager { // in the debugger. void DebugAnnotate(const char *annotation) { _dbg_assert_(curRenderStep_); - VkRenderData data{ VKRRenderCommand::DEBUG_ANNOTATION }; + VkRenderData &data = curRenderStep_->commands.push_uninitialized(); + data.cmd = VKRRenderCommand::DEBUG_ANNOTATION; data.debugAnnotation.annotation = annotation; - curRenderStep_->commands.push_back(data); } VkCommandBuffer GetInitCmd(); diff --git a/unittest/UnitTest.cpp b/unittest/UnitTest.cpp index fccc21983430..4b4b1b6e5052 100644 --- a/unittest/UnitTest.cpp +++ b/unittest/UnitTest.cpp @@ -392,6 +392,16 @@ bool TestFastVec() { EXPECT_EQ_INT(b[4], 80); EXPECT_EQ_INT(b[5], 9); + b.resize(2); + b.insert(b.end(), items, items + 4); + EXPECT_EQ_INT(b[0], 8); + EXPECT_EQ_INT(b[1], 50); + EXPECT_EQ_INT(b[2], 50); + EXPECT_EQ_INT(b[3], 60); + EXPECT_EQ_INT(b[4], 70); + EXPECT_EQ_INT(b[5], 80); + + return true; }