Basic crashing text rendering

This commit is contained in:
Dynamitos
2022-04-15 11:19:30 +02:00
parent 3fec36295a
commit eb23264c40
41 changed files with 895 additions and 273 deletions
+3
View File
@@ -28,3 +28,6 @@
[submodule "external/ttf-parser"]
path = external/ttf-parser
url = git@github.com:kv01/ttf-parser.git
[submodule "external/freetype"]
path = external/freetype
url = https://gitlab.freedesktop.org/freetype/freetype.git
+1 -1
View File
@@ -4,7 +4,7 @@
"name": "Win32",
"includePath": [
"${workspaceFolder}/src/**",
"${workspaceFolder}/external/**"
"${workspaceFolder}/src/Engine"
],
"defines": [
"_DEBUG",
+3
View File
@@ -18,6 +18,7 @@ set(JSON_ROOT ${EXTERNAL_ROOT}/json)
set(KTX_ROOT ${EXTERNAL_ROOT}/ktx)
set(STB_ROOT ${EXTERNAL_ROOT}/stb)
set(TTFPARSER_ROOT ${EXTERNAL_ROOT}/ttf-parser)
set(FREETYPE_ROOT ${EXTERNAL_ROOT}/freetype)
set(SPIRV_ROOT ${EXTERNAL_ROOT}/SPIRV-Cross)
set(NSAM_ROOT ${EXTERNAL_ROOT}/aftermath)
@@ -50,6 +51,7 @@ find_package(Threads REQUIRED)
find_package(Assimp REQUIRED)
find_package(JSON REQUIRED)
find_package(GLFW REQUIRED)
find_package(FreeType REQUIRED)
find_package(TTFParser REQUIRED)
find_package(GLM REQUIRED)
find_package(KTX REQUIRED)
@@ -130,6 +132,7 @@ if(WIN32)
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SLANG_BINARIES} $<TARGET_FILE_DIR:Engine>
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SLANG_GLSLANG} $<TARGET_FILE_DIR:Engine>
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${GLFW_BINARY} $<TARGET_FILE_DIR:Engine>
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${FREETYPE_BINARY} $<TARGET_FILE_DIR:Engine>
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${ASSIMP_BINARY} $<TARGET_FILE_DIR:Engine>
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${NSAM_BINARIES} $<TARGET_FILE_DIR:Engine>
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${NSAM_LLVM} $<TARGET_FILE_DIR:Engine>
+3 -3
View File
@@ -62,9 +62,9 @@ set(GLFW_VULKAN_STATIC OFF CACHE BOOL "GLFW vulkan static")
add_subdirectory(${GLFW_ROOT} ${GLFW_ROOT})
#--------------FreeType------------------------------
#list(APPEND DEPENDENCIES freetype)
list(APPEND DEPENDENCIES freetype)
#add_subdirectory(${FREETYPE_ROOT} ${FREETYPE_ROOT})
add_subdirectory(${FREETYPE_ROOT} ${FREETYPE_ROOT})
#--------------SLang------------------------------
list(APPEND DEPENDENCIES slang)
@@ -73,7 +73,7 @@ if(WIN32)
ExternalProject_Add(slang
SOURCE_DIR ${SLANG_ROOT}
BINARY_DIR ${SLANG_ROOT}
CONFIGURE_COMMAND ""
CONFIGURE_COMMAND premake.bat vs2019 --file=${CMAKE_SOURCE_DIR}/external/slang/premake5.lua gmake --arch=${CMAKE_PLATFORM} --deps=true
BUILD_COMMAND msbuild slang.sln -p:Configuration=Release -p:Platform=${CMAKE_PLATFORM}
INSTALL_COMMAND "")
elseif(UNIX)
Vendored Submodule
+1
Submodule external/freetype added at e50798b720
+1 -1
Binary file not shown.
+69
View File
@@ -0,0 +1,69 @@
struct GlyphData
{
float2 bearing;
float2 size;
};
struct ViewData
{
float4x4 projectionMatrix;
}
layout(set = 0, binding = 0)
ConstantBuffer<ViewData> viewData;
layout(set = 0, binding = 1)
SamplerState glyphSampler;
layout(set = 0, binding = 2)
StructuredBuffer<GlyphData> glyphData;
layout(set = 1)
Texture2D glyphTextures[];
layout(push_constant)
float scale;
struct VertexStageInput
{
uint glyphIndex;
float2 position;
uint vertexId : SV_VertexID;
};
struct VertexStageOutput
{
float4 position : SV_Position;
float2 uvCoords : TEXCOORD;
uint glyphIndex : GLYPHINDEX;
};
[shader("vertex")]
VertexStageOutput vertexMain(VertexStageInput input)
{
GlyphData glyph = glyphData[input.glyphIndex];
float xpos = input.position.x + glyph.bearing.x * scale;
float ypos = input.position.y - (glyph.size.y - glyph.bearing.y) * scale;
float w = glyph.size.x * scale;
float h = glyph.size.y * scale;
float4 coordinates[4] = {
float4(xpos, ypos + h, 0, 0),
float4(xpos, ypos, 0, 1),
float4(xpos + w, ypos, 1, 0),
float4(xpos + w, ypos + h, 1, 1)
};
float4 vertex = coordinates[input.vertexId];
VertexStageOutput output;
output.uvCoords = vertex.zw;
output.position = mul(viewData.projectionMatrix, float4(vertex.xy, 0, 1));
output.glyphIndex = input.glyphIndex;
return output;
}
[shader("fragment")]
float4 fragmentMain(
float4 position : SV_Position,
float2 uvCoords : TEXCOORD,
uint glyphIndex : GLYPHINDEX
) : SV_Target
{
return glyphTextures[glyphIndex].Sample(glyphSampler, uvCoords);
}
-1
View File
@@ -17,7 +17,6 @@ VertexStageOutput vertexMain(uint vertexId : SV_VertexID)
VertexStageOutput output;
output.uvCoords = coordinates[vertexId];
output.position = float4(output.uvCoords * 2 - 1, 1, 1);
output.position.y = -output.position.y;
return output;
}
+2 -2
View File
@@ -1,2 +1,2 @@
slangc ForwardPlus.slang -target spirv -entry vertexMain -profile vs_6_0 -o vertex.spv -I lib/ -D USE_INSTANCING=0 -D NUM_MATERIAL_TEXCOORDS=1
slangc ForwardPlus.slang -target spirv -entry fragmentMain -profile ps_6_0 -o fragment.spv -I lib/ -D USE_INSTANCING=0 -D NUM_MATERIAL_TEXCOORDS=1
slangc TextPass.slang -target glsl -entry vertexMain -profile vs_6_0 -o vertex.glsl -I lib/ -D INDEX_VIEW_PARAMS=0
slangc TextPass.slang -target glsl -entry fragmentMain -profile ps_6_0 -o fragment.glsl -I lib/ -D INDEX_VIEW_PARAMS=0
+20
View File
@@ -0,0 +1,20 @@
#version 450
layout(row_major) uniform;
layout(row_major) buffer;
#line 61 0
layout(location = 0)
out vec4 _S1;
#line 61
void main()
{
#line 61
_S1 = vec4(float(0), float(1), float(0), float(1));
#line 61
return;
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+114
View File
@@ -0,0 +1,114 @@
#version 450
layout(row_major) uniform;
layout(row_major) buffer;
#line 7 0
struct GlyphData_0
{
vec2 bearing_0;
vec2 size_0;
};
layout(std430, binding = 1) readonly buffer _S1 {
GlyphData_0 _data[];
} glyphData_0;
#line 1
struct ViewParameter_0
{
mat4x4 projectionMatrix_0;
};
#line 5
layout(binding = 0)
layout(std140) uniform _S2
{
ViewParameter_0 _data;
} gViewParams_0;
#line 5
layout(location = 0)
out vec2 _S3;
#line 5
layout(location = 1)
out uint _S4;
#line 5
layout(location = 0)
in uint _S5;
#line 5
layout(location = 1)
in vec2 _S6;
#line 5
layout(location = 2)
in float _S7;
#line 20
struct VertexStageInput_0
{
uint glyphIndex_0;
vec2 position_0;
float scale_0;
uint vertexId_0;
};
struct VertexStageOutput_0
{
vec4 position_1;
vec2 uvCoords_0;
uint glyphIndex_1;
};
void main()
{
#line 36
VertexStageInput_0 _S8 = VertexStageInput_0(_S5, _S6, _S7, uint(gl_VertexIndex));
GlyphData_0 glyph_0 = ((glyphData_0)._data[(_S8.glyphIndex_0)]);
float xpos_0 = _S8.position_0.x + glyph_0.bearing_0.x * _S8.scale_0;
float ypos_0 = _S8.position_0.y - (glyph_0.size_0.y - glyph_0.bearing_0.y) * _S8.scale_0;
float w_0 = glyph_0.size_0.x * _S8.scale_0;
vec4 coordinates_0[4] = { vec4(xpos_0, ypos_0 + glyph_0.size_0.y * _S8.scale_0, float(0), float(0)), vec4(xpos_0, ypos_0, float(0), float(1)), vec4(xpos_0 + w_0, ypos_0, float(1), float(0)), vec4(xpos_0 + w_0, ypos_0 + w_0, float(1), float(1)) };
#line 46
vec4 vertex_0 = coordinates_0[_S8.vertexId_0];
#line 53
VertexStageOutput_0 output_0;
output_0.uvCoords_0 = vertex_0.zw;
vec4 _S9 = (((vec4(vertex_0.xy, float(0), float(1))) * (gViewParams_0._data.projectionMatrix_0)));
#line 55
output_0.position_1 = _S9;
output_0.glyphIndex_1 = _S8.glyphIndex_0;
VertexStageOutput_0 _S10 = output_0;
#line 57
gl_Position = _S10.position_1;
#line 57
_S3 = _S10.uvCoords_0;
#line 57
_S4 = _S10.glyphIndex_1;
#line 57
return;
}
+27 -16
View File
@@ -1,7 +1,8 @@
#include "FontAsset.h"
#include "Graphics/GraphicsResources.h"
#define TTF_FONT_PARSER_IMPLEMENTATION
#include "ttfParser.h"
#include <ft2build.h>
#include FT_FREETYPE_H
#include "Window/WindowManager.h"
using namespace Seele;
@@ -31,20 +32,30 @@ void FontAsset::save()
void FontAsset::load()
{
TTFFontParser::FontData font_data;
int8_t error = TTFFontParser::parse_file(getFullPath().c_str(), &font_data, [](void*, void*, int){}, nullptr);
assert(!error);
for(auto pair : font_data.glyphs)
FT_Library ft;
assert(!FT_Init_FreeType(&ft));
FT_Face face;
assert(!FT_New_Face(ft, getFullPath().c_str(), 0, &face));
FT_Set_Pixel_Sizes(face, 0, 48);
for(uint8 c = 0; c < 128; ++c)
{
const TTFFontParser::Glyph& glyphData = pair.second;
Glyph& glyph = glyphs[pair.first];
glyph.advance = glyphData.advance_width;
std::memcpy(glyph.boundingBox, glyphData.bounding_box, sizeof(glyphData.bounding_box));
glyph.center = Vector2(glyphData.glyph_center.x, glyphData.glyph_center.y);
glyph.index = glyphData.glyph_index;
glyph.leftSideBearing = glyphData.left_side_bearing;
glyph.numContours = glyphData.num_contours;
Array<float> curveTextureData;
Gfx::PGraphics graphics = WindowManager::getGraphics();
if(FT_Load_Char(face, c, FT_LOAD_RENDER))
{
std::cout << "error loading " << (char)c << std::endl;
}
TextureCreateInfo imageData;
imageData.format = Gfx::SE_FORMAT_R8_UINT;
imageData.width = face->glyph->bitmap.width;
imageData.height = face->glyph->bitmap.rows;
imageData.resourceData.data = face->glyph->bitmap.buffer;
imageData.resourceData.size = imageData.width * imageData.height;
Glyph& glyph = glyphs[c];
glyph.texture = graphics->createTexture2D(imageData);
glyph.size = IVector2(face->glyph->bitmap.width, face->glyph->bitmap.rows);
glyph.bearing = IVector2(face->glyph->bitmap_left, face->glyph->bitmap_top);
glyph.advance = face->glyph->advance.x;
}
FT_Done_Face(face);
FT_Done_FreeType(ft);
}
+7 -9
View File
@@ -13,18 +13,16 @@ public:
virtual ~FontAsset();
virtual void save() override;
virtual void load() override;
private:
struct Glyph
{
int16 index;
int16 numContours;
uint16 advance;
int16 leftSideBearing;
int16 boundingBox[4];
Vector2 center;
Gfx::PTexture2D curveTexture;
Gfx::PTexture2D bandTexture;
Gfx::PTexture2D texture;
IVector2 size;
IVector2 bearing;
uint32 advance;
};
const Map<uint32, Glyph> getGlyphData() const { return glyphs; }
private:
Map<uint32, Glyph> glyphs;
};
DECLARE_REF(FontAsset)
+2
View File
@@ -3,6 +3,8 @@
#include "Graphics/Graphics.h"
#include "Window/WindowManager.h"
#include "Graphics/Vulkan/VulkanGraphicsEnums.h"
#include "ktx.h"
using namespace Seele;
+1
View File
@@ -7,6 +7,7 @@
#include <stb_image.h>
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include <stb_image_write.h>
#include "ktx.h"
using namespace Seele;
+28 -25
View File
@@ -198,7 +198,7 @@ public:
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
Map()
constexpr Map() noexcept
: root(-1)
, beginIt(-1)
, endIt(-1)
@@ -207,8 +207,7 @@ public:
, comp(Compare())
{
}
explicit Map(const Compare& comp,
const Allocator& alloc = Allocator())
constexpr explicit Map(const Compare& comp, const Allocator& alloc = Allocator()) noexcept(noexcept(Allocator()))
: nodeContainer(alloc)
, root(-1)
, beginIt(-1)
@@ -218,7 +217,7 @@ public:
, comp(comp)
{
}
explicit Map(const Allocator& alloc)
constexpr explicit Map(const Allocator& alloc) noexcept(noexcept(Compare))
: nodeContainer(alloc)
, root(-1)
, beginIt(-1)
@@ -228,7 +227,7 @@ public:
, comp(Compare())
{
}
Map(const Map& other)
constexpr Map(const Map& other)
: nodeContainer(other.nodeContainer)
, root(other.root)
, _size(other._size)
@@ -236,18 +235,18 @@ public:
{
markIteratorsDirty();
}
Map(Map&& other)
: nodeContainer(other.nodeContainer)
constexpr Map(Map&& other) noexcept
: nodeContainer(std::move(other.nodeContainer))
, root(std::move(other.root))
, _size(std::move(other._size))
, comp(std::move(other.comp))
{
markIteratorsDirty();
}
~Map()
constexpr ~Map() noexcept
{
}
Map& operator=(const Map& other)
constexpr Map& operator=(const Map& other)
{
if(this != &other)
{
@@ -259,7 +258,7 @@ public:
}
return *this;
}
Map& operator=(Map&& other)
constexpr Map& operator=(Map&& other)
{
if(this != &other)
{
@@ -271,7 +270,7 @@ public:
}
return *this;
}
inline mapped_type& operator[](const key_type& key)
constexpr mapped_type& operator[](const key_type& key)
{
root = splay(root, key);
if (!isValid(root)
@@ -284,7 +283,7 @@ public:
markIteratorsDirty();
return getNode(root)->pair.value;
}
inline mapped_type& operator[](key_type&& key)
constexpr mapped_type& operator[](key_type&& key)
{
root = splay(root, std::move(key));
if (!isValid(root)
@@ -297,7 +296,7 @@ public:
markIteratorsDirty();
return getNode(root)->pair.value;
}
iterator find(const key_type& key)
constexpr iterator find(const key_type& key)
{
root = splay(root, key);
refreshIterators();
@@ -309,7 +308,7 @@ public:
}
return iterator(root, &nodeContainer);
}
iterator find(key_type&& key)
constexpr iterator find(key_type&& key)
{
root = splay(root, std::move(key));
refreshIterators();
@@ -321,30 +320,34 @@ public:
}
return iterator(root, &nodeContainer);
}
iterator erase(const key_type& key)
constexpr iterator erase(const key_type& key)
{
root = remove(root, key);
refreshIterators();
return iterator(root, &nodeContainer);
}
iterator erase(K&& key)
constexpr iterator erase(key_type&& key)
{
root = remove(root, std::move(key));
refreshIterators();
return iterator(root, &nodeContainer);
}
void clear()
constexpr void clear()
{
nodeContainer.clear();
root = -1;
_size = 0;
markIteratorsDirty();
}
bool exists(key_type&& key)
constexpr bool exists(const key_type& key)
{
return find(std::forward<K>(key)) != endIt;
return find(key) != endIt;
}
iterator begin()
constexpr bool exists(key_type&& key)
{
return find(std::move(key)) != endIt;
}
constexpr iterator begin()
{
if(iteratorsDirty)
{
@@ -352,7 +355,7 @@ public:
}
return beginIt;
}
iterator end()
constexpr iterator end()
{
if(iteratorsDirty)
{
@@ -360,7 +363,7 @@ public:
}
return endIt;
}
iterator begin() const
constexpr iterator begin() const
{
if(iteratorsDirty)
{
@@ -368,7 +371,7 @@ public:
}
return beginIt;
}
iterator end() const
constexpr iterator end() const
{
if(iteratorsDirty)
{
@@ -376,11 +379,11 @@ public:
}
return endIt;
}
bool empty() const
constexpr bool empty() const
{
return nodeContainer.empty();
}
size_type size() const
constexpr size_type size() const
{
return _size;
}
-1
View File
@@ -4,7 +4,6 @@
#include "Containers/Array.h"
#include "VertexShaderInput.h"
#include "ShaderCompiler.h"
#include "ktx.h"
namespace Seele
{
+13
View File
@@ -1404,6 +1404,19 @@ typedef enum SeDescriptorType
SE_DESCRIPTOR_TYPE_MAX_ENUM = 0x7FFFFFFF
} SeDescriptorType;
typedef enum SeDescriptorBindingFlagBits {
SE_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT = 0x00000001,
SE_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT = 0x00000002,
SE_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT = 0x00000004,
SE_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT = 0x00000008,
SE_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT = SE_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT,
SE_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT = SE_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT,
SE_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT = SE_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT,
SE_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT = SE_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT,
SE_DESCRIPTOR_BINDING_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} SeDescriptorBindingFlagBits;
typedef SeFlags SeDescriptorBindingFlags;
typedef enum SeAttachmentLoadOp
{
SE_ATTACHMENT_LOAD_OP_LOAD = 0,
+36 -52
View File
@@ -50,73 +50,63 @@ struct ViewportCreateInfo
// doesnt own the data, only proxy it
struct BulkResourceData
{
uint32 size;
uint8 *data;
uint32 size = 0;
uint8 *data = nullptr;
Gfx::QueueType owner = Gfx::QueueType::GRAPHICS;
BulkResourceData()
: size(0), data(nullptr), owner(Gfx::QueueType::GRAPHICS)
{
}
};
struct TextureCreateInfo
{
BulkResourceData resourceData;
uint32 width;
uint32 height;
uint32 depth;
bool bArray;
uint32 arrayLayers;
uint32 mipLevels;
uint32 samples;
Gfx::SeFormat format;
Gfx::SeImageUsageFlagBits usage;
TextureCreateInfo()
: resourceData(), width(1), height(1), depth(1), bArray(false), arrayLayers(1)
, mipLevels(1), samples(1), format(Gfx::SE_FORMAT_R32G32B32A32_SFLOAT)
, usage(Gfx::SE_IMAGE_USAGE_SAMPLED_BIT)
{
}
BulkResourceData resourceData = BulkResourceData();
uint32 width = 1;
uint32 height = 1;
uint32 depth = 1;
bool bArray = false;
uint32 arrayLayers = 1;
uint32 mipLevels = 1;
uint32 samples = 1;
Gfx::SeFormat format = Gfx::SE_FORMAT_R32G32B32A32_SFLOAT;
Gfx::SeImageUsageFlagBits usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT;
};
struct SamplerCreateInfo
{
Gfx::SeSamplerCreateFlags flags;
Gfx::SeFilter magFilter;
Gfx::SeFilter minFilter;
Gfx::SeSamplerMipmapMode mipmapMode;
Gfx::SeSamplerAddressMode addressModeU;
Gfx::SeSamplerAddressMode addressModeV;
Gfx::SeSamplerAddressMode addressModeW;
float mipLodBias;
uint32 anisotropyEnable;
float maxAnisotropy;
uint32 compareEnable;
Gfx::SeCompareOp compareOp;
float minLod;
float maxLod;
Gfx::SeBorderColor borderColor;
uint32 unnormalizedCoordinates;
};
struct VertexBufferCreateInfo
{
BulkResourceData resourceData;
BulkResourceData resourceData = BulkResourceData();
// bytes per vertex
uint32 vertexSize;
uint32 numVertices;
VertexBufferCreateInfo()
: resourceData(), vertexSize(0), numVertices(0)
{
}
uint32 vertexSize = 0;
uint32 numVertices = 0;
};
struct IndexBufferCreateInfo
{
BulkResourceData resourceData;
Gfx::SeIndexType indexType;
IndexBufferCreateInfo()
: resourceData(), indexType(Gfx::SeIndexType::SE_INDEX_TYPE_UINT16)
{
}
BulkResourceData resourceData = BulkResourceData();
Gfx::SeIndexType indexType = Gfx::SeIndexType::SE_INDEX_TYPE_UINT16;
};
struct UniformBufferCreateInfo
{
BulkResourceData resourceData;
uint8 bDynamic : 1;
UniformBufferCreateInfo()
: resourceData(), bDynamic(0)
{
}
BulkResourceData resourceData = BulkResourceData();
uint8 bDynamic : 1 = 0;
};
struct StructuredBufferCreateInfo
{
BulkResourceData resourceData;
uint8 bDynamic: 1;
StructuredBufferCreateInfo()
: resourceData(), bDynamic(0)
{
}
};
struct ShaderCreateInfo
{
@@ -138,13 +128,6 @@ struct SePushConstantRange
};
struct VertexElement
{
VertexElement(){}
//VertexElement(uint8 attributeIndex, SeFormat vertexFormat, uint8 offset)
// : attributeIndex(attributeIndex), vertexFormat(vertexFormat), offset(offset)
//{}
VertexElement(uint8 streamIndex, uint8 offset, SeFormat vertexFormat, uint8 attributeIndex, uint8 stride)
: streamIndex(streamIndex), offset(offset), vertexFormat(vertexFormat), attributeIndex(attributeIndex), stride(stride)
{}
uint8 streamIndex;
uint8 offset;
SeFormat vertexFormat;
@@ -152,6 +135,7 @@ struct VertexElement
uint8 stride;
uint8 bInstanced = 0;
};
static_assert(std::is_aggregate_v<VertexElement>);
struct RasterizationState
{
uint8 depthClampEnable : 1;
+3 -3
View File
@@ -93,17 +93,17 @@ ShaderCollection& ShaderMap::createShaders(
return collection;
}
void DescriptorLayout::addDescriptorBinding(uint32 bindingIndex, SeDescriptorType type, uint32 arrayCount)
void DescriptorLayout::addDescriptorBinding(uint32 bindingIndex, SeDescriptorType type, uint32 arrayCount, SeDescriptorBindingFlags bindingFlags)
{
if (descriptorBindings.size() <= bindingIndex)
{
descriptorBindings.resize(bindingIndex + 1);
}
DescriptorBinding binding;
DescriptorBinding& binding = descriptorBindings[bindingIndex];
binding.binding = bindingIndex;
binding.descriptorType = type;
binding.descriptorCount = arrayCount;
descriptorBindings[bindingIndex] = binding;
binding.bindingFlags = bindingFlags;
}
PDescriptorSet DescriptorLayout::allocateDescriptorSet()
+5 -8
View File
@@ -160,16 +160,10 @@ public:
: binding(other.binding), descriptorType(other.descriptorType), descriptorCount(other.descriptorCount), shaderStages(other.shaderStages)
{
}
void operator=(const DescriptorBinding &other)
{
binding = other.binding;
descriptorType = other.descriptorType;
descriptorCount = other.descriptorCount;
shaderStages = other.shaderStages;
}
uint32_t binding;
SeDescriptorType descriptorType;
uint32_t descriptorCount;
SeDescriptorBindingFlags bindingFlags = 0;
SeShaderStageFlags shaderStages;
};
DEFINE_REF(DescriptorBinding)
@@ -196,6 +190,7 @@ public:
virtual void updateBuffer(uint32 binding, PStructuredBuffer structuredBuffer) = 0;
virtual void updateSampler(uint32 binding, PSamplerState samplerState) = 0;
virtual void updateTexture(uint32 binding, PTexture texture, PSamplerState samplerState = nullptr) = 0;
virtual void updateTextureArray(uint32_t binding, Array<PTexture> texture) = 0;
virtual bool operator<(PDescriptorSet other) = 0;
virtual uint32 getSetIndex() const = 0;
@@ -224,7 +219,7 @@ public:
return *this;
}
virtual void create() = 0;
virtual void addDescriptorBinding(uint32 binding, SeDescriptorType type, uint32 arrayCount = 1);
virtual void addDescriptorBinding(uint32 binding, SeDescriptorType type, uint32 arrayCount = 1, SeDescriptorBindingFlags bindingFlags = 0);
virtual void reset();
virtual PDescriptorSet allocateDescriptorSet();
const Array<DescriptorBinding> &getBindings() const { return descriptorBindings; }
@@ -557,6 +552,7 @@ public:
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) = 0;
virtual void bindVertexBuffer(const Array<VertexInputStream>& streams) = 0;
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) = 0;
virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) = 0;
virtual void draw(const MeshBatchElement& data) = 0;
virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) = 0;
std::string name;
@@ -571,6 +567,7 @@ public:
virtual void bindPipeline(Gfx::PComputePipeline pipeline) = 0;
virtual void bindDescriptor(Gfx::PDescriptorSet set) = 0;
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) = 0;
virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) = 0;
virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) = 0;
std::string name;
};
@@ -11,5 +11,7 @@ target_sources(Engine
RenderGraph.h
RenderGraph.cpp
RenderPass.h
TextPass.h
TextPass.cpp
UIPass.h
UIPass.cpp)
+200
View File
@@ -0,0 +1,200 @@
#include "TextPass.h"
#include "RenderGraph.h"
#include "Graphics/Graphics.h"
#include "Graphics/VertexShaderInput.h"
using namespace Seele;
TextPass::TextPass(Gfx::PGraphics graphics, Gfx::PViewport viewport, Gfx::PRenderTargetAttachment attachment)
: RenderPass(graphics, viewport)
, renderTarget(attachment)
{
}
TextPass::~TextPass()
{
}
MainJob TextPass::beginFrame()
{
for(TextRender& render : passData.texts)
{
FontData& fontData = getFontData(render.font);
TextResources& resources = textResources.add();
Array<GlyphInstanceData> instanceData;
float x = render.position.x;
float y = render.position.y;
for(uint32 c : render.text)
{
instanceData.add(GlyphInstanceData{
.glyphIndex = fontData.characterToGlyphIndex[c],
.position = Vector2(x, y)
});
x += (fontData.characterAdvance[c] >> 6) * render.scale;
}
VertexBufferCreateInfo vbInfo;
vbInfo.numVertices = static_cast<uint32>(instanceData.size());
vbInfo.vertexSize = sizeof(GlyphInstanceData);
vbInfo.resourceData.data = reinterpret_cast<uint8*>(instanceData.data());
vbInfo.resourceData.size = static_cast<uint32>(instanceData.size());
resources.vertexBuffer = graphics->createVertexBuffer(vbInfo);
resources.descriptorSet = descriptorLayout->allocateDescriptorSet();
resources.descriptorSet->updateBuffer(0, projectionBuffer);
resources.descriptorSet->updateSampler(1, glyphSampler);
resources.descriptorSet->updateBuffer(2, fontData.structuredBuffer);
resources.descriptorSet->writeChanges();
resources.textureArraySet = descriptorLayout->allocateDescriptorSet();
resources.textureArraySet->updateTextureArray(0, fontData.textures);
resources.textureArraySet->writeChanges();
resources.scale = render.scale;
}
co_return;
}
MainJob TextPass::render()
{
graphics->beginRenderPass(renderPass);
Array<Gfx::PRenderCommand> commands;
for(TextResources& resources : textResources)
{
Gfx::PRenderCommand command = graphics->createRenderCommand("TextPassCommand");
command->setViewport(viewport);
command->bindPipeline(pipeline);
command->bindVertexBuffer({VertexInputStream(0, 0, resources.vertexBuffer)});
command->pushConstants(pipelineLayout, Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(float), &resources.scale);
command->draw(4, static_cast<uint32>(resources.vertexBuffer->getNumVertices()), 0, 0);
commands.add(command);
}
graphics->executeCommands(commands);
graphics->endRenderPass();
co_return;
}
MainJob TextPass::endFrame()
{
co_return;
}
void TextPass::publishOutputs()
{
}
void TextPass::createRenderPass()
{
depthAttachment = resources->requestRenderTarget("UIPASS_DEPTH");
std::ifstream codeStream("./shaders/TextPass.slang", std::ios::ate);
auto fileSize = codeStream.tellg();
codeStream.seekg(0);
Array<char> buffer(static_cast<uint32>(fileSize));
codeStream.read(buffer.data(), fileSize);
ShaderCreateInfo createInfo;
createInfo.shaderCode.add(std::string(buffer.data()));
createInfo.defines["INDEX_VIEW_PARAMS"] = "0";
createInfo.name = "TextVertex";
createInfo.entryPoint = "vertexMain";
vertexShader = graphics->createVertexShader(createInfo);
createInfo.name = "TextFragment";
createInfo.entryPoint = "fragmentMain";
fragmentShader = graphics->createFragmentShader(createInfo);
Array<Gfx::VertexElement> elements;
elements.add({
.streamIndex = 0,
.offset = offsetof(GlyphInstanceData, glyphIndex),
.vertexFormat = Gfx::SE_FORMAT_R32_UINT,
.attributeIndex = 0,
.stride = sizeof(GlyphInstanceData),
.bInstanced = 1
});
elements.add({
.streamIndex = 0,
.offset = offsetof(GlyphInstanceData, position),
.vertexFormat = Gfx::SE_FORMAT_R32G32_SFLOAT,
.attributeIndex = 1,
.stride = sizeof(GlyphInstanceData),
.bInstanced = 1
});
declaration = graphics->createVertexDeclaration(elements);
descriptorLayout = graphics->createDescriptorLayout("TextDescriptor");
descriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
descriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_SAMPLER);
descriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, 128, Gfx::SE_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT);
descriptorLayout->create();
textureArrayLayout = graphics->createDescriptorLayout("TextureArray");
textureArrayLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 128, Gfx::SE_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT);
textureArrayLayout->create();
Matrix4 projectionMatrix = glm::ortho(0.f, (float)viewport->getSizeX(), 0.f, (float)viewport->getSizeY());
projectionBuffer = graphics->createUniformBuffer({
.resourceData = {
.size = sizeof(Matrix4),
.data = (uint8*)&projectionMatrix,
},
.bDynamic = false,
});
glyphSampler = graphics->createSamplerState({
.magFilter = Gfx::SE_FILTER_LINEAR,
.minFilter = Gfx::SE_FILTER_LINEAR,
.addressModeU = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
.addressModeV = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE
});
pipelineLayout = graphics->createPipelineLayout();
pipelineLayout->addDescriptorLayout(0, descriptorLayout);
pipelineLayout->addDescriptorLayout(1, textureArrayLayout);
pipelineLayout->addPushConstants({
.stageFlags = Gfx::SE_SHADER_STAGE_VERTEX_BIT,
.offset = 0,
.size = sizeof(float)});
pipelineLayout->create();
Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(renderTarget, depthAttachment);
renderPass = graphics->createRenderPass(layout, viewport);
GraphicsPipelineCreateInfo pipelineInfo;
pipelineInfo.vertexDeclaration = declaration;
pipelineInfo.vertexShader = vertexShader;
pipelineInfo.fragmentShader = fragmentShader;
pipelineInfo.renderPass = renderPass;
pipelineInfo.pipelineLayout = pipelineLayout;
pipelineInfo.rasterizationState.cullMode = Gfx::SE_CULL_MODE_NONE;
pipelineInfo.topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
pipeline = graphics->createGraphicsPipeline(pipelineInfo);
}
TextPass::FontData& TextPass::getFontData(PFontAsset font)
{
if(fontData.exists(font))
{
return fontData[font];
}
const Map<uint32, FontAsset::Glyph>& fontGlyphs = font->getGlyphData();
FontData& fd = fontData[font];
Array<GlyphData> buffer;
buffer.reserve(fontGlyphs.size());
for(const auto& [key, value] : fontGlyphs)
{
fd.characterToGlyphIndex[key] = static_cast<uint32>(buffer.size());
fd.characterAdvance[key] = value.advance;
fd.textures.add(value.texture);
GlyphData& gd = buffer.add();
gd.bearing = value.bearing;
gd.size = value.size;
}
StructuredBufferCreateInfo bufferInfo;
bufferInfo.bDynamic = false;
bufferInfo.resourceData.data = reinterpret_cast<uint8*>(buffer.data());
bufferInfo.resourceData.size = static_cast<uint32>(buffer.size());
fd.structuredBuffer = graphics->createStructuredBuffer(bufferInfo);
return fontData[font];
}
+85
View File
@@ -0,0 +1,85 @@
#pragma once
#include "RenderPass.h"
#include "UI/RenderHierarchy.h"
#include "Graphics/GraphicsResources.h"
#include "Asset/FontAsset.h"
namespace Seele
{
DECLARE_NAME_REF(Gfx, Texture2D)
DECLARE_NAME_REF(Gfx, RenderTargetAttachment)
DECLARE_NAME_REF(Gfx, StructuredBuffer)
struct TextRender
{
std::string text;
PFontAsset font;
Vector4 textColor;
Vector2 position;
float scale;
};
struct TextPassData
{
Array<TextRender> texts;
};
class TextPass : public RenderPass<TextPassData>
{
public:
TextPass(Gfx::PGraphics graphics, Gfx::PViewport viewport, Gfx::PRenderTargetAttachment renderTarget);
virtual ~TextPass();
virtual MainJob beginFrame() override;
virtual MainJob render() override;
virtual MainJob endFrame() override;
virtual void publishOutputs() override;
virtual void createRenderPass() override;
private:
struct GlyphData
{
Vector2 bearing;
Vector2 size;
};
struct GlyphInstanceData
{
uint32 glyphIndex;
Vector2 position;
};
struct FontData
{
Gfx::PStructuredBuffer structuredBuffer;
Array<Gfx::PTexture> textures;
Map<uint32, uint32> characterToGlyphIndex;
// Logically this should be part of GlyphData,
// but because GlyphData mirrors shader data and we need
// the advance on the CPU, we need this in a separate structure
Map<uint32, uint32> characterAdvance;
};
FontData& getFontData(PFontAsset font);
Map<PFontAsset, FontData> fontData;
struct TextResources
{
Gfx::PDescriptorSet descriptorSet;
Gfx::PDescriptorSet textureArraySet;
Gfx::PVertexBuffer vertexBuffer;
float scale;
};
Array<TextResources> textResources;
Gfx::PRenderTargetAttachment renderTarget;
Gfx::PRenderTargetAttachment depthAttachment;
Gfx::PTexture2D depthBuffer;
Gfx::PDescriptorLayout descriptorLayout;
Gfx::PDescriptorLayout textureArrayLayout;
Gfx::PUniformBuffer projectionBuffer;
Gfx::PSamplerState glyphSampler;
Gfx::PVertexDeclaration declaration;
Gfx::PVertexShader vertexShader;
Gfx::PFragmentShader fragmentShader;
Gfx::PPipelineLayout pipelineLayout;
Gfx::PGraphicsPipeline pipeline;
};
DEFINE_REF(TextPass);
} // namespace Seele
@@ -290,6 +290,13 @@ void RenderCommand::bindIndexBuffer(Gfx::PIndexBuffer indexBuffer)
PIndexBuffer buf = indexBuffer.cast<IndexBuffer>();
vkCmdBindIndexBuffer(handle, buf->getHandle(), 0, cast(buf->getIndexType()));
}
void RenderCommand::pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data)
{
assert(threadId == std::this_thread::get_id());
vkCmdPushConstants(handle, layout.cast<PipelineLayout>()->getHandle(), stage, offset, size, data);
}
void RenderCommand::draw(const MeshBatchElement& data)
{
assert(threadId == std::this_thread::get_id());
@@ -386,6 +393,12 @@ void ComputeCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptor
delete[] sets;
}
void ComputeCommand::pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data)
{
assert(threadId == std::this_thread::get_id());
vkCmdPushConstants(handle, layout.cast<PipelineLayout>()->getHandle(), stage, offset, size, data);
}
void ComputeCommand::dispatch(uint32 threadX, uint32 threadY, uint32 threadZ)
{
assert(threadId == std::this_thread::get_id());
@@ -89,6 +89,7 @@ public:
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets) override;
virtual void bindVertexBuffer(const Array<VertexInputStream>& streams) override;
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) override;
virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) override;
virtual void draw(const MeshBatchElement& data) override;
virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) override;
private:
@@ -121,6 +122,7 @@ public:
virtual void bindPipeline(Gfx::PComputePipeline pipeline) override;
virtual void bindDescriptor(Gfx::PDescriptorSet set) override;
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) override;
virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) override;
virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) override;
private:
PComputePipeline pipeline;
@@ -29,6 +29,7 @@ void DescriptorLayout::create()
return;
}
bindings.resize(descriptorBindings.size());
Array<VkDescriptorBindingFlags> bindingFlags(descriptorBindings.size());
for (size_t i = 0; i < descriptorBindings.size(); ++i)
{
VkDescriptorSetLayoutBinding &binding = bindings[i];
@@ -38,9 +39,16 @@ void DescriptorLayout::create()
binding.descriptorType = cast(rhiBinding.descriptorType);
binding.stageFlags = rhiBinding.shaderStages;
binding.pImmutableSamplers = nullptr;
bindingFlags[i] = rhiBinding.bindingFlags;
}
VkDescriptorSetLayoutCreateInfo createInfo =
init::DescriptorSetLayoutCreateInfo(bindings.data(), (uint32)bindings.size());
VkDescriptorSetLayoutBindingFlagsCreateInfo bindingFlagsInfo = {};
bindingFlagsInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO;
bindingFlagsInfo.pNext = nullptr;
bindingFlagsInfo.bindingCount = static_cast<uint32>(bindingFlags.size());
bindingFlagsInfo.pBindingFlags = bindingFlags.data();
createInfo.pNext = &bindingFlagsInfo;
VK_CHECK(vkCreateDescriptorSetLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle));
allocator = new DescriptorAllocator(graphics, *this);
@@ -188,20 +196,54 @@ void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::
imageInfo.sampler = vulkanSampler->sampler;
}
imageInfos.add(imageInfo);
VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
if(samplerState != nullptr)
{
descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
}
else if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT)
{
descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
}
VkWriteDescriptorSet writeDescriptor =
init::WriteDescriptorSet(
setHandle,
samplerState != nullptr ? VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
descriptorType,
binding,
&imageInfos.back());
if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT)
{
writeDescriptor.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
}
writeDescriptors.add(writeDescriptor);
cachedData[binding] = vulkanTexture;
}
void DescriptorSet::updateTextureArray(uint32_t binding, Array<Gfx::PTexture> textures)
{
// maybe make this a parameter?
uint32 arrayElement = 0;
for(const auto& gfxTexture : textures)
{
TextureHandle* vulkanTexture = TextureBase::cast(gfxTexture);
imageInfos.add(
init::DescriptorImageInfo(
VK_NULL_HANDLE,
vulkanTexture->getView(),
cast(vulkanTexture->getLayout())));
VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT)
{
descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
}
VkWriteDescriptorSet& write = writeDescriptors.add(
init::WriteDescriptorSet(
setHandle,
descriptorType,
binding,
&imageInfos.back()
));
write.dstArrayElement = arrayElement++;
}
}
bool DescriptorSet::operator<(Gfx::PDescriptorSet other)
{
@@ -281,6 +323,20 @@ void DescriptorAllocator::allocateDescriptorSet(Gfx::PDescriptorSet &descriptorS
VkDescriptorSetLayout layoutHandle = layout.getHandle();
VkDescriptorSetAllocateInfo allocInfo =
init::DescriptorSetAllocateInfo(poolHandle, &layoutHandle, 1);
VkDescriptorSetVariableDescriptorCountAllocateInfo setCounts = {};
setCounts.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO;
setCounts.pNext = nullptr;
setCounts.descriptorSetCount = 1;
uint32 counts = 0;
for(const auto& binding : layout.bindings)
{
if(binding.binding & Gfx::SE_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT)
{
counts = binding.descriptorCount;
}
}
setCounts.pDescriptorCounts = &counts;
allocInfo.pNext = &setCounts;
for(uint32 setIndex = 0; setIndex < cachedHandles.size(); ++setIndex)
{
@@ -12,11 +12,10 @@ public:
DescriptorLayout(PGraphics graphics, const std::string& name);
virtual ~DescriptorLayout();
virtual void create();
inline VkDescriptorSetLayout getHandle() const
constexpr VkDescriptorSetLayout getHandle() const
{
return layoutHandle;
}
private:
uint32 hash;
PGraphics graphics;
@@ -72,6 +71,7 @@ public:
virtual void updateBuffer(uint32_t binding, Gfx::PStructuredBuffer uniformBuffer);
virtual void updateSampler(uint32_t binding, Gfx::PSamplerState samplerState);
virtual void updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSamplerState sampler = nullptr);
virtual void updateTextureArray(uint32_t binding, Array<Gfx::PTexture> texture);
virtual bool operator<(Gfx::PDescriptorSet other);
inline bool isCurrentlyBound() const
+27 -2
View File
@@ -204,11 +204,27 @@ Gfx::PComputePipeline Graphics::createComputePipeline(const ComputePipelineCreat
return pipeline;
}
Gfx::PSamplerState Graphics::createSamplerState(const SamplerCreateInfo&)
Gfx::PSamplerState Graphics::createSamplerState(const SamplerCreateInfo& createInfo)
{
PSamplerState sampler = new SamplerState(); // TODO: proper sampler creation
PSamplerState sampler = new SamplerState();
VkSamplerCreateInfo vkInfo =
init::SamplerCreateInfo();
vkInfo.addressModeU = cast(createInfo.addressModeU);
vkInfo.addressModeV = cast(createInfo.addressModeV);
vkInfo.addressModeW = cast(createInfo.addressModeW);
vkInfo.anisotropyEnable = createInfo.anisotropyEnable;
vkInfo.borderColor = cast(createInfo.borderColor);
vkInfo.compareEnable = createInfo.compareEnable;
vkInfo.compareOp = cast(createInfo.compareOp);
vkInfo.flags = createInfo.flags;
vkInfo.magFilter = cast(createInfo.magFilter);
vkInfo.maxAnisotropy = createInfo.maxAnisotropy;
vkInfo.maxLod = createInfo.maxLod;
vkInfo.minFilter = cast(createInfo.minFilter);
vkInfo.minLod = createInfo.minLod;
vkInfo.mipLodBias = createInfo.mipLodBias;
vkInfo.mipmapMode = cast(createInfo.mipmapMode);
vkInfo.unnormalizedCoordinates = createInfo.unnormalizedCoordinates;
VK_CHECK(vkCreateSampler(handle, &vkInfo, nullptr, &sampler->sampler));
return sampler;
}
@@ -537,6 +553,15 @@ void Graphics::createDevice(GraphicsInitializer initializer)
queueInfos.data(),
(uint32)queueInfos.size(),
&features);
VkPhysicalDeviceDescriptorIndexingFeatures descriptorIndexing = {};
std::memset(&descriptorIndexing, 0, sizeof(descriptorIndexing));
descriptorIndexing.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES;
descriptorIndexing.shaderSampledImageArrayNonUniformIndexing = VK_TRUE;
descriptorIndexing.runtimeDescriptorArray = VK_TRUE;
descriptorIndexing.descriptorBindingVariableDescriptorCount = VK_TRUE;
descriptorIndexing.descriptorBindingPartiallyBound = VK_TRUE;
deviceInfo.pNext = &descriptorIndexing;
#if ENABLE_VALIDATION
VkDeviceDiagnosticsConfigCreateInfoNV crashDiagInfo;
crashDiagInfo.sType = VK_STRUCTURE_TYPE_DEVICE_DIAGNOSTICS_CONFIG_CREATE_INFO_NV;
@@ -1421,3 +1421,134 @@ Gfx::SeClearValue Seele::Vulkan::cast(const VkClearValue& clear)
}
return result;
}
VkSamplerAddressMode Seele::Vulkan::cast(const Gfx::SeSamplerAddressMode &mode)
{
switch(mode)
{
case SE_SAMPLER_ADDRESS_MODE_REPEAT:
return VK_SAMPLER_ADDRESS_MODE_REPEAT;
case SE_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT:
return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
case SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE:
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
case SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER:
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
case SE_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE:
return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
default:
return VK_SAMPLER_ADDRESS_MODE_MAX_ENUM;
}
}
Gfx::SeSamplerAddressMode Seele::Vulkan::cast(const VkSamplerAddressMode &mode)
{
switch(mode)
{
case VK_SAMPLER_ADDRESS_MODE_REPEAT:
return SE_SAMPLER_ADDRESS_MODE_REPEAT;
case VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT:
return SE_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE:
return SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER:
return SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
case VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE:
return SE_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
default:
return SE_SAMPLER_ADDRESS_MODE_MAX_ENUM;
}
}
VkBorderColor Seele::Vulkan::cast(const Gfx::SeBorderColor &color)
{
switch(color)
{
case SE_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:
return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
case SE_BORDER_COLOR_INT_TRANSPARENT_BLACK:
return VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
case SE_BORDER_COLOR_FLOAT_OPAQUE_BLACK:
return VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
case SE_BORDER_COLOR_INT_OPAQUE_BLACK:
return VK_BORDER_COLOR_INT_OPAQUE_BLACK;
case SE_BORDER_COLOR_FLOAT_OPAQUE_WHITE:
return VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
case SE_BORDER_COLOR_INT_OPAQUE_WHITE:
return VK_BORDER_COLOR_INT_OPAQUE_WHITE;
default:
return VK_BORDER_COLOR_MAX_ENUM;
}
}
Gfx::SeBorderColor Seele::Vulkan::cast(const VkBorderColor &color)
{
switch(color)
{
case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:
return SE_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
case VK_BORDER_COLOR_INT_TRANSPARENT_BLACK:
return SE_BORDER_COLOR_INT_TRANSPARENT_BLACK;
case VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK:
return SE_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
case VK_BORDER_COLOR_INT_OPAQUE_BLACK:
return SE_BORDER_COLOR_INT_OPAQUE_BLACK;
case VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE:
return SE_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
case VK_BORDER_COLOR_INT_OPAQUE_WHITE:
return SE_BORDER_COLOR_INT_OPAQUE_WHITE;
default:
return SE_BORDER_COLOR_MAX_ENUM;
}
}
VkFilter Seele::Vulkan::cast(const Gfx::SeFilter &filter)
{
switch(filter)
{
case SE_FILTER_NEAREST:
return VK_FILTER_NEAREST;
case SE_FILTER_LINEAR:
return VK_FILTER_LINEAR;
case SE_FILTER_CUBIC_IMG:
return VK_FILTER_CUBIC_IMG;
default:
return VK_FILTER_MAX_ENUM;
}
}
Gfx::SeFilter Seele::Vulkan::cast(const VkFilter &filter)
{
switch(filter)
{
case VK_FILTER_NEAREST:
return SE_FILTER_NEAREST;
case VK_FILTER_LINEAR:
return SE_FILTER_LINEAR;
case VK_FILTER_CUBIC_IMG:
return SE_FILTER_CUBIC_IMG;
default:
return SE_FILTER_MAX_ENUM;
}
}
VkSamplerMipmapMode Seele::Vulkan::cast(const Gfx::SeSamplerMipmapMode &filter)
{
switch(filter)
{
case SE_SAMPLER_MIPMAP_MODE_NEAREST:
return VK_SAMPLER_MIPMAP_MODE_NEAREST;
case SE_SAMPLER_MIPMAP_MODE_LINEAR:
return VK_SAMPLER_MIPMAP_MODE_LINEAR;
default:
return VK_SAMPLER_MIPMAP_MODE_MAX_ENUM;
}
}
Gfx::SeSamplerMipmapMode Seele::Vulkan::cast(const VkSamplerMipmapMode &filter)
{
switch(filter)
{
case VK_SAMPLER_MIPMAP_MODE_NEAREST:
return SE_SAMPLER_MIPMAP_MODE_NEAREST;
case VK_SAMPLER_MIPMAP_MODE_LINEAR:
return SE_SAMPLER_MIPMAP_MODE_LINEAR;
default:
return SE_SAMPLER_MIPMAP_MODE_MAX_ENUM;
}
}
@@ -54,5 +54,13 @@ VkCompareOp cast(const Gfx::SeCompareOp &op);
Gfx::SeCompareOp cast(const VkCompareOp &op);
VkClearValue cast(const Gfx::SeClearValue &clear);
Gfx::SeClearValue cast(const VkClearValue &clear);
VkSamplerAddressMode cast(const Gfx::SeSamplerAddressMode &mode);
Gfx::SeSamplerAddressMode cast(const VkSamplerAddressMode &mode);
VkBorderColor cast(const Gfx::SeBorderColor &color);
Gfx::SeBorderColor cast(const VkBorderColor &color);
VkFilter cast(const Gfx::SeFilter &filter);
Gfx::SeFilter cast(const VkFilter &filter);
VkSamplerMipmapMode cast(const Gfx::SeSamplerMipmapMode &filter);
Gfx::SeSamplerMipmapMode cast(const VkSamplerMipmapMode &filter);
} // namespace Vulkan
} // namespace Seele
+1 -2
View File
@@ -116,8 +116,7 @@ void MaterialAsset::load()
{
PSamplerParameter p = new SamplerParameter(param.key(), 0, bindingCounter);
layout->addDescriptorBinding(bindingCounter++, Gfx::SE_DESCRIPTOR_TYPE_SAMPLER);
SamplerCreateInfo createInfo;
p->data = WindowManager::getGraphics()->createSamplerState(createInfo);
p->data = WindowManager::getGraphics()->createSamplerState({});
parameters.add(p);
}
else
+17 -3
View File
@@ -2,17 +2,29 @@
#include "Graphics/Graphics.h"
#include "Scene/Actor/Actor.h"
#include "Window.h"
#include "Asset/AssetRegistry.h"
using namespace Seele;
InspectorView::InspectorView(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo &createInfo)
: View(graphics, window, createInfo, "InspectorView")
, uiPass(UIPass(graphics, viewport, new Gfx::SwapchainAttachment(window->getGfxHandle())))
, textPass(TextPass(graphics, viewport, new Gfx::SwapchainAttachment(window->getGfxHandle())))
{
AssetRegistry::importFile("./fonts/Calibri.ttf");
PRenderGraphResources resources = new RenderGraphResources();
uiPass.setResources(resources);
textPass.setResources(resources);
uiPass.publishOutputs();
textPass.publishOutputs();
uiPass.createRenderPass();
textPass.createRenderPass();
TextRender& render = textPassData.texts.add();
render.font = AssetRegistry::findFont("Calibri");
render.text = "Seele Engine";
render.position = Vector2(0.5f, 0.5f);
render.scale = 1.0f;
render.textColor = Vector4(1, 1, 1, 1);
}
InspectorView::~InspectorView()
@@ -31,19 +43,21 @@ Job InspectorView::update()
void InspectorView::commitUpdate()
{
}
void InspectorView::prepareRender()
{
textPass.updateViewFrame(textPassData);
}
MainJob InspectorView::render()
{
return uiPass.beginFrame()
.then(textPass.beginFrame())
.then(uiPass.render())
.then(uiPass.endFrame());
.then(textPass.render())
.then(uiPass.endFrame())
.then(textPass.endFrame());
}
void InspectorView::keyCallback(KeyCode, InputAction, KeyModifier)
+3
View File
@@ -2,6 +2,7 @@
#include "View.h"
#include "Graphics/RenderPass/RenderGraph.h"
#include "Graphics/RenderPass/UIPass.h"
#include "Graphics/RenderPass/TextPass.h"
#include "UI/Elements/Panel.h"
namespace Seele
@@ -22,8 +23,10 @@ public:
void selectActor();
protected:
UIPass uiPass;
TextPass textPass;
UIPassData uiPassData;
TextPassData textPassData;
UI::PPanel rootPanel;
PActor selectedActor;
-1
View File
@@ -20,7 +20,6 @@ Seele::SceneView::SceneView(Gfx::PGraphics graphics, PWindow owner, const Viewpo
{
scene = new Scene(graphics);
scene->addActor(activeCamera);
AssetRegistry::importFile("./fonts/GLSNECB.ttf");
AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Avatar_Girl_Sword_Ayaka_Tex_Body_Diffuse.png");
AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Avatar_Girl_Sword_Ayaka_Tex_Body_Lightmap.png");
AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Avatar_Girl_Sword_Ayaka_Tex_Face_Diffuse.png");
+4 -136
View File
@@ -19,7 +19,7 @@ int main()
mainWindowInfo.pixelFormat = Gfx::SE_FORMAT_B8G8R8A8_UNORM;
auto window = windowManager->addWindow(mainWindowInfo);
ViewportCreateInfo sceneViewInfo;
sceneViewInfo.sizeX = 1280;
sceneViewInfo.sizeX = 680;
sceneViewInfo.sizeY = 720;
sceneViewInfo.offsetX = 0;
sceneViewInfo.offsetY = 0;
@@ -31,144 +31,12 @@ int main()
inspectorViewInfo.sizeY = 720;
inspectorViewInfo.offsetX = 640;
inspectorViewInfo.offsetY = 0;
//PInspectorView inspectorView = new InspectorView(windowManager->getGraphics(), window, inspectorViewInfo);
//window->addView(inspectorView);
PInspectorView inspectorView = new InspectorView(windowManager->getGraphics(), window, inspectorViewInfo);
window->addView(inspectorView);
sceneView->setFocused();
window->render();
getGlobalThreadPool().mainLoop();
return 0;
}
/*
#include <coroutine>
#include <iostream>
#include <thread>
#include <vector>
struct Return;
struct Promise
{
Promise()
{
handle = std::coroutine_handle<Promise>::from_promise(*this);
numRefs = 0;
}
Return get_return_object();
std::suspend_always initial_suspend() noexcept { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
void return_void() {}
void unhandled_exception() {}
void resume() { handle.resume(); }
void addRef()
{
numRefs++;
}
void removeRef()
{
numRefs--;
if(numRefs == 0)
{
if(handle.done())
{
handle.destroy();
}
else
{
resume();
}
}
}
std::coroutine_handle<Promise> handle;
uint64_t numRefs;
};
struct Return
{
using promise_type = Promise;
Return(Promise* promise)
: promise(promise)
{
promise->addRef();
}
Return(const Return& other)
{
promise = other.promise;
if(promise != nullptr)
{
promise->addRef();
}
}
Return(Return&& other)
{
promise = other.promise;
other.promise = nullptr;
}
~Return()
{
promise->removeRef();
}
Return& operator=(const Return& other)
{
if(this != &other)
{
if(promise != nullptr)
{
promise->removeRef();
}
promise = other.promise;
if(promise != nullptr)
{
promise->addRef();
}
}
return *this;
}
Return& operator=(Return&& other)
{
if(this != &other)
{
if(promise != nullptr)
{
promise->removeRef();
}
promise = other.promise;
}
}
Promise* promise;
};
Return Promise::get_return_object(){
return {this};
}
Return coro1()
{
std::cout << "coro1" << std::endl;
co_return;
}
Return coro2()
{
std::cout << "coro2" << std::endl;
co_return;
}
Return coroAll(std::vector<Return> coros)
{
for(auto coro : coros)
{
coro.promise->resume();
}
co_return;
}
int main()
{
std::vector<Return> returns{coro1(), coro2()};
std::thread t = std::thread([returns](){
coroAll(returns);
});
t.join();
}*/
}