feat(renderer): storage & staging buffer types
Some checks reported errors
continuous-integration/drone/push Build was killed
Some checks reported errors
continuous-integration/drone/push Build was killed
This commit is contained in:
parent
2ddb90faff
commit
5422792705
5 changed files with 101 additions and 34 deletions
|
|
@ -16,7 +16,7 @@ Buffer::Buffer(IDevice *device, IGpu *gpu, const CreateInfo &info)
|
|||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
}
|
||||
)
|
||||
, m_memory(m_device, m_buffer, allocation_info_from_memory_requirements())
|
||||
, m_memory(m_device, m_buffer, determine_allocation_info(info.usage))
|
||||
, m_size(info.size)
|
||||
{
|
||||
}
|
||||
|
|
@ -31,30 +31,18 @@ void Buffer::unmap() /* override */
|
|||
m_device->unmap_memory(m_memory);
|
||||
}
|
||||
|
||||
[[nodiscard]] auto Buffer::to_native_usage_flags(Usage usage) const -> VkBufferUsageFlags
|
||||
{
|
||||
switch (usage)
|
||||
{
|
||||
case Usage::vertex: return VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
|
||||
case Usage::index: return VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
|
||||
}
|
||||
|
||||
std::unreachable();
|
||||
}
|
||||
|
||||
[[nodiscard]] auto Buffer::allocation_info_from_memory_requirements() const -> VkMemoryAllocateInfo
|
||||
[[nodiscard]] auto Buffer::determine_allocation_info(Usage usage) const -> VkMemoryAllocateInfo
|
||||
{
|
||||
const auto requirements = m_device->get_memory_requirements(m_buffer);
|
||||
auto memory_properties = m_gpu->get_memory_properties();
|
||||
|
||||
const auto required_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
||||
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
|
||||
const auto required_properties = to_native_memory_properties(usage);
|
||||
auto type = 0u;
|
||||
for (auto idx = 0; idx < memory_properties.memoryTypeCount; ++idx)
|
||||
{
|
||||
if ((requirements.memoryTypeBits & (1 << idx))
|
||||
&& ((memory_properties.memoryTypes[idx].propertyFlags & required_properties)
|
||||
== required_properties))
|
||||
const auto property_flags = memory_properties.memoryTypes[idx].propertyFlags;
|
||||
if (has_correct_memory_type_bit(requirements.memoryTypeBits, idx)
|
||||
&& has_required_memory_properties(required_properties, property_flags))
|
||||
|
||||
{
|
||||
type = idx;
|
||||
|
|
@ -69,4 +57,50 @@ void Buffer::unmap() /* override */
|
|||
};
|
||||
}
|
||||
|
||||
[[nodiscard]] auto Buffer::to_native_usage_flags(Usage usage) const -> VkBufferUsageFlags
|
||||
{
|
||||
switch (usage)
|
||||
{
|
||||
case Usage::vertex: return VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||
|
||||
case Usage::index: return VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||
|
||||
case Usage::storage:
|
||||
return VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
|
||||
|
||||
case Usage::staging: return VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
||||
}
|
||||
|
||||
std::unreachable();
|
||||
}
|
||||
|
||||
[[nodiscard]] auto Buffer::to_native_memory_properties(Usage usage) const -> VkMemoryPropertyFlags
|
||||
{
|
||||
switch (usage)
|
||||
{
|
||||
case Usage::vertex:
|
||||
case Usage::index:
|
||||
case Usage::storage: return VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||
|
||||
case Usage::staging:
|
||||
return VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
|
||||
}
|
||||
|
||||
std::unreachable();
|
||||
}
|
||||
|
||||
[[nodiscard]] auto Buffer::has_correct_memory_type_bit(uint32_t type_bits, uint32_t type_idx) const
|
||||
-> bool
|
||||
{
|
||||
return type_bits & (1 << type_idx);
|
||||
}
|
||||
|
||||
[[nodiscard]] auto Buffer::has_required_memory_properties(
|
||||
uint32_t required_properties,
|
||||
uint32_t property_flags
|
||||
) const -> bool
|
||||
{
|
||||
return (property_flags & required_properties) == required_properties;
|
||||
}
|
||||
|
||||
} // namespace lt::renderer::vk
|
||||
|
|
|
|||
|
|
@ -14,15 +14,36 @@ public:
|
|||
|
||||
void unmap() override;
|
||||
|
||||
// TODO(Light): this is to make copying possible.
|
||||
// But it should be removed in the future,
|
||||
// Right now it's not possible because: buffers can't understand CommandBuffers.
|
||||
// And I'm not sure how to properly abstract over command buffers,
|
||||
// before using other APIs...
|
||||
[[nodiscard]] auto vk()
|
||||
{
|
||||
return *m_buffer;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_size() const -> size_t override
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
private:
|
||||
[[nodiscard]] auto determine_allocation_info(Usage usage) const -> VkMemoryAllocateInfo;
|
||||
|
||||
[[nodiscard]] auto to_native_usage_flags(Usage usage) const -> VkBufferUsageFlags;
|
||||
|
||||
[[nodiscard]] auto allocation_info_from_memory_requirements() const -> VkMemoryAllocateInfo;
|
||||
[[nodiscard]] auto to_native_memory_properties(Usage usage) const -> VkMemoryPropertyFlags;
|
||||
|
||||
|
||||
[[nodiscard]] auto has_correct_memory_type_bit(uint32_t type_bits, uint32_t type_idx) const
|
||||
-> bool;
|
||||
|
||||
[[nodiscard]] auto has_required_memory_properties(
|
||||
uint32_t required_properties,
|
||||
uint32_t property_flags
|
||||
) const -> bool;
|
||||
|
||||
Device *m_device {};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
#include <renderer/backend/vk/data/buffer.hpp>
|
||||
#include <renderer/frontend/data/buffer.hpp>
|
||||
|
||||
|
|
|
|||
|
|
@ -8,11 +8,15 @@ namespace lt::renderer {
|
|||
class IBuffer
|
||||
{
|
||||
public:
|
||||
enum Usage : uint8_t
|
||||
enum class Usage : uint8_t
|
||||
{
|
||||
vertex,
|
||||
|
||||
index,
|
||||
|
||||
storage,
|
||||
|
||||
staging,
|
||||
};
|
||||
|
||||
struct CreateInfo
|
||||
|
|
@ -24,6 +28,13 @@ public:
|
|||
std::string debug_name;
|
||||
};
|
||||
|
||||
struct CopyInfo
|
||||
{
|
||||
size_t offset;
|
||||
|
||||
size_t size;
|
||||
};
|
||||
|
||||
[[nodiscard]] static auto create(
|
||||
Api target_api,
|
||||
class IDevice *device,
|
||||
|
|
|
|||
|
|
@ -8,16 +8,19 @@ Suite raii = "buffer_raii"_suite = [] {
|
|||
Case { "happy path won't throw" } = [] {
|
||||
auto fixture = FixtureDeviceSwapchain {};
|
||||
|
||||
ignore = IBuffer::create(
|
||||
lt::renderer::Api::vulkan,
|
||||
fixture.device(),
|
||||
fixture.gpu(),
|
||||
IBuffer::CreateInfo {
|
||||
.usage = IBuffer::Usage::vertex,
|
||||
.size = 1000u,
|
||||
.debug_name = "",
|
||||
}
|
||||
);
|
||||
for (auto idx = 0; idx <= std::to_underlying(IBuffer::Usage::staging); ++idx)
|
||||
{
|
||||
ignore = IBuffer::create(
|
||||
lt::renderer::Api::vulkan,
|
||||
fixture.device(),
|
||||
fixture.gpu(),
|
||||
IBuffer::CreateInfo {
|
||||
.usage = static_cast<IBuffer::Usage>(idx),
|
||||
.size = 1000u,
|
||||
.debug_name = "",
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
expect_false(fixture.has_any_messages_of(error));
|
||||
expect_false(fixture.has_any_messages_of(warning));
|
||||
|
|
@ -77,7 +80,7 @@ Suite raii = "buffer_raii"_suite = [] {
|
|||
);
|
||||
});
|
||||
|
||||
/** Make sure the default-case was good */
|
||||
/** Make sure the default-case was OK */
|
||||
ignore = IBuffer::create(lt::renderer::Api::vulkan, fixture.device(), fixture.gpu(), info);
|
||||
|
||||
expect_false(fixture.has_any_messages_of(error));
|
||||
|
|
@ -96,7 +99,7 @@ Suite mapping = "buffer_mapping"_suite = [] {
|
|||
fixture.device(),
|
||||
fixture.gpu(),
|
||||
IBuffer::CreateInfo {
|
||||
.usage = IBuffer::Usage::vertex,
|
||||
.usage = IBuffer::Usage::staging,
|
||||
.size = size,
|
||||
.debug_name = "",
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue