mirror of
https://github.com/love2d/love.git
synced 2026-08-14 01:20:56 +02:00
first draft of vulkan buffer implementation
This commit is contained in:
@@ -578,6 +578,8 @@ set(LOVE_SRC_MODULE_GRAPHICS_VULKAN
|
||||
src/modules/graphics/vulkan/Shader.cpp
|
||||
src/modules/graphics/vulkan/ShaderStage.h
|
||||
src/modules/graphics/vulkan/ShaderStage.cpp
|
||||
src/modules/graphics/vulkan/Buffer.h
|
||||
src/modules/graphics/vulkan/Buffer.cpp
|
||||
)
|
||||
|
||||
set(LOVE_SRC_MODULE_GRAPHICS
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
#include "Buffer.h"
|
||||
#include "Graphics.h"
|
||||
|
||||
namespace love {
|
||||
namespace graphics {
|
||||
namespace vulkan {
|
||||
static uint32_t findMemoryType(VkPhysicalDevice physicalDevice, uint32_t typeFtiler, VkMemoryPropertyFlags properties) {
|
||||
VkPhysicalDeviceMemoryProperties memProperties;
|
||||
vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memProperties);
|
||||
|
||||
for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) {
|
||||
if ((typeFtiler & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
throw love::Exception("failed to find suitable memory type");
|
||||
}
|
||||
|
||||
Buffer::Buffer(love::graphics::Graphics* gfx, const Settings& settings, const std::vector<DataDeclaration>& format, const void* data, size_t size, size_t arraylength)
|
||||
: love::graphics::Buffer(gfx, settings, format, size, arrayLength) {
|
||||
auto vgfx = (Graphics*)gfx;
|
||||
device = vgfx->getDevice();
|
||||
auto physicalDevice = vgfx->getPhysicalDevice();
|
||||
|
||||
VkBufferCreateInfo bufferInfo{};
|
||||
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||
bufferInfo.size = getSize();
|
||||
bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; // todo: only vertex buffers are allowed for now
|
||||
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
|
||||
if (vkCreateBuffer(device, &bufferInfo, nullptr, &buffer) != VK_SUCCESS) {
|
||||
throw love::Exception("failed to create buffer");
|
||||
}
|
||||
|
||||
VkMemoryRequirements memRequirements;
|
||||
vkGetBufferMemoryRequirements(device, buffer, &memRequirements);
|
||||
|
||||
VkMemoryAllocateInfo allocInfo{};
|
||||
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||
allocInfo.allocationSize = memRequirements.size;
|
||||
allocInfo.memoryTypeIndex = findMemoryType(physicalDevice, memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||
|
||||
if (vkAllocateMemory(device, &allocInfo, nullptr, &bufferMemory) != VK_SUCCESS) {
|
||||
throw love::Exception("failed to allocate vertex buffer memory");
|
||||
}
|
||||
|
||||
vkBindBufferMemory(device, buffer, bufferMemory, 0);
|
||||
|
||||
vkMapMemory(device, bufferMemory, 0, getSize(), 0, &mappedMemory);
|
||||
memcpy(mappedMemory, data, size);
|
||||
vkUnmapMemory(device, bufferMemory);
|
||||
}
|
||||
|
||||
Buffer::~Buffer() {
|
||||
vkDestroyBuffer(device, buffer, nullptr);
|
||||
vkFreeMemory(device, bufferMemory, nullptr);
|
||||
}
|
||||
|
||||
void* Buffer::map(MapType map, size_t offset, size_t size) {
|
||||
vkMapMemory(device, bufferMemory, offset, size, 0, &mappedMemory);
|
||||
return mappedMemory;
|
||||
}
|
||||
|
||||
void Buffer::fill(size_t offset, size_t size, const void *data) {
|
||||
memcpy(mappedMemory, data, size);
|
||||
}
|
||||
|
||||
void Buffer::unmap(size_t usedoffset, size_t usedsize) {
|
||||
vkUnmapMemory(device, bufferMemory);
|
||||
}
|
||||
|
||||
void Buffer::copyTo(love::graphics::Buffer* dest, size_t sourceoffset, size_t destoffset, size_t size) {
|
||||
throw love::Exception("not implemented yet");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#include "graphics/Buffer.h"
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
|
||||
namespace love {
|
||||
namespace graphics {
|
||||
namespace vulkan {
|
||||
class Buffer : public love::graphics::Buffer {
|
||||
public:
|
||||
Buffer(love::graphics::Graphics* gfx, const Settings& settings, const std::vector<DataDeclaration>& format, const void* data, size_t size, size_t arraylength);
|
||||
virtual ~Buffer();
|
||||
|
||||
void* map(MapType map, size_t offset, size_t size) override;
|
||||
void unmap(size_t usedoffset, size_t usedsize) override;
|
||||
void fill(size_t offset, size_t size, const void* data) override;
|
||||
void copyTo(love::graphics::Buffer* dest, size_t sourceoffset, size_t destoffset, size_t size) override;
|
||||
ptrdiff_t getHandle() const override {
|
||||
return (ptrdiff_t) buffer; // todo ?
|
||||
}
|
||||
ptrdiff_t getTexelBufferHandle() const override {
|
||||
return (ptrdiff_t) nullptr; // todo ?
|
||||
}
|
||||
|
||||
private:
|
||||
VkDevice device;
|
||||
VkPhysicalDevice physicalDevice;
|
||||
|
||||
// todo use a staging buffer for improved performance
|
||||
VkBuffer buffer;
|
||||
VkDeviceMemory bufferMemory;
|
||||
|
||||
void* mappedMemory;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "Graphics.h"
|
||||
#include "Buffer.h"
|
||||
#include "SDL_vulkan.h"
|
||||
#include "window/Window.h"
|
||||
#include "common/Exception.h"
|
||||
@@ -77,6 +78,10 @@ namespace love {
|
||||
cleanup();
|
||||
}
|
||||
|
||||
love::graphics::Buffer* Graphics::newBuffer(const love::graphics::Buffer::Settings& settings, const std::vector<love::graphics::Buffer::DataDeclaration>& format, const void* data, size_t size, size_t arraylength) {
|
||||
return new Buffer(this, settings, format, data, size, arraylength);
|
||||
}
|
||||
|
||||
void Graphics::present(void* screenshotCallbackdata) {
|
||||
vkWaitForFences(device, 1, &inFlightFences[currentFrame], VK_TRUE, UINT64_MAX);
|
||||
|
||||
|
||||
@@ -27,9 +27,13 @@ namespace love {
|
||||
return device;
|
||||
}
|
||||
|
||||
const VkPhysicalDevice getPhysicalDevice() const {
|
||||
return physicalDevice;
|
||||
}
|
||||
|
||||
// implementation for virtual functions
|
||||
Texture* newTexture(const Texture::Settings& settings, const Texture::Slices* data = nullptr) override { return nullptr; }
|
||||
Buffer* newBuffer(const Buffer::Settings& settings, const std::vector<Buffer::DataDeclaration>& format, const void* data, size_t size, size_t arraylength) override { return nullptr; }
|
||||
love::graphics::Buffer* newBuffer(const love::graphics::Buffer::Settings& settings, const std::vector<love::graphics::Buffer::DataDeclaration>& format, const void* data, size_t size, size_t arraylength) override;
|
||||
void clear(OptionalColorD color, OptionalInt stencil, OptionalDouble depth) override {}
|
||||
void clear(const std::vector<OptionalColorD>& colors, OptionalInt stencil, OptionalDouble depth) override {}
|
||||
void discard(const std::vector<bool>& colorbuffers, bool depthstencil) override {}
|
||||
|
||||
Reference in New Issue
Block a user