diff --git a/rendering/vulkan14/vulkan14indirect.cpp b/rendering/vulkan14/vulkan14indirect.cpp index e6c38c2b..38028907 100644 --- a/rendering/vulkan14/vulkan14indirect.cpp +++ b/rendering/vulkan14/vulkan14indirect.cpp @@ -353,7 +353,7 @@ bool vulkan14_renderer::draw_indirect(vk14::instance_cull &Cull, command_set con auto &draws{scene.draws}; auto &window{draw.draws_window}; auto const size{static_cast(Count) * draws.stride}; - auto slice{(window.open && (size <= draws.window)) ? draw.draws_cache.allocate_before(size, draws.stride, window.base + draws.window) : vk14::ring_slice{}}; + auto slice{(window.open && (size <= draws.window)) ? draw.draws_cache.allocate_before(size, draws.stride, window.base, window.base + draws.window) : vk14::ring_slice{}}; if ((false == bool(slice)) && (size <= draws.window)) { slice = draw.draws_cache.allocate(size, draws.stride); diff --git a/rendering/vulkan14/vulkan14memory.cpp b/rendering/vulkan14/vulkan14memory.cpp index ccd0b1a7..39f5e69a 100644 --- a/rendering/vulkan14/vulkan14memory.cpp +++ b/rendering/vulkan14/vulkan14memory.cpp @@ -764,14 +764,14 @@ VkDeviceSize ring_cache::next(VkDeviceSize const Alignment) const return (m_part.offset + m_used + alignment - 1) / alignment * alignment; } -ring_slice ring_cache::allocate_before(VkDeviceSize const Size, VkDeviceSize const Alignment, VkDeviceSize const Limit) +ring_slice ring_cache::allocate_before(VkDeviceSize const Size, VkDeviceSize const Alignment, VkDeviceSize const Base, VkDeviceSize const Limit) { if (false == bool(m_part)) { return {}; } auto const offset{next(Alignment)}; - if ((offset + Size > m_part.offset + m_part.size) || (offset + Size > Limit)) + if ((offset < Base) || (offset + Size > m_part.offset + m_part.size) || (offset + Size > Limit)) { return {}; } @@ -786,7 +786,7 @@ ring_slice ring_cache::allocate_before(VkDeviceSize const Size, VkDeviceSize con ring_slice ring_cache::allocate(VkDeviceSize const Size, VkDeviceSize const Alignment) { - if (auto const slice{allocate_before(Size, Alignment, std::numeric_limits::max())}) + if (auto const slice{allocate_before(Size, Alignment, 0, std::numeric_limits::max())}) { return slice; } @@ -812,7 +812,7 @@ ring_slice ring_cache::allocate(VkDeviceSize const Size, VkDeviceSize const Alig return {}; } } - return allocate_before(Size, Alignment, std::numeric_limits::max()); + return allocate_before(Size, Alignment, 0, std::numeric_limits::max()); } } // namespace vk14 diff --git a/rendering/vulkan14/vulkan14memory.h b/rendering/vulkan14/vulkan14memory.h index 2f0172e9..9563aaaa 100644 --- a/rendering/vulkan14/vulkan14memory.h +++ b/rendering/vulkan14/vulkan14memory.h @@ -293,9 +293,10 @@ class ring_cache void reset(frame_ring *Ring, VkDeviceSize Part); // Size bytes aligned to Alignment (at most 256); empty when the ring is full ring_slice allocate(VkDeviceSize Size, VkDeviceSize Alignment); - // the same, only when the slice fits in the part held and ends before Limit (an offset in the buffer); empty, with nothing taken, - // otherwise - ring_slice allocate_before(VkDeviceSize Size, VkDeviceSize Alignment, VkDeviceSize Limit); + // the same, only when the slice fits in the part held and lies within Base to Limit (offsets in the buffer: a window the shaders + // index from Base); empty, with nothing taken, otherwise. the part held may lie below Base: a large slice which got a part of its + // own opened the window above it + ring_slice allocate_before(VkDeviceSize Size, VkDeviceSize Alignment, VkDeviceSize Base, VkDeviceSize Limit); private: // where the next slice aligned to Alignment would begin in the part held, as an offset in the buffer diff --git a/rendering/vulkan14/vulkan14scene.cpp b/rendering/vulkan14/vulkan14scene.cpp index 65b9135a..86a2116a 100644 --- a/rendering/vulkan14/vulkan14scene.cpp +++ b/rendering/vulkan14/vulkan14scene.cpp @@ -1852,7 +1852,7 @@ std::uint32_t vulkan14_renderer::push_draw_block() auto &draws{m_context->scene.draws}; auto &draw{*m_draw}; auto &window{draw.draws_window}; - auto slice{window.open ? draw.draws_cache.allocate_before(draws.stride, draws.stride, window.base + draws.window) : vk14::ring_slice{}}; + auto slice{window.open ? draw.draws_cache.allocate_before(draws.stride, draws.stride, window.base, window.base + draws.window) : vk14::ring_slice{}}; if (false == bool(slice)) { slice = draw.draws_cache.allocate(draws.stride, draws.stride); @@ -1884,7 +1884,7 @@ std::uint32_t vulkan14_renderer::walk_instances(glm::mat4 const *Modelviews, std auto const capacity{static_cast(instances.window / instances.stride) - 1}; auto const count{std::min(Count, capacity)}; auto const size{static_cast(count) * instances.stride}; - auto slice{window.open ? draw.instances_cache.allocate_before(size, instances.stride, window.base + instances.window) : vk14::ring_slice{}}; + auto slice{window.open ? draw.instances_cache.allocate_before(size, instances.stride, window.base, window.base + instances.window) : vk14::ring_slice{}}; if (false == bool(slice)) { // a new window, which begins with the identity of the draws which aren't instanced, followed by the instances