Refactoring basic text rendering
This commit is contained in:
@@ -105,7 +105,8 @@ class Graphics {
|
||||
|
||||
virtual void copyBuffer(Gfx::PShaderBuffer src, Gfx::PShaderBuffer dst) = 0;
|
||||
|
||||
bool supportMeshShading() const { return meshShadingEnabled; }
|
||||
constexpr bool supportMeshShading() const { return meshShadingEnabled; }
|
||||
constexpr bool supportRayTracing() const { return rayTracingEnabled; }
|
||||
|
||||
// Ray Tracing
|
||||
virtual OBottomLevelAS createBottomLevelAccelerationStructure(const BottomLevelASCreateInfo& createInfo) = 0;
|
||||
@@ -122,6 +123,7 @@ class Graphics {
|
||||
QueueFamilyMapping queueMapping;
|
||||
OShaderCompiler shaderCompiler;
|
||||
bool meshShadingEnabled = false;
|
||||
bool rayTracingEnabled = false;
|
||||
friend class Window;
|
||||
};
|
||||
DEFINE_REF(Graphics)
|
||||
|
||||
@@ -30,10 +30,12 @@ void Mesh::load(ArchiveBuffer& buffer) {
|
||||
referencedMaterial = AssetRegistry::findMaterialInstance(refFolder, refId);
|
||||
id = vertexData->allocateVertexData(vertexCount);
|
||||
byteSize = vertexData->deserializeMesh(id, buffer);
|
||||
blas = buffer.getGraphics()->createBottomLevelAccelerationStructure(Gfx::BottomLevelASCreateInfo{
|
||||
.mesh = this,
|
||||
});
|
||||
vertexData->registerBottomLevelAccelerationStructure(blas);
|
||||
if (buffer.getGraphics()->supportRayTracing()) {
|
||||
blas = buffer.getGraphics()->createBottomLevelAccelerationStructure(Gfx::BottomLevelASCreateInfo{
|
||||
.mesh = this,
|
||||
});
|
||||
vertexData->registerBottomLevelAccelerationStructure(blas);
|
||||
}
|
||||
}
|
||||
|
||||
uint64 Mesh::getCPUSize() const {
|
||||
|
||||
@@ -25,7 +25,7 @@ void Seele::addDebugVertex(DebugVertex vert) { gDebugVertices.add(vert); }
|
||||
|
||||
void Seele::addDebugVertices(Array<DebugVertex> verts) { gDebugVertices.addAll(verts); }
|
||||
|
||||
BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) {
|
||||
BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics), scene(scene) {
|
||||
//waterRenderer = new WaterRenderer(graphics, scene, viewParamsLayout);
|
||||
basePassLayout = graphics->createPipelineLayout("BasePassLayout");
|
||||
|
||||
|
||||
@@ -78,6 +78,7 @@ class BasePass : public RenderPass {
|
||||
} skyboxData;
|
||||
Gfx::OUniformBuffer skyboxBuffer;
|
||||
Component::Skybox skybox;
|
||||
PScene scene;
|
||||
};
|
||||
DEFINE_REF(BasePass)
|
||||
} // namespace Seele
|
||||
|
||||
@@ -17,8 +17,6 @@ target_sources(Engine
|
||||
RenderPass.cpp
|
||||
TerrainRenderer.h
|
||||
TerrainRenderer.cpp
|
||||
TextPass.h
|
||||
TextPass.cpp
|
||||
UIPass.h
|
||||
UIPass.cpp
|
||||
VisibilityPass.h
|
||||
@@ -38,6 +36,5 @@ target_sources(Engine
|
||||
RenderGraphResources.h
|
||||
RenderPass.h
|
||||
TerrainRenderer.h
|
||||
TextPass.h
|
||||
UIPass.h
|
||||
VisibilityPass.h)
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
CachedDepthPass::CachedDepthPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) {
|
||||
CachedDepthPass::CachedDepthPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics), scene(scene) {
|
||||
depthPrepassLayout = graphics->createPipelineLayout("CachedDepthLayout");
|
||||
depthPrepassLayout->addDescriptorLayout(viewParamsLayout);
|
||||
depthPrepassLayout->addPushConstants(Gfx::SePushConstantRange{
|
||||
|
||||
@@ -25,6 +25,7 @@ class CachedDepthPass : public RenderPass {
|
||||
Gfx::OTimestampQuery timestamps;
|
||||
|
||||
Gfx::PShaderBuffer cullingBuffer;
|
||||
PScene scene;
|
||||
};
|
||||
DEFINE_REF(CachedDepthPass)
|
||||
} // namespace Seele
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
DepthCullingPass::DepthCullingPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) {
|
||||
DepthCullingPass::DepthCullingPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics), scene(scene) {
|
||||
depthAttachmentLayout = graphics->createDescriptorLayout("pDepthAttachment");
|
||||
depthAttachmentLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 0,
|
||||
|
||||
@@ -44,6 +44,7 @@ class DepthCullingPass : public RenderPass {
|
||||
Gfx::PComputePipeline depthReduceLevel;
|
||||
|
||||
Gfx::PShaderBuffer cullingBuffer;
|
||||
PScene scene;
|
||||
};
|
||||
DEFINE_REF(DepthCullingPass)
|
||||
} // namespace Seele
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
LightCullingPass::LightCullingPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) {}
|
||||
LightCullingPass::LightCullingPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics), scene(scene) {}
|
||||
|
||||
LightCullingPass::~LightCullingPass() {}
|
||||
|
||||
|
||||
@@ -58,6 +58,8 @@ class LightCullingPass : public RenderPass {
|
||||
Gfx::PComputePipeline cullingEnabledPipeline;
|
||||
Gfx::OPipelineStatisticsQuery query;
|
||||
Gfx::PTimestampQuery timestamps;
|
||||
|
||||
PScene scene;
|
||||
};
|
||||
DEFINE_REF(LightCullingPass)
|
||||
} // namespace Seele
|
||||
|
||||
@@ -14,7 +14,7 @@ struct SampleParams {
|
||||
uint32 samplesPerPixel;
|
||||
};
|
||||
|
||||
RayTracingPass::RayTracingPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) {
|
||||
RayTracingPass::RayTracingPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics), scene(scene) {
|
||||
paramsLayout = graphics->createDescriptorLayout("pRayTracingParams");
|
||||
paramsLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 0,
|
||||
|
||||
@@ -25,5 +25,6 @@ class RayTracingPass : public RenderPass {
|
||||
Gfx::OMissShader miss;
|
||||
Gfx::PRayTracingPipeline pipeline;
|
||||
Gfx::OTopLevelAS tlas;
|
||||
PScene scene;
|
||||
};
|
||||
} // namespace Seele
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
RenderPass::RenderPass(Gfx::PGraphics graphics, PScene scene) : graphics(graphics), scene(scene) {
|
||||
RenderPass::RenderPass(Gfx::PGraphics graphics) : graphics(graphics) {
|
||||
viewParamsLayout = graphics->createDescriptorLayout("pViewParams");
|
||||
viewParamsLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 0,
|
||||
|
||||
@@ -14,7 +14,7 @@ DECLARE_NAME_REF(Gfx, Graphics)
|
||||
DECLARE_NAME_REF(Gfx, RenderPass)
|
||||
class RenderPass {
|
||||
public:
|
||||
RenderPass(Gfx::PGraphics graphics, PScene scene);
|
||||
RenderPass(Gfx::PGraphics graphics);
|
||||
RenderPass(RenderPass&&) = default;
|
||||
RenderPass& operator=(RenderPass&&) = default;
|
||||
virtual ~RenderPass();
|
||||
@@ -71,7 +71,6 @@ class RenderPass {
|
||||
Gfx::ORenderPass renderPass;
|
||||
Gfx::PGraphics graphics;
|
||||
Gfx::PViewport viewport;
|
||||
PScene scene;
|
||||
};
|
||||
DEFINE_REF(RenderPass)
|
||||
template <typename RP>
|
||||
|
||||
@@ -1,202 +0,0 @@
|
||||
#include "TextPass.h"
|
||||
#include "Graphics/Command.h"
|
||||
#include "Graphics/Enums.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/RenderTarget.h"
|
||||
#include "RenderGraph.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
TextPass::TextPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) {}
|
||||
|
||||
TextPass::~TextPass() {}
|
||||
|
||||
void TextPass::beginFrame(const Component::Camera& cam) {
|
||||
RenderPass::beginFrame(cam);
|
||||
for (TextRender& render : texts) {
|
||||
FontData& fd = getFontData(render.font);
|
||||
TextResources& res = textResources[render.font].add();
|
||||
Array<GlyphInstanceData> instanceData;
|
||||
float x = render.position.x;
|
||||
float y = render.position.y;
|
||||
for (uint32 c : render.text) {
|
||||
const GlyphData& glyph = fd.glyphDataSet[fd.characterToGlyphIndex[c]];
|
||||
Vector2 bearing = glyph.bearing;
|
||||
Vector2 size = glyph.size;
|
||||
float xpos = x + bearing.x * render.scale;
|
||||
float ypos = y - (size.y - bearing.y) * render.scale;
|
||||
|
||||
float w = size.x * render.scale;
|
||||
float h = size.y * render.scale;
|
||||
|
||||
instanceData.add(GlyphInstanceData{
|
||||
.position = Vector2(xpos, ypos),
|
||||
.widthHeight = Vector2(w, h),
|
||||
.glyphIndex = fd.characterToGlyphIndex[c],
|
||||
});
|
||||
x += (glyph.advance >> 6) * render.scale;
|
||||
}
|
||||
res.instanceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = static_cast<uint32>(instanceData.size() * sizeof(GlyphInstanceData)),
|
||||
.data = reinterpret_cast<uint8*>(instanceData.data()),
|
||||
},
|
||||
.numElements = instanceData.size(),
|
||||
});
|
||||
|
||||
res.textureArraySet = fd.textureArraySet;
|
||||
|
||||
res.textData = {
|
||||
.textColor = render.textColor,
|
||||
.scale = render.scale,
|
||||
};
|
||||
}
|
||||
auto proj = viewport->getProjectionMatrix();
|
||||
projectionBuffer->updateContents(0, sizeof(Matrix4), &proj);
|
||||
generalSet->updateBuffer(1, 0, projectionBuffer);
|
||||
generalSet->writeChanges();
|
||||
// co_return;
|
||||
}
|
||||
|
||||
void TextPass::render() {
|
||||
graphics->beginRenderPass(renderPass);
|
||||
Array<Gfx::ORenderCommand> commands;
|
||||
for (const auto& [fontAsset, res] : textResources) {
|
||||
Gfx::ORenderCommand command = graphics->createRenderCommand("TextPassCommand");
|
||||
command->setViewport(viewport);
|
||||
command->bindPipeline(pipeline);
|
||||
for (const auto& resource : res) {
|
||||
command->bindDescriptor({generalSet, resource.textureArraySet});
|
||||
// command->bindVertexBuffer({resource.vertexBuffer});
|
||||
|
||||
command->pushConstants(Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(TextData),
|
||||
&resource.textData);
|
||||
// command->draw(4, static_cast<uint32>(resource.vertexBuffer->getNumVertices()), 0, 0);
|
||||
}
|
||||
commands.add(std::move(command));
|
||||
}
|
||||
graphics->executeCommands(std::move(commands));
|
||||
graphics->endRenderPass();
|
||||
textResources.clear();
|
||||
// co_return;
|
||||
}
|
||||
|
||||
void TextPass::endFrame() {
|
||||
// co_return;
|
||||
}
|
||||
|
||||
void TextPass::publishOutputs() {}
|
||||
|
||||
void TextPass::createRenderPass() {
|
||||
renderTarget = resources->requestRenderTarget("UIPASS_COLOR");
|
||||
depthAttachment = resources->requestRenderTarget("UIPASS_DEPTH");
|
||||
|
||||
ShaderCompilationInfo createInfo = {
|
||||
.name = "TextVertex",
|
||||
.modules = {"TextPass"},
|
||||
.entryPoints = {{"vertexMain", "TextPass"}, {"fragmentMain", "TextFragment"}},
|
||||
};
|
||||
graphics->beginShaderCompilation(createInfo);
|
||||
vertexShader = graphics->createVertexShader({0});
|
||||
fragmentShader = graphics->createFragmentShader({1});
|
||||
|
||||
generalLayout = graphics->createDescriptorLayout("pRender");
|
||||
generalLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 0,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
.uniformLength = sizeof(Matrix4),
|
||||
});
|
||||
generalLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 1,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER,
|
||||
});
|
||||
generalLayout->create();
|
||||
|
||||
textureArrayLayout = graphics->createDescriptorLayout("pGlyphTextures");
|
||||
textureArrayLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 0,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
.textureType = Gfx::SE_IMAGE_VIEW_TYPE_2D_ARRAY,
|
||||
.descriptorCount = 256,
|
||||
.bindingFlags = Gfx::SE_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT,
|
||||
});
|
||||
textureArrayLayout->create();
|
||||
|
||||
projectionBuffer = graphics->createUniformBuffer({
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(Matrix4),
|
||||
.data = nullptr,
|
||||
},
|
||||
});
|
||||
|
||||
glyphSampler = graphics->createSampler({
|
||||
.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,
|
||||
});
|
||||
|
||||
generalSet = generalLayout->allocateDescriptorSet();
|
||||
generalSet->updateBuffer(0, 0, projectionBuffer);
|
||||
generalSet->updateSampler(1, 0, glyphSampler);
|
||||
generalSet->writeChanges();
|
||||
|
||||
pipelineLayout = graphics->createPipelineLayout();
|
||||
pipelineLayout->addDescriptorLayout(generalLayout);
|
||||
pipelineLayout->addDescriptorLayout(textureArrayLayout);
|
||||
pipelineLayout->addPushConstants(
|
||||
{.stageFlags = Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, .offset = 0, .size = sizeof(TextData)});
|
||||
pipelineLayout->create();
|
||||
|
||||
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{.colorAttachments = {renderTarget}, .depthAttachment = depthAttachment};
|
||||
renderPass = graphics->createRenderPass(std::move(layout), {}, viewport);
|
||||
|
||||
Gfx::LegacyPipelineCreateInfo pipelineInfo;
|
||||
pipelineInfo.vertexShader = vertexShader;
|
||||
pipelineInfo.fragmentShader = fragmentShader;
|
||||
pipelineInfo.renderPass = renderPass;
|
||||
pipelineInfo.pipelineLayout = pipelineLayout;
|
||||
pipelineInfo.rasterizationState.cullMode = Gfx::SE_CULL_MODE_NONE;
|
||||
pipelineInfo.colorBlend.attachmentCount = 1;
|
||||
pipelineInfo.colorBlend.blendAttachments[0].blendEnable = true;
|
||||
pipelineInfo.colorBlend.blendAttachments[0].colorWriteMask =
|
||||
Gfx::SE_COLOR_COMPONENT_R_BIT | Gfx::SE_COLOR_COMPONENT_G_BIT | Gfx::SE_COLOR_COMPONENT_B_BIT | Gfx::SE_COLOR_COMPONENT_A_BIT;
|
||||
pipelineInfo.colorBlend.blendAttachments[0].srcColorBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA;
|
||||
pipelineInfo.colorBlend.blendAttachments[0].dstColorBlendFactor = Gfx::SE_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
pipelineInfo.colorBlend.blendAttachments[0].alphaBlendOp = Gfx::SE_BLEND_OP_ADD;
|
||||
pipelineInfo.colorBlend.blendAttachments[0].srcAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
pipelineInfo.colorBlend.blendAttachments[0].dstAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_ZERO;
|
||||
pipelineInfo.colorBlend.blendAttachments[0].alphaBlendOp = Gfx::SE_BLEND_OP_ADD;
|
||||
pipelineInfo.topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
|
||||
|
||||
pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||
}
|
||||
TextPass::FontData& TextPass::getFontData(PFontAsset font) {
|
||||
if (fontData.exists(font)) {
|
||||
return fontData[font];
|
||||
}
|
||||
const auto& fontGlyphs = font->getGlyphData();
|
||||
FontData& fd = fontData[font];
|
||||
Array<GlyphData> glyphData;
|
||||
Array<Gfx::PTexture2D> textures;
|
||||
glyphData.reserve(fontGlyphs.size());
|
||||
for (const auto& [key, value] : fontGlyphs) {
|
||||
fd.characterToGlyphIndex[key] = static_cast<uint32>(glyphData.size());
|
||||
GlyphData& gd = glyphData.add();
|
||||
gd.bearing = value.bearing;
|
||||
gd.size = value.size;
|
||||
gd.advance = value.advance;
|
||||
textures.add(font->getTexture(value.textureIndex));
|
||||
}
|
||||
fd.glyphDataSet = glyphData;
|
||||
|
||||
textureArrayLayout->reset();
|
||||
fd.textureArraySet = textureArrayLayout->allocateDescriptorSet();
|
||||
for (uint32 i = 0; i < textures.size(); ++i) {
|
||||
fd.textureArraySet->updateTexture(0, i, textures[i]);
|
||||
}
|
||||
fd.textureArraySet->writeChanges();
|
||||
return fontData[font];
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
#pragma once
|
||||
#include "Asset/FontAsset.h"
|
||||
#include "Graphics/Shader.h"
|
||||
#include "RenderPass.h"
|
||||
#include "UI/RenderHierarchy.h"
|
||||
|
||||
|
||||
namespace Seele {
|
||||
DECLARE_NAME_REF(Gfx, Texture2D)
|
||||
DECLARE_NAME_REF(Gfx, ShaderBuffer)
|
||||
struct TextRender {
|
||||
std::string text;
|
||||
PFontAsset font;
|
||||
Vector4 textColor;
|
||||
Vector2 position;
|
||||
float scale;
|
||||
};
|
||||
class TextPass : public RenderPass {
|
||||
public:
|
||||
TextPass(Gfx::PGraphics graphics, PScene scene);
|
||||
TextPass(TextPass&&) = default;
|
||||
TextPass& operator=(TextPass&&) = default;
|
||||
virtual ~TextPass();
|
||||
virtual void beginFrame(const Component::Camera& cam) override;
|
||||
virtual void render() override;
|
||||
virtual void endFrame() override;
|
||||
virtual void publishOutputs() override;
|
||||
virtual void createRenderPass() override;
|
||||
|
||||
private:
|
||||
struct GlyphData {
|
||||
Vector2 bearing;
|
||||
Vector2 size;
|
||||
uint32 advance;
|
||||
};
|
||||
struct GlyphInstanceData {
|
||||
Vector2 position;
|
||||
Vector2 widthHeight;
|
||||
uint32 glyphIndex;
|
||||
};
|
||||
struct TextData {
|
||||
Vector4 textColor;
|
||||
float scale;
|
||||
};
|
||||
struct FontData {
|
||||
Gfx::PDescriptorSet textureArraySet;
|
||||
Array<GlyphData> glyphDataSet;
|
||||
Map<uint32, uint32> characterToGlyphIndex;
|
||||
};
|
||||
FontData& getFontData(PFontAsset font);
|
||||
Map<PFontAsset, FontData> fontData;
|
||||
|
||||
struct TextResources {
|
||||
Gfx::PShaderBuffer instanceBuffer;
|
||||
Gfx::PDescriptorSet textureArraySet;
|
||||
TextData textData;
|
||||
};
|
||||
Map<PFontAsset, Array<TextResources>> textResources;
|
||||
|
||||
Gfx::RenderTargetAttachment renderTarget;
|
||||
Gfx::RenderTargetAttachment depthAttachment;
|
||||
|
||||
Gfx::ODescriptorLayout generalLayout;
|
||||
Gfx::ODescriptorLayout textureArrayLayout;
|
||||
|
||||
Gfx::PDescriptorSet generalSet;
|
||||
|
||||
Gfx::OUniformBuffer projectionBuffer;
|
||||
Gfx::OSampler glyphSampler;
|
||||
|
||||
Gfx::OVertexShader vertexShader;
|
||||
Gfx::OFragmentShader fragmentShader;
|
||||
Gfx::OPipelineLayout pipelineLayout;
|
||||
Gfx::PGraphicsPipeline pipeline;
|
||||
Array<TextRender> texts;
|
||||
};
|
||||
DEFINE_REF(TextPass);
|
||||
} // namespace Seele
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "UIPass.h"
|
||||
#include "Asset/AssetRegistry.h"
|
||||
#include "Graphics/Command.h"
|
||||
#include "Graphics/Enums.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
@@ -7,53 +8,100 @@
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
UIPass::UIPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) {}
|
||||
UIPass::UIPass(Gfx::PGraphics graphics, UI::PSystem system) : RenderPass(graphics) {
|
||||
glyphInstanceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{.name = "GlyphInstanceBuffer"});
|
||||
textDescriptorLayout = graphics->createDescriptorLayout("pText");
|
||||
textDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 0,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
textDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 1,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER,
|
||||
});
|
||||
textDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 2,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
.descriptorCount = 1024,
|
||||
});
|
||||
textPipelineLayout = graphics->createPipelineLayout("TextPipeline");
|
||||
textPipelineLayout->addDescriptorLayout(viewParamsLayout);
|
||||
textPipelineLayout->addDescriptorLayout(textDescriptorLayout);
|
||||
|
||||
uiPipelineLayout = graphics->createPipelineLayout("UIPipeline");
|
||||
uiPipelineLayout->addDescriptorLayout(viewParamsLayout);
|
||||
// todo:
|
||||
texts.add(TextRender{
|
||||
.text = "TestText123",
|
||||
.font = AssetRegistry::findFont("", "arial"),
|
||||
.fontSize = 12,
|
||||
.position = Vector2(0, 100),
|
||||
});
|
||||
}
|
||||
|
||||
UIPass::~UIPass() {}
|
||||
|
||||
void UIPass::beginFrame(const Component::Camera& cam) {
|
||||
RenderPass::beginFrame(cam);
|
||||
VertexBufferCreateInfo info = {
|
||||
.sourceData =
|
||||
{
|
||||
.size = (uint32)(sizeof(UI::RenderElementStyle) * renderElements.size()),
|
||||
.data = (uint8*)renderElements.data(),
|
||||
},
|
||||
.vertexSize = sizeof(UI::RenderElementStyle),
|
||||
.numVertices = (uint32)renderElements.size(),
|
||||
};
|
||||
elementBuffer = graphics->createVertexBuffer(info);
|
||||
uint32 numTextures = static_cast<uint32>(usedTextures.size());
|
||||
numTexturesBuffer->updateContents(0, sizeof(uint32), &numTextures);
|
||||
descriptorSet->updateBuffer(2, 0, numTexturesBuffer);
|
||||
for (uint32 i = 0; i < usedTextures.size(); ++i) {
|
||||
descriptorSet->updateTexture(3, i, usedTextures[i]);
|
||||
glyphs.clear();
|
||||
usedTextures.clear();
|
||||
for (TextRender& render : texts) {
|
||||
TextResources& res = textResources[render.font].add();
|
||||
float x = render.position.x * viewport->getContentScaleX();
|
||||
float y = (viewport->getHeight() - render.position.y) * viewport->getContentScaleY();
|
||||
for (uint32 c : render.text) {
|
||||
const FontAsset::Glyph& glyph = render.font->getGlyphData(c);
|
||||
Vector2 bearing = Vector2(glyph.bearing) * viewport->getContentScaleX();
|
||||
Vector2 size = Vector2(glyph.size) * viewport->getContentScaleY();
|
||||
float xpos = x + glyph.bearing.x;
|
||||
float ypos = y + (size.y - bearing.y);
|
||||
|
||||
float w = size.x;
|
||||
float h = size.y;
|
||||
|
||||
glyphs.add(GlyphInstanceData{
|
||||
.x = xpos,
|
||||
.y = ypos,
|
||||
.width = w,
|
||||
.height = h,
|
||||
.glyphIndex = (uint32)usedTextures.size(),
|
||||
});
|
||||
usedTextures.add(glyph.texture);
|
||||
x += glyph.advance >> 6;
|
||||
}
|
||||
}
|
||||
descriptorSet->writeChanges();
|
||||
// co_return;
|
||||
glyphInstanceBuffer->rotateBuffer(sizeof(GlyphInstanceData) * glyphs.size());
|
||||
glyphInstanceBuffer->updateContents(0, sizeof(GlyphInstanceData) * glyphs.size(), glyphs.data());
|
||||
glyphInstanceBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_VERTEX_SHADER_BIT);
|
||||
textDescriptorLayout->reset();
|
||||
textDescriptorSet = textDescriptorLayout->allocateDescriptorSet();
|
||||
textDescriptorSet->updateBuffer(0, 0, glyphInstanceBuffer);
|
||||
textDescriptorSet->updateSampler(1, 0, glyphSampler);
|
||||
for (uint32 i = 0; i < usedTextures.size(); ++i) {
|
||||
textDescriptorSet->updateTexture(2, i, usedTextures[i]);
|
||||
}
|
||||
textDescriptorSet->writeChanges();
|
||||
}
|
||||
|
||||
void UIPass::render() {
|
||||
graphics->beginRenderPass(renderPass);
|
||||
Gfx::ORenderCommand command = graphics->createRenderCommand("UIPassCommand");
|
||||
command->setViewport(viewport);
|
||||
command->bindPipeline(pipeline);
|
||||
command->bindVertexBuffer({elementBuffer});
|
||||
command->bindDescriptor(descriptorSet);
|
||||
command->draw(4, static_cast<uint32>(renderElements.size()), 0, 0);
|
||||
Array<Gfx::ORenderCommand> commands;
|
||||
Gfx::ORenderCommand command = graphics->createRenderCommand("TextPassCommand");
|
||||
command->setViewport(viewport);
|
||||
command->bindPipeline(textPipeline);
|
||||
command->bindDescriptor({viewParamsSet, textDescriptorSet});
|
||||
command->draw(4, glyphs.size(), 0, 0);
|
||||
commands.add(std::move(command));
|
||||
graphics->executeCommands(std::move(commands));
|
||||
graphics->endRenderPass();
|
||||
|
||||
// co_return;
|
||||
}
|
||||
|
||||
void UIPass::endFrame() {
|
||||
// co_return;
|
||||
}
|
||||
void UIPass::endFrame() {}
|
||||
|
||||
void UIPass::publishOutputs() {
|
||||
void UIPass::publishOutputs() {}
|
||||
|
||||
void UIPass::createRenderPass() {
|
||||
TextureCreateInfo depthBufferInfo = {
|
||||
.format = Gfx::SE_FORMAT_D32_SFLOAT,
|
||||
.width = viewport->getWidth(),
|
||||
@@ -65,98 +113,69 @@ void UIPass::publishOutputs() {
|
||||
depthAttachment =
|
||||
Gfx::RenderTargetAttachment(depthBuffer, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
||||
resources->registerRenderPassOutput("UIPASS_DEPTH", depthAttachment);
|
||||
depthAttachment.clear.depthStencil.depth = 0;
|
||||
|
||||
TextureCreateInfo colorBufferInfo = {
|
||||
.format = Gfx::SE_FORMAT_R16G16B16A16_SFLOAT,
|
||||
.width = viewport->getWidth(),
|
||||
.height = viewport->getHeight(),
|
||||
.usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
||||
colorAttachment = Gfx::RenderTargetAttachment(viewport, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
||||
colorAttachment.clear.color = {{1.0f, 1.0f, 1.0f, 1.0f}};
|
||||
|
||||
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
|
||||
.colorAttachments = {colorAttachment},
|
||||
.depthAttachment = depthAttachment,
|
||||
};
|
||||
colorBuffer = graphics->createTexture2D(colorBufferInfo);
|
||||
renderTarget = Gfx::RenderTargetAttachment(colorBuffer, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
||||
renderTarget.clear.color = {{0.0f, 0.0f, 0.0f, 1.0f}};
|
||||
resources->registerRenderPassOutput("UIPASS_COLOR", renderTarget);
|
||||
}
|
||||
renderPass = graphics->createRenderPass(std::move(layout), {}, viewport, "TextPass");
|
||||
|
||||
void UIPass::createRenderPass() {
|
||||
ShaderCompilationInfo createInfo = {
|
||||
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
||||
.name = "TextVertex",
|
||||
.modules = {"TextPass"},
|
||||
.entryPoints = {{"vertexMain", "TextPass"}, {"fragmentMain", "TextPass"}},
|
||||
.rootSignature = textPipelineLayout,
|
||||
});
|
||||
textPipelineLayout->create();
|
||||
textVertexShader = graphics->createVertexShader({0});
|
||||
textFragmentShader = graphics->createFragmentShader({1});
|
||||
|
||||
glyphSampler = graphics->createSampler({
|
||||
.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,
|
||||
});
|
||||
|
||||
Gfx::LegacyPipelineCreateInfo pipelineInfo = {
|
||||
.topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
|
||||
.vertexShader = textVertexShader,
|
||||
.fragmentShader = textFragmentShader,
|
||||
.renderPass = renderPass,
|
||||
.pipelineLayout = textPipelineLayout,
|
||||
.rasterizationState =
|
||||
{
|
||||
.cullMode = Gfx::SE_CULL_MODE_NONE,
|
||||
},
|
||||
.colorBlend =
|
||||
{
|
||||
|
||||
.attachmentCount = 1,
|
||||
.blendAttachments = {{
|
||||
.blendEnable = true,
|
||||
.srcColorBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA,
|
||||
.dstColorBlendFactor = Gfx::SE_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
|
||||
.srcAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
|
||||
.dstAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_ZERO,
|
||||
.alphaBlendOp = Gfx::SE_BLEND_OP_ADD,
|
||||
.colorWriteMask = Gfx::SE_COLOR_COMPONENT_R_BIT | Gfx::SE_COLOR_COMPONENT_G_BIT | Gfx::SE_COLOR_COMPONENT_B_BIT |
|
||||
Gfx::SE_COLOR_COMPONENT_A_BIT,
|
||||
}},
|
||||
},
|
||||
};
|
||||
|
||||
textPipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
||||
.name = "UIVertex",
|
||||
.modules = {"UIPass"},
|
||||
.entryPoints =
|
||||
{
|
||||
{"vertexMain", "UIPass"},
|
||||
{"fragmentMain", "UIFragment"},
|
||||
},
|
||||
};
|
||||
graphics->beginShaderCompilation(createInfo);
|
||||
vertexShader = graphics->createVertexShader({0});
|
||||
fragmentShader = graphics->createFragmentShader({1});
|
||||
|
||||
descriptorLayout = graphics->createDescriptorLayout("pParams");
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 0,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
.uniformLength = sizeof(Matrix4),
|
||||
.entryPoints = {{"vertexMain", "UIPass"}, {"fragmentMain", "UIPass"}},
|
||||
.rootSignature = uiPipelineLayout,
|
||||
});
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 1,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER,
|
||||
});
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 2,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
.uniformLength = sizeof(uint32)
|
||||
});
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 3,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
.textureType = Gfx::SE_IMAGE_VIEW_TYPE_2D_ARRAY,
|
||||
.descriptorCount = 256,
|
||||
.bindingFlags = Gfx::SE_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT | Gfx::SE_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT,
|
||||
});
|
||||
descriptorLayout->create();
|
||||
|
||||
Matrix4 projectionMatrix = glm::ortho(0, 1, 1, 0);
|
||||
|
||||
Gfx::OUniformBuffer uniformBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(Matrix4),
|
||||
.data = (uint8*)&projectionMatrix,
|
||||
},
|
||||
});
|
||||
Gfx::OSampler backgroundSampler = graphics->createSampler({});
|
||||
|
||||
numTexturesBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(uint32),
|
||||
.data = nullptr,
|
||||
},
|
||||
});
|
||||
|
||||
descriptorSet = descriptorLayout->allocateDescriptorSet();
|
||||
descriptorSet->updateBuffer(0, 0, uniformBuffer);
|
||||
descriptorSet->updateSampler(1, 0, backgroundSampler);
|
||||
descriptorSet->writeChanges();
|
||||
|
||||
pipelineLayout = graphics->createPipelineLayout();
|
||||
pipelineLayout->addDescriptorLayout(descriptorLayout);
|
||||
pipelineLayout->create();
|
||||
|
||||
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{.colorAttachments = {renderTarget}, .depthAttachment = depthAttachment};
|
||||
renderPass = graphics->createRenderPass(std::move(layout), {}, viewport);
|
||||
|
||||
Gfx::LegacyPipelineCreateInfo pipelineInfo;
|
||||
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(std::move(pipelineInfo));
|
||||
uiVertexShader = graphics->createVertexShader({0});
|
||||
uiFragmentShader = graphics->createFragmentShader({1});
|
||||
}
|
||||
|
||||
@@ -1,15 +1,22 @@
|
||||
#pragma once
|
||||
#include "Graphics/Shader.h"
|
||||
#include "RenderPass.h"
|
||||
#include "UI/RenderHierarchy.h"
|
||||
|
||||
#include "Asset/FontAsset.h"
|
||||
#include "UI/System.h"
|
||||
|
||||
namespace Seele {
|
||||
DECLARE_NAME_REF(Gfx, Texture2D)
|
||||
DECLARE_NAME_REF(Gfx, RenderTargetAttachment)
|
||||
struct TextRender {
|
||||
std::string text;
|
||||
PFontAsset font;
|
||||
uint32 fontSize;
|
||||
Vector4 textColor;
|
||||
Vector2 position;
|
||||
};
|
||||
class UIPass : public RenderPass {
|
||||
public:
|
||||
UIPass(Gfx::PGraphics graphics, PScene scene);
|
||||
UIPass(Gfx::PGraphics graphics, UI::PSystem system);
|
||||
UIPass(UIPass&&) = default;
|
||||
UIPass& operator=(UIPass&&) = default;
|
||||
virtual ~UIPass();
|
||||
@@ -20,23 +27,54 @@ class UIPass : public RenderPass {
|
||||
virtual void createRenderPass() override;
|
||||
|
||||
private:
|
||||
Gfx::RenderTargetAttachment renderTarget;
|
||||
Gfx::OTexture2D colorBuffer;
|
||||
struct GlyphData {
|
||||
Vector2 bearing;
|
||||
Vector2 size;
|
||||
uint32 advance;
|
||||
};
|
||||
struct GlyphInstanceData {
|
||||
float x;
|
||||
float y;
|
||||
float width;
|
||||
float height;
|
||||
uint32 glyphIndex;
|
||||
};
|
||||
struct TextData {
|
||||
Vector4 textColor;
|
||||
float scale;
|
||||
};
|
||||
|
||||
struct TextResources {
|
||||
Gfx::PShaderBuffer instanceBuffer;
|
||||
Gfx::PDescriptorSet textureArraySet;
|
||||
TextData textData;
|
||||
};
|
||||
Map<PFontAsset, Array<TextResources>> textResources;
|
||||
|
||||
Gfx::RenderTargetAttachment colorAttachment;
|
||||
Gfx::RenderTargetAttachment depthAttachment;
|
||||
Gfx::OTexture2D depthBuffer;
|
||||
|
||||
Gfx::ODescriptorLayout descriptorLayout;
|
||||
Gfx::PDescriptorSet descriptorSet;
|
||||
Gfx::ODescriptorLayout textDescriptorLayout;
|
||||
Gfx::PDescriptorSet textDescriptorSet;
|
||||
|
||||
Gfx::OUniformBuffer numTexturesBuffer;
|
||||
Gfx::OVertexBuffer elementBuffer;
|
||||
Gfx::OVertexShader textVertexShader;
|
||||
Gfx::OFragmentShader textFragmentShader;
|
||||
Gfx::OPipelineLayout textPipelineLayout;
|
||||
Gfx::PGraphicsPipeline textPipeline;
|
||||
|
||||
Gfx::OVertexShader vertexShader;
|
||||
Gfx::OFragmentShader fragmentShader;
|
||||
Gfx::PGraphicsPipeline pipeline;
|
||||
Gfx::OPipelineLayout pipelineLayout;
|
||||
Gfx::ODescriptorLayout uiDescriptorLayout;
|
||||
Gfx::PDescriptorSet uiDescriptorSet;
|
||||
|
||||
Array<UI::RenderElementStyle> renderElements;
|
||||
Gfx::OVertexShader uiVertexShader;
|
||||
Gfx::OFragmentShader uiFragmentShader;
|
||||
Gfx::OPipelineLayout uiPipelineLayout;
|
||||
Gfx::PGraphicsPipeline uiPipeline;
|
||||
|
||||
Array<TextRender> texts;
|
||||
Array<GlyphInstanceData> glyphs;
|
||||
Gfx::OShaderBuffer glyphInstanceBuffer;
|
||||
Gfx::OSampler glyphSampler;
|
||||
Array<Gfx::PTexture2D> usedTextures;
|
||||
};
|
||||
DEFINE_REF(UIPass);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
VisibilityPass::VisibilityPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) {}
|
||||
VisibilityPass::VisibilityPass(Gfx::PGraphics graphics) : RenderPass(graphics) {}
|
||||
|
||||
VisibilityPass::~VisibilityPass() {}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
namespace Seele {
|
||||
class VisibilityPass : public RenderPass {
|
||||
public:
|
||||
VisibilityPass(Gfx::PGraphics graphics, PScene scene);
|
||||
VisibilityPass(Gfx::PGraphics graphics);
|
||||
VisibilityPass(VisibilityPass&&) = default;
|
||||
VisibilityPass& operator=(VisibilityPass&&) = default;
|
||||
virtual ~VisibilityPass();
|
||||
|
||||
@@ -142,6 +142,7 @@ Graphics::~Graphics() {
|
||||
|
||||
void Graphics::init(GraphicsInitializer initInfo) {
|
||||
initInstance(initInfo);
|
||||
//setupDebugCallback();
|
||||
pickPhysicalDevice();
|
||||
createDevice(initInfo);
|
||||
VmaAllocatorCreateInfo createInfo = {
|
||||
@@ -437,6 +438,8 @@ Gfx::OTopLevelAS Graphics::createTopLevelAccelerationStructure(const Gfx::TopLev
|
||||
}
|
||||
|
||||
void Graphics::buildBottomLevelAccelerationStructures(Array<Gfx::PBottomLevelAS> data) {
|
||||
if (!supportRayTracing())
|
||||
return;
|
||||
Gfx::PShaderBuffer verticesBuffer = StaticMeshVertexData::getInstance()->getPositionBuffer();
|
||||
Gfx::PIndexBuffer indexBuffer = StaticMeshVertexData::getInstance()->getIndexBuffer();
|
||||
|
||||
@@ -790,14 +793,12 @@ void Graphics::pickPhysicalDevice() {
|
||||
};
|
||||
meshShaderFeatures = {
|
||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT,
|
||||
.pNext = &accelerationFeatures,
|
||||
.taskShader = true,
|
||||
.meshShader = true,
|
||||
.meshShaderQueries = true,
|
||||
};
|
||||
features12 = {
|
||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES,
|
||||
.pNext = &meshShaderFeatures,
|
||||
.storageBuffer8BitAccess = true,
|
||||
.uniformAndStorageBuffer8BitAccess = true,
|
||||
.shaderBufferInt64Atomics = true,
|
||||
@@ -836,17 +837,36 @@ void Graphics::pickPhysicalDevice() {
|
||||
.inheritedQueries = true,
|
||||
},
|
||||
};
|
||||
if (Gfx::useMeshShading) {
|
||||
uint32 count = 0;
|
||||
vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &count, nullptr);
|
||||
Array<VkExtensionProperties> extensionProps(count);
|
||||
vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &count, extensionProps.data());
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
bool rayTracingPipelineSupport = false;
|
||||
bool accelerationStructureSupport = false;
|
||||
uint32 count = 0;
|
||||
vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &count, nullptr);
|
||||
Array<VkExtensionProperties> extensionProps(count);
|
||||
vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &count, extensionProps.data());
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
if (Gfx::useMeshShading) {
|
||||
if (std::strcmp(VK_EXT_MESH_SHADER_EXTENSION_NAME, extensionProps[i].extensionName) == 0) {
|
||||
meshShadingEnabled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (std::strcmp(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, extensionProps[i].extensionName) == 0) {
|
||||
rayTracingPipelineSupport = true;
|
||||
}
|
||||
if (std::strcmp(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, extensionProps[i].extensionName) == 0) {
|
||||
accelerationStructureSupport = true;
|
||||
}
|
||||
}
|
||||
rayTracingEnabled = rayTracingPipelineSupport && accelerationStructureSupport;
|
||||
if (meshShadingEnabled) {
|
||||
features12.pNext = &meshShaderFeatures;
|
||||
}
|
||||
if (rayTracingEnabled) {
|
||||
if (meshShadingEnabled) {
|
||||
meshShaderFeatures.pNext = &accelerationFeatures;
|
||||
} else {
|
||||
features12.pNext = &accelerationFeatures;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -920,12 +940,14 @@ void Graphics::createDevice(GraphicsInitializer initializer) {
|
||||
if (supportMeshShading()) {
|
||||
initializer.deviceExtensions.add(VK_EXT_MESH_SHADER_EXTENSION_NAME);
|
||||
}
|
||||
if (supportRayTracing()) {
|
||||
initializer.deviceExtensions.add(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME);
|
||||
initializer.deviceExtensions.add(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME);
|
||||
initializer.deviceExtensions.add(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME);
|
||||
}
|
||||
#ifdef __APPLE__
|
||||
initializer.deviceExtensions.add("VK_KHR_portability_subset");
|
||||
#endif
|
||||
initializer.deviceExtensions.add(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME);
|
||||
initializer.deviceExtensions.add(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME);
|
||||
initializer.deviceExtensions.add(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME);
|
||||
VkDeviceCreateInfo deviceInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
|
||||
.pNext = &features,
|
||||
@@ -963,15 +985,17 @@ void Graphics::createDevice(GraphicsInitializer initializer) {
|
||||
cmdBeginDebugUtilsLabelEXT = (PFN_vkCmdBeginDebugUtilsLabelEXT)vkGetInstanceProcAddr(instance, "vkCmdBeginDebugUtilsLabelEXT");
|
||||
cmdEndDebugUtilsLabelEXT = (PFN_vkCmdEndDebugUtilsLabelEXT)vkGetInstanceProcAddr(instance, "vkCmdEndDebugUtilsLabelEXT");
|
||||
|
||||
createAccelerationStructure = (PFN_vkCreateAccelerationStructureKHR)vkGetDeviceProcAddr(handle, "vkCreateAccelerationStructureKHR");
|
||||
cmdBuildAccelerationStructures =
|
||||
(PFN_vkCmdBuildAccelerationStructuresKHR)vkGetDeviceProcAddr(handle, "vkCmdBuildAccelerationStructuresKHR");
|
||||
getAccelerationStructureBuildSize =
|
||||
(PFN_vkGetAccelerationStructureBuildSizesKHR)vkGetDeviceProcAddr(handle, "vkGetAccelerationStructureBuildSizesKHR");
|
||||
createRayTracingPipelines = (PFN_vkCreateRayTracingPipelinesKHR)vkGetDeviceProcAddr(handle, "vkCreateRayTracingPipelinesKHR");
|
||||
getRayTracingShaderGroupHandles =
|
||||
(PFN_vkGetRayTracingShaderGroupHandlesKHR)vkGetDeviceProcAddr(handle, "vkGetRayTracingShaderGroupHandlesKHR");
|
||||
cmdTraceRays = (PFN_vkCmdTraceRaysKHR)vkGetDeviceProcAddr(handle, "vkCmdTraceRaysKHR");
|
||||
getAccelerationStructureDeviceAddress =
|
||||
(PFN_vkGetAccelerationStructureDeviceAddressKHR)vkGetDeviceProcAddr(handle, "vkGetAccelerationStructureDeviceAddressKHR");
|
||||
if (rayTracingEnabled) {
|
||||
createAccelerationStructure = (PFN_vkCreateAccelerationStructureKHR)vkGetDeviceProcAddr(handle, "vkCreateAccelerationStructureKHR");
|
||||
cmdBuildAccelerationStructures =
|
||||
(PFN_vkCmdBuildAccelerationStructuresKHR)vkGetDeviceProcAddr(handle, "vkCmdBuildAccelerationStructuresKHR");
|
||||
getAccelerationStructureBuildSize =
|
||||
(PFN_vkGetAccelerationStructureBuildSizesKHR)vkGetDeviceProcAddr(handle, "vkGetAccelerationStructureBuildSizesKHR");
|
||||
createRayTracingPipelines = (PFN_vkCreateRayTracingPipelinesKHR)vkGetDeviceProcAddr(handle, "vkCreateRayTracingPipelinesKHR");
|
||||
getRayTracingShaderGroupHandles =
|
||||
(PFN_vkGetRayTracingShaderGroupHandlesKHR)vkGetDeviceProcAddr(handle, "vkGetRayTracingShaderGroupHandlesKHR");
|
||||
cmdTraceRays = (PFN_vkCmdTraceRaysKHR)vkGetDeviceProcAddr(handle, "vkCmdTraceRaysKHR");
|
||||
getAccelerationStructureDeviceAddress =
|
||||
(PFN_vkGetAccelerationStructureDeviceAddressKHR)vkGetDeviceProcAddr(handle, "vkGetAccelerationStructureDeviceAddressKHR");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,10 +57,9 @@ void glfwFramebufferResizeCallback(GLFWwindow* handle, int width, int height) {
|
||||
|
||||
Window::Window(PGraphics graphics, const WindowCreateInfo& createInfo)
|
||||
: graphics(graphics), preferences(createInfo), instance(graphics->getInstance()), swapchain(VK_NULL_HANDLE) {
|
||||
float xscale, yscale;
|
||||
glfwGetMonitorContentScale(glfwGetPrimaryMonitor(), &xscale, &yscale);
|
||||
glfwGetMonitorContentScale(glfwGetPrimaryMonitor(), &contentScaleX, &contentScaleY);
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
GLFWwindow* handle = glfwCreateWindow(createInfo.width / xscale, createInfo.height / yscale, createInfo.title, nullptr, nullptr);
|
||||
GLFWwindow* handle = glfwCreateWindow(createInfo.width / contentScaleX, createInfo.height / contentScaleY, createInfo.title, nullptr, nullptr);
|
||||
windowHandle = handle;
|
||||
glfwSetWindowUserPointer(handle, this);
|
||||
|
||||
|
||||
@@ -30,6 +30,6 @@ Matrix4 Viewport::getProjectionMatrix() const {
|
||||
//);
|
||||
return glm::perspective(fieldOfView, sizeX / static_cast<float>(sizeY), 0.1f, 1000.0f);
|
||||
} else {
|
||||
return glm::ortho(0.0f, (float)sizeX, (float)sizeY, 0.0f);
|
||||
return glm::ortho(0.0f, (float)sizeX, 0.0f, (float)sizeY);
|
||||
}
|
||||
}
|
||||
@@ -24,12 +24,16 @@ class Window {
|
||||
constexpr SeFormat getSwapchainFormat() const { return framebufferFormat; }
|
||||
constexpr uint32 getFramebufferWidth() const { return framebufferWidth; }
|
||||
constexpr uint32 getFramebufferHeight() const { return framebufferHeight; }
|
||||
constexpr float getContentScaleX() const { return contentScaleX; }
|
||||
constexpr float getContentScaleY() const { return contentScaleY; }
|
||||
constexpr bool isPaused() const { return paused; }
|
||||
|
||||
protected:
|
||||
SeFormat framebufferFormat;
|
||||
uint32 framebufferWidth;
|
||||
uint32 framebufferHeight;
|
||||
float contentScaleX;
|
||||
float contentScaleY;
|
||||
bool paused = false;
|
||||
};
|
||||
DEFINE_REF(Window)
|
||||
@@ -45,6 +49,8 @@ class Viewport {
|
||||
constexpr uint32 getHeight() const { return sizeY; }
|
||||
constexpr uint32 getOffsetX() const { return offsetX; }
|
||||
constexpr uint32 getOffsetY() const { return offsetY; }
|
||||
constexpr float getContentScaleX() const { return owner->getContentScaleX(); }
|
||||
constexpr float getContentScaleY() const { return owner->getContentScaleY(); }
|
||||
constexpr Gfx::SeSampleCountFlags getSamples() const { return samples; }
|
||||
Matrix4 getProjectionMatrix() const;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user