RenderTextures and Rml Geometry
This commit is contained in:
parent
eb79ff9879
commit
68ec759c36
@ -6,6 +6,7 @@ set(LIB vulkan-renderer)
|
||||
|
||||
find_package(Vulkan REQUIRED)
|
||||
find_package(glm CONFIG REQUIRED)
|
||||
find_package(RmlUi CONFIG REQUIRED)
|
||||
|
||||
# Link library
|
||||
|
||||
@ -27,3 +28,4 @@ target_link_libraries(${LIB} PUBLIC utils)
|
||||
target_link_libraries(${LIB} PUBLIC p7)
|
||||
target_link_libraries(${LIB} PRIVATE glm::glm)
|
||||
target_link_libraries(${LIB} PRIVATE Vulkan::Vulkan)
|
||||
target_link_libraries(${LIB} PRIVATE RmlUi::RmlUi)
|
||||
@ -18,7 +18,7 @@ namespace ee_vulkan {
|
||||
static constexpr vk::ClearValue CLEAR_DEPTH = {.depthStencil = {1.0f, 0}};
|
||||
};
|
||||
|
||||
struct Mesh {
|
||||
struct ProvinceMesh {
|
||||
lazy<vulkan_render::Buffer<
|
||||
glm::vec2,
|
||||
vk::BufferUsageFlagBits::eVertexBuffer,
|
||||
@ -76,7 +76,7 @@ export namespace ee_vulkan {
|
||||
|
||||
lazy<vulkan_render::Texture<vulkan_render::TextureMode::DEPTH>> depth;
|
||||
lazy<vulkan_render::Uniform<glm::mat4>> viewProjectionUniform;
|
||||
Mesh provinces;
|
||||
ProvinceMesh provinces;
|
||||
|
||||
std::size_t currentFrame = 0;
|
||||
|
||||
|
||||
@ -47,6 +47,15 @@ export namespace vulkan_render {
|
||||
RenderCommands(const Context &context, std::uint32_t maxFramesInFlight);
|
||||
|
||||
void SubmitStagingBuffer(const BaseBuffer<BufferMode::STAGING_ACCESS> &buffer) const;
|
||||
void SubmitTexture(
|
||||
const BaseBuffer<BufferMode::STATIC> &buffer,
|
||||
const Texture<TextureMode::PARTIAL> &texture
|
||||
) const;
|
||||
void TranslateTextureLayout(
|
||||
const Texture<TextureMode::PARTIAL> &texture,
|
||||
const vk::ImageLayout &from,
|
||||
const vk::ImageLayout &to
|
||||
) const;
|
||||
|
||||
private:
|
||||
static vk::raii::CommandPool MakePool(const Context &context, std::uint32_t queueFamily);
|
||||
|
||||
@ -149,6 +149,7 @@ export namespace vulkan_render {
|
||||
};
|
||||
|
||||
enum class TextureMode {
|
||||
PARTIAL,
|
||||
RENDER,
|
||||
DEPTH
|
||||
};
|
||||
@ -171,35 +172,25 @@ export namespace vulkan_render {
|
||||
Texture(
|
||||
const Context &context,
|
||||
const std::uint32_t width, const std::uint32_t height,
|
||||
const vk::Format &format,
|
||||
const std::span<std::byte> textureData
|
||||
) requires (mode == TextureMode::RENDER)
|
||||
: context(context), width(width), height(height), data(textureData), format(format) {
|
||||
Buffer<
|
||||
std::byte,
|
||||
vk::BufferUsageFlagBits::eTransferSrc,
|
||||
BufferMode::STATIC
|
||||
> stagingBuffer(context, data);
|
||||
|
||||
const vk::Format &format
|
||||
) requires (mode == TextureMode::PARTIAL)
|
||||
: context(context), width(width), height(height), format(format) {
|
||||
MakeInstance(
|
||||
vk::Flags(vk::ImageUsageFlagBits::eTransferDst) | vk::ImageUsageFlagBits::eSampled,
|
||||
vk::MemoryPropertyFlagBits::eDeviceLocal,
|
||||
handle,
|
||||
memory
|
||||
);
|
||||
|
||||
/* TODO: Transition image layout
|
||||
* Copy buffer to image
|
||||
* Transition image layout
|
||||
* Create view
|
||||
*/
|
||||
}
|
||||
|
||||
Texture(
|
||||
const Context &context,
|
||||
const Surface &surface
|
||||
) requires (mode == TextureMode::DEPTH)
|
||||
: context(context), width(surface.extent.width), height(surface.extent.height), format(vk::Format::eD32SfloatS8Uint) {
|
||||
) requires (mode == TextureMode::DEPTH) :
|
||||
context(context),
|
||||
width(surface.extent.width),
|
||||
height(surface.extent.height),
|
||||
format(vk::Format::eD32SfloatS8Uint) {
|
||||
MakeInstance(
|
||||
vk::ImageUsageFlagBits::eDepthStencilAttachment,
|
||||
vk::MemoryPropertyFlagBits::eDeviceLocal,
|
||||
@ -209,6 +200,21 @@ export namespace vulkan_render {
|
||||
MakeView(vk::ImageAspectFlagBits::eDepth);
|
||||
}
|
||||
|
||||
// ReSharper disable once CppNonExplicitConvertingConstructor
|
||||
Texture(Texture<TextureMode::PARTIAL> &&from) requires (mode == TextureMode::RENDER) :
|
||||
context(from.context),
|
||||
width(from.width),
|
||||
height(from.height),
|
||||
format(from.format) {
|
||||
if (*from.view == nullptr) {
|
||||
LOG(ERROR, "Corrupted render texture created, source data is not complete.");
|
||||
}
|
||||
}
|
||||
|
||||
void Init(const vk::ImageAspectFlags &flags) requires (mode == TextureMode::PARTIAL) {
|
||||
MakeView(flags);
|
||||
}
|
||||
|
||||
Texture(Texture&&) noexcept = default;
|
||||
Texture(const Texture&) = delete;
|
||||
Texture& operator=(const Texture&) = delete;
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
export module vulkan_render:factory;
|
||||
import :hardware;
|
||||
import :resources;
|
||||
import :control;
|
||||
import :data;
|
||||
|
||||
export namespace vulkan_render {
|
||||
|
||||
@ -27,4 +29,14 @@ export namespace vulkan_render {
|
||||
static void SetupFrames(const Context &context, Swapchain &swapchain, const Surface &surface);
|
||||
};
|
||||
|
||||
class DataFactory {
|
||||
public:
|
||||
static Texture<TextureMode::RENDER> CreateRenderTexture(
|
||||
const Context &context,
|
||||
const RenderCommands &commands,
|
||||
std::uint32_t width, std::uint32_t height,
|
||||
std::span<std::byte> textureData
|
||||
);
|
||||
};
|
||||
|
||||
}
|
||||
89
renderers/vulkan/modules/rml/rmlui_vulkan.cppm
Normal file
89
renderers/vulkan/modules/rml/rmlui_vulkan.cppm
Normal file
@ -0,0 +1,89 @@
|
||||
/**
|
||||
* Do not include <RmlUi/Core.h> in module .cpp implementation
|
||||
* to prevent MSVC internal compiler error
|
||||
*/
|
||||
|
||||
module;
|
||||
|
||||
#include <RmlUi/Core.h>
|
||||
|
||||
export module rmlui_vulkan;
|
||||
import vulkan_render;
|
||||
import utils;
|
||||
import std;
|
||||
|
||||
namespace ee_rml {
|
||||
template <typename T> using lazy = std::optional<T>;
|
||||
|
||||
struct GeometryMesh {
|
||||
lazy<vulkan_render::Buffer<
|
||||
Rml::Vertex,
|
||||
vk::BufferUsageFlagBits::eVertexBuffer,
|
||||
vulkan_render::BufferMode::STAGING_ACCESS
|
||||
>> vertices;
|
||||
lazy<vulkan_render::Buffer<
|
||||
std::uint32_t,
|
||||
vk::BufferUsageFlagBits::eIndexBuffer,
|
||||
vulkan_render::BufferMode::STAGING_ACCESS
|
||||
>> indices;
|
||||
};
|
||||
}
|
||||
|
||||
export namespace ee_rml {
|
||||
|
||||
struct RenderContext {
|
||||
vulkan_render::Context &context;
|
||||
vulkan_render::RenderCommands &commands;
|
||||
};
|
||||
|
||||
class RmlVulkan final : public Rml::RenderInterface {
|
||||
public:
|
||||
explicit RmlVulkan(RenderContext &renderContext) : renderer(renderContext) {}
|
||||
|
||||
Rml::CompiledGeometryHandle CompileGeometry(
|
||||
const Rml::Span<const Rml::Vertex> vertices,
|
||||
const Rml::Span<const std::int32_t> indices
|
||||
) override {
|
||||
GeometryMesh *mesh = Allocate<GeometryMesh>();
|
||||
mesh->vertices.emplace(renderer.context, vertices.size());
|
||||
mesh->indices.emplace(renderer.context, indices.size());
|
||||
|
||||
std::ranges::copy(vertices, mesh->vertices->content.data());
|
||||
std::ranges::copy(indices, mesh->indices->content.data());
|
||||
|
||||
renderer.commands.SubmitStagingBuffer(*mesh->vertices);
|
||||
renderer.commands.SubmitStagingBuffer(*mesh->indices);
|
||||
|
||||
return reinterpret_cast<Rml::CompiledGeometryHandle>(mesh);
|
||||
}
|
||||
|
||||
void RenderGeometry(
|
||||
Rml::CompiledGeometryHandle geometry,
|
||||
Rml::Vector2f translation,
|
||||
Rml::TextureHandle texture
|
||||
) override {
|
||||
|
||||
}
|
||||
|
||||
void ReleaseGeometry(const Rml::CompiledGeometryHandle geometry) override {
|
||||
Deallocate(reinterpret_cast<GeometryMesh*>(geometry));
|
||||
};
|
||||
|
||||
Rml::TextureHandle LoadTexture(Rml::Vector2i &texture_dimensions, const Rml::String &source) override {return 0;}
|
||||
|
||||
Rml::TextureHandle GenerateTexture(
|
||||
Rml::Span<const std::uint8_t> source,
|
||||
Rml::Vector2i source_dimensions
|
||||
) override {return 0;}
|
||||
|
||||
void ReleaseTexture(Rml::TextureHandle texture) override {}
|
||||
|
||||
void EnableScissorRegion(bool enable) override {}
|
||||
|
||||
void SetScissorRegion(Rml::Rectanglei region) override {}
|
||||
|
||||
private:
|
||||
RenderContext &renderer;
|
||||
};
|
||||
|
||||
}
|
||||
@ -74,6 +74,83 @@ void vulkan_render::RenderCommands::SubmitStagingBuffer(const BaseBuffer<BufferM
|
||||
cmd.Submit(buffer.context.device.transfer);
|
||||
}
|
||||
|
||||
void vulkan_render::RenderCommands::SubmitTexture(
|
||||
const BaseBuffer<BufferMode::STATIC> &buffer,
|
||||
const Texture<TextureMode::PARTIAL> &texture
|
||||
) const {
|
||||
const Command cmd(buffer.context, graphicsPool);
|
||||
|
||||
const vk::BufferImageCopy copyRegion {
|
||||
.bufferOffset = 0,
|
||||
.bufferRowLength = 0,
|
||||
.bufferImageHeight = 0,
|
||||
.imageSubresource = {
|
||||
.aspectMask = vk::ImageAspectFlagBits::eColor,
|
||||
.mipLevel = 0,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1
|
||||
},
|
||||
.imageOffset = {0, 0, 0},
|
||||
.imageExtent = {texture.width, texture.height, 1}
|
||||
};
|
||||
|
||||
cmd.handle.copyBufferToImage(buffer.handle, texture.handle, vk::ImageLayout::eTransferDstOptimal, {copyRegion});
|
||||
|
||||
cmd.Submit(buffer.context.device.graphics);
|
||||
}
|
||||
|
||||
void vulkan_render::RenderCommands::TranslateTextureLayout(
|
||||
const Texture<TextureMode::PARTIAL> &texture,
|
||||
const vk::ImageLayout &from,
|
||||
const vk::ImageLayout &to
|
||||
) const {
|
||||
const Command cmd(texture.context, graphicsPool);
|
||||
|
||||
vk::ImageMemoryBarrier barrier {
|
||||
.oldLayout = from,
|
||||
.newLayout = to,
|
||||
.srcQueueFamilyIndex = vk::QueueFamilyIgnored,
|
||||
.dstQueueFamilyIndex = vk::QueueFamilyIgnored,
|
||||
.image = texture.handle,
|
||||
.subresourceRange = {
|
||||
.aspectMask = vk::ImageAspectFlagBits::eColor,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1
|
||||
},
|
||||
};
|
||||
|
||||
vk::PipelineStageFlags sourceStage;
|
||||
vk::PipelineStageFlags destinationStage;
|
||||
|
||||
if (from == vk::ImageLayout::eUndefined && to == vk::ImageLayout::eTransferDstOptimal) {
|
||||
barrier.srcAccessMask = vk::AccessFlagBits::eNone;
|
||||
barrier.dstAccessMask = vk::AccessFlagBits::eTransferWrite;
|
||||
|
||||
sourceStage = vk::PipelineStageFlagBits::eTopOfPipe;
|
||||
destinationStage = vk::PipelineStageFlagBits::eTransfer;
|
||||
} else if (from == vk::ImageLayout::eTransferDstOptimal && to == vk::ImageLayout::eReadOnlyOptimal) {
|
||||
barrier.srcAccessMask = vk::AccessFlagBits::eTransferWrite;
|
||||
barrier.dstAccessMask = vk::AccessFlagBits::eShaderRead;
|
||||
|
||||
sourceStage = vk::PipelineStageFlagBits::eTransfer;
|
||||
destinationStage = vk::PipelineStageFlagBits::eFragmentShader;
|
||||
} else {
|
||||
LOG(ERROR, "Unsupported layout transition: %d -> %d.", from, to);
|
||||
}
|
||||
|
||||
cmd.handle.pipelineBarrier(
|
||||
sourceStage, destinationStage,
|
||||
vk::DependencyFlags(0),
|
||||
nullptr,
|
||||
nullptr,
|
||||
{barrier}
|
||||
);
|
||||
|
||||
cmd.Submit(texture.context.device.graphics);
|
||||
}
|
||||
|
||||
vk::raii::CommandPool vulkan_render::RenderCommands::MakePool(const Context &context, const std::uint32_t queueFamily) {
|
||||
return context.device.handle.createCommandPool({
|
||||
.flags = vk::CommandPoolCreateFlagBits::eResetCommandBuffer,
|
||||
|
||||
@ -85,3 +85,33 @@ void vulkan_render::ResourcesFactory::SetupFrames(const Context &context, Swapch
|
||||
}
|
||||
LOG(INFO, "Frame views are ready.");
|
||||
}
|
||||
|
||||
vulkan_render::Texture<vulkan_render::TextureMode::RENDER> vulkan_render::DataFactory::CreateRenderTexture(
|
||||
const Context &context,
|
||||
const RenderCommands &commands,
|
||||
const std::uint32_t width, const std::uint32_t height,
|
||||
const std::span<std::byte> textureData
|
||||
) {
|
||||
Texture<TextureMode::PARTIAL> texture(context, width, height, vk::Format::eR8G8B8A8Srgb);
|
||||
const Buffer<
|
||||
std::byte,
|
||||
vk::BufferUsageFlagBits::eTransferSrc,
|
||||
BufferMode::STATIC
|
||||
> stagingBuffer(context, textureData);
|
||||
|
||||
commands.TranslateTextureLayout(
|
||||
texture,
|
||||
vk::ImageLayout::eUndefined,
|
||||
vk::ImageLayout::eTransferDstOptimal
|
||||
);
|
||||
commands.SubmitTexture(stagingBuffer, texture);
|
||||
commands.TranslateTextureLayout(
|
||||
texture,
|
||||
vk::ImageLayout::eTransferDstOptimal,
|
||||
vk::ImageLayout::eShaderReadOnlyOptimal
|
||||
);
|
||||
|
||||
texture.Init(vk::ImageAspectFlagBits::eColor);
|
||||
|
||||
return std::move(texture);
|
||||
}
|
||||
|
||||
6
renderers/vulkan/src/rml/rmlui_vulkan.cpp
Normal file
6
renderers/vulkan/src/rml/rmlui_vulkan.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
// module;
|
||||
//
|
||||
// #include <RmlUi/Core.h>
|
||||
//
|
||||
// module rmlui_vulkan;
|
||||
//
|
||||
Loading…
x
Reference in New Issue
Block a user