framegraph 资源优化 & 支持imgui::image
This commit is contained in:
parent
fef024d407
commit
44bf81dcfe
14
engine/modules/engine/render/impl/editor_system_impl.inl
Normal file
14
engine/modules/engine/render/impl/editor_system_impl.inl
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#include "render/editor_system.h"
|
||||||
|
namespace api {
|
||||||
|
SINGLETON_DEFINE(EditorSystem)
|
||||||
|
EditorSystem::EditorSystem()
|
||||||
|
{
|
||||||
|
SINGLETON_PTR();
|
||||||
|
}
|
||||||
|
ImTextureID EditorSystem::AddTexture(FrameGraph& graph, TextureDesc& desc, TextureSampler key)
|
||||||
|
{
|
||||||
|
ImageViewPtr imageview = graph.ResolveTextureView(desc);
|
||||||
|
SamplerPtr sampler = graph.ResolveTextureSampler(key);
|
||||||
|
return AddTexture(imageview, sampler, desc.state);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,15 +1,5 @@
|
|||||||
#include "render/renderapi.h"
|
#include "render/renderapi.h"
|
||||||
#include "render/module.h"
|
#include "render/module.h"
|
||||||
#ifdef WITH_EDITOR
|
|
||||||
#include "render/editor_system.h"
|
|
||||||
namespace api {
|
|
||||||
SINGLETON_DEFINE(EditorSystem)
|
|
||||||
EditorSystem::EditorSystem()
|
|
||||||
{
|
|
||||||
SINGLETON_PTR();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
namespace api {
|
namespace api {
|
||||||
SINGLETON_DEFINE(RenderAPI)
|
SINGLETON_DEFINE(RenderAPI)
|
||||||
IMPLEMENT_STATIC_MODULE(RENDER_API, RenderModule, render);
|
IMPLEMENT_STATIC_MODULE(RENDER_API, RenderModule, render);
|
||||||
|
|||||||
@ -4,8 +4,14 @@
|
|||||||
#include "module/module_manager.h"
|
#include "module/module_manager.h"
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
namespace api {
|
namespace api {
|
||||||
class RenderEditorContext {
|
class EditorSystem;
|
||||||
|
struct RenderEditorContext {
|
||||||
|
EditorSystem* editor;
|
||||||
|
uint32_t frame;
|
||||||
|
uint32_t frameCount;
|
||||||
|
EditorSystem* operator->() {
|
||||||
|
return editor;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
class EditorPanel {
|
class EditorPanel {
|
||||||
public:
|
public:
|
||||||
@ -40,7 +46,8 @@ namespace api {
|
|||||||
mWindows.push_back(ptr);
|
mWindows.push_back(ptr);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
virtual ImTextureID AddTexture(const TextureDesc& desc) = 0;
|
ImTextureID AddTexture(FrameGraph& graph, TextureDesc& desc, TextureSampler sampler);
|
||||||
|
virtual ImTextureID AddTexture(ImageViewPtr imageview, SamplerPtr sampler, ResourceState state) = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif // WITH_EDITOR
|
#endif // WITH_EDITOR
|
||||||
@ -6,8 +6,9 @@ namespace api {
|
|||||||
class FrameGraph
|
class FrameGraph
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TextureDesc mSurface{};
|
uint32_t mSurfaceID{0};
|
||||||
table<Tag, TextureDesc> mTextureTagMap;
|
table<TextureSampler, void*> mTextureSamplerPool;
|
||||||
|
table<Tag, uint32_t> mTextureTagMap;
|
||||||
table<TextureKey, uint32_t> mTextureKeyMap;
|
table<TextureKey, uint32_t> mTextureKeyMap;
|
||||||
std::vector<TextureDesc> mTexturePool;
|
std::vector<TextureDesc> mTexturePool;
|
||||||
table<TextureViewKey, ImageViewPtr> mTextureViewPool;
|
table<TextureViewKey, ImageViewPtr> mTextureViewPool;
|
||||||
@ -17,8 +18,9 @@ namespace api {
|
|||||||
inline static Name NameSurface{ "surface" };
|
inline static Name NameSurface{ "surface" };
|
||||||
#ifdef WITH_EDITOR
|
#ifdef WITH_EDITOR
|
||||||
inline static Name NameEditorSurface{ "editor_surface" };
|
inline static Name NameEditorSurface{ "editor_surface" };
|
||||||
TextureDesc mEditorSurface{};
|
|
||||||
bool mIsRenderEditorSurface{false};
|
bool mIsRenderEditorSurface{false};
|
||||||
|
uint32_t mEditorSurfaceID{ 0 };
|
||||||
|
TextureDesc& GetEditorSurface() { return ResolveTexture(mEditorSurfaceID); }
|
||||||
#endif //
|
#endif //
|
||||||
public:
|
public:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@ -26,23 +28,27 @@ namespace api {
|
|||||||
FrameGraphNodePtr AddRenderPass(const RenderPassSetupFunction& setup, const RenderPassNodeExecuteFn& executor);
|
FrameGraphNodePtr AddRenderPass(const RenderPassSetupFunction& setup, const RenderPassNodeExecuteFn& executor);
|
||||||
RenderPassBuilder CreateRenderPassBuild();
|
RenderPassBuilder CreateRenderPassBuild();
|
||||||
void InitSurface(TextureDesc* surfaces, uint32_t frames);
|
void InitSurface(TextureDesc* surfaces, uint32_t frames);
|
||||||
void Input(const TextureDesc& surfaces) { mSurface = surfaces; };
|
void Input(const TextureDesc& surfaces) { mSurfaceID = surfaces.id; };
|
||||||
void Setup();
|
void Setup();
|
||||||
void Compile();
|
void Compile();
|
||||||
void Execute(FRenderView& view);
|
void Execute(FRenderView& view);
|
||||||
void Clear();
|
void Clear();
|
||||||
void CullGraph();
|
void CullGraph();
|
||||||
void FillGraph();
|
void FillGraph();
|
||||||
|
TextureDesc& GetSurface() { return ResolveTexture(mSurfaceID); }
|
||||||
|
TextureDesc& GetRenderSurface();
|
||||||
void TransitionState(TextureDesc& desc, ResourceState state);
|
void TransitionState(TextureDesc& desc, ResourceState state);
|
||||||
bool ResolveState(TextureDesc& desc, ResourceState& srcstart, ResourceState& dststate);
|
bool ResolveState(TextureDesc& desc, ResourceState& srcstart, ResourceState& dststate);
|
||||||
bool ResolveState(AttachmentDesc& desc, ResourceState& srcstart, ResourceState& dststate);
|
bool ResolveState(AttachmentDesc& desc, ResourceState& srcstart, ResourceState& dststate);
|
||||||
bool ResolveState(BufferDesc& desc, ResourceState& srcstart, ResourceState& dststate);
|
bool ResolveState(BufferDesc& desc, ResourceState& srcstart, ResourceState& dststate);
|
||||||
TextureDesc& ResolveTexture(TextureDesc& desc);
|
TextureDesc& ResolveTexture(uint32_t id);
|
||||||
TextureDesc ResourceTexture(Name name, int num);
|
TextureDesc ResourceTexture(Name name, int num);
|
||||||
ImageViewPtr ResolveTextureView(TextureDesc& desc);
|
ImageViewPtr ResolveTextureView(TextureDesc& desc);
|
||||||
ImageViewPtr ResolveTextureView(TextureViewKey key);
|
ImageViewPtr ResolveTextureView(TextureViewKey key);
|
||||||
|
void* ResolveTextureSampler(TextureSampler sampler);
|
||||||
void ResourceTexture(TextureDesc& desc);
|
void ResourceTexture(TextureDesc& desc);
|
||||||
void SetResourceTexture(TextureDesc texture, Name name, int num = 0);
|
void SetResourceTexture(TextureDesc texture, Name name, int num = 0);
|
||||||
|
uint32_t GetTextureID(Name name, int num);
|
||||||
public:
|
public:
|
||||||
void ExecutePresentPass(FRenderView& view);
|
void ExecutePresentPass(FRenderView& view);
|
||||||
void ExecuteRenderPass(RenderPassNode* node, FRenderView& view);
|
void ExecuteRenderPass(RenderPassNode* node, FRenderView& view);
|
||||||
|
|||||||
@ -11,6 +11,8 @@ namespace api {
|
|||||||
: graph(*graph) , node(node) {};
|
: graph(*graph) , node(node) {};
|
||||||
RenderPassBuilder& Name(pmr::Name name);
|
RenderPassBuilder& Name(pmr::Name name);
|
||||||
RenderPassBuilder& Type(RenderPassNodeType type,RenderPassNodeFlag flag = RenderPassNodeFlag::None);
|
RenderPassBuilder& Type(RenderPassNodeType type,RenderPassNodeFlag flag = RenderPassNodeFlag::None);
|
||||||
|
RenderPassBuilder& Read(TextureDesc desc, ResourceState state, pmr::Name name = {});
|
||||||
RenderPassBuilder& Write(AttachmentDesc desc, ResourceState state, pmr::Name name = {});
|
RenderPassBuilder& Write(AttachmentDesc desc, ResourceState state, pmr::Name name = {});
|
||||||
|
RenderPassBuilder& Dependency(RenderPassNode* rely) { node->dependencies.push_back(rely); return *this;}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -40,9 +40,8 @@ namespace api {
|
|||||||
using Resource = std::variant<TextureDesc, BufferDesc, AttachmentDesc>;
|
using Resource = std::variant<TextureDesc, BufferDesc, AttachmentDesc>;
|
||||||
Name name;
|
Name name;
|
||||||
Resource res;
|
Resource res;
|
||||||
RenderPassNode* node;
|
|
||||||
FrameResource() noexcept = default;
|
FrameResource() noexcept = default;
|
||||||
FrameResource(Name name,const Resource& res, RenderPassNode* node) : name(name), res(res), node(node){};
|
FrameResource(Name name,const Resource& res) : name(name), res(res){};
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T& CastTo() {
|
T& CastTo() {
|
||||||
return std::get<T>(res);
|
return std::get<T>(res);
|
||||||
@ -56,8 +55,8 @@ namespace api {
|
|||||||
bool IsBuffer() const {
|
bool IsBuffer() const {
|
||||||
return std::holds_alternative<BufferDesc>(res);
|
return std::holds_alternative<BufferDesc>(res);
|
||||||
}
|
}
|
||||||
static FrameResource* Make(Name name, const Resource& res, RenderPassNode* node) {
|
static FrameResource* Make(Name name, const Resource& res) {
|
||||||
return new(FramePool()) FrameResource(name, res, node);
|
return new(FramePool()) FrameResource(name, res);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
using FrameGraphEdgePtr = FrameResource*;
|
using FrameGraphEdgePtr = FrameResource*;
|
||||||
|
|||||||
@ -35,7 +35,7 @@ namespace api {
|
|||||||
virtual void CreateBuffer(BufferDesc& desc) = 0;
|
virtual void CreateBuffer(BufferDesc& desc) = 0;
|
||||||
virtual void CreateTexture(TextureDesc& desc) = 0;
|
virtual void CreateTexture(TextureDesc& desc) = 0;
|
||||||
virtual ImageViewPtr CreateTextureView(TextureViewKey desc) = 0;
|
virtual ImageViewPtr CreateTextureView(TextureViewKey desc) = 0;
|
||||||
|
virtual SamplerPtr CreateTextureSampler(TextureSampler sampler) = 0;
|
||||||
virtual void BeginFrame() = 0;
|
virtual void BeginFrame() = 0;
|
||||||
virtual void EndFrame() = 0;
|
virtual void EndFrame() = 0;
|
||||||
virtual void RenderView(FRenderView& view);
|
virtual void RenderView(FRenderView& view);
|
||||||
|
|||||||
@ -119,6 +119,91 @@ namespace api {
|
|||||||
VERTEX = 0x1,
|
VERTEX = 0x1,
|
||||||
FRAGMENT = 0x2,
|
FRAGMENT = 0x2,
|
||||||
};
|
};
|
||||||
|
//! Sampler Wrap mode
|
||||||
|
enum class SamplerWrapMode : uint8_t {
|
||||||
|
CLAMP_TO_EDGE, //!< clamp-to-edge. The edge of the texture extends to infinity.
|
||||||
|
REPEAT, //!< repeat. The texture infinitely repeats in the wrap direction.
|
||||||
|
MIRRORED_REPEAT, //!< mirrored-repeat. The texture infinitely repeats and mirrors in the wrap direction.
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Sampler minification filter
|
||||||
|
enum class SamplerMinFilter : uint8_t {
|
||||||
|
// don't change the enums values
|
||||||
|
NEAREST = 0, //!< No filtering. Nearest neighbor is used.
|
||||||
|
LINEAR = 1, //!< Box filtering. Weighted average of 4 neighbors is used.
|
||||||
|
NEAREST_MIPMAP_NEAREST = 2, //!< Mip-mapping is activated. But no filtering occurs.
|
||||||
|
LINEAR_MIPMAP_NEAREST = 3, //!< Box filtering within a mip-map level.
|
||||||
|
NEAREST_MIPMAP_LINEAR = 4, //!< Mip-map levels are interpolated, but no other filtering occurs.
|
||||||
|
LINEAR_MIPMAP_LINEAR = 5 //!< Both interpolated Mip-mapping and linear filtering are used.
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Sampler magnification filter
|
||||||
|
enum class SamplerMagFilter : uint8_t {
|
||||||
|
// don't change the enums values
|
||||||
|
NEAREST = 0, //!< No filtering. Nearest neighbor is used.
|
||||||
|
LINEAR = 1, //!< Box filtering. Weighted average of 4 neighbors is used.
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Sampler compare mode
|
||||||
|
enum class SamplerCompareMode : uint8_t {
|
||||||
|
// don't change the enums values
|
||||||
|
NONE = 0,
|
||||||
|
COMPARE_TO_TEXTURE = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
//! comparison function for the depth / stencil sampler
|
||||||
|
enum class SamplerCompareFunc : uint8_t {
|
||||||
|
// don't change the enums values
|
||||||
|
LE = 0, //!< Less or equal
|
||||||
|
GE, //!< Greater or equal
|
||||||
|
L, //!< Strictly less than
|
||||||
|
G, //!< Strictly greater than
|
||||||
|
E, //!< Equal
|
||||||
|
NE, //!< Not equal
|
||||||
|
A, //!< Always. Depth / stencil testing is deactivated.
|
||||||
|
N //!< Never. The depth / stencil test always fails.
|
||||||
|
};
|
||||||
|
using SamplerPtr = void*;
|
||||||
|
//! Sampler parameters
|
||||||
|
struct TextureSampler { // NOLINT
|
||||||
|
SamplerMagFilter filterMag : 1; //!< magnification filter (NEAREST)
|
||||||
|
SamplerMinFilter filterMin : 3; //!< minification filter (NEAREST)
|
||||||
|
SamplerWrapMode wrapS : 2; //!< s-coordinate wrap mode (CLAMP_TO_EDGE)
|
||||||
|
SamplerWrapMode wrapT : 2; //!< t-coordinate wrap mode (CLAMP_TO_EDGE)
|
||||||
|
|
||||||
|
SamplerWrapMode wrapR : 2; //!< r-coordinate wrap mode (CLAMP_TO_EDGE)
|
||||||
|
uint8_t anisotropyLog2 : 3; //!< anisotropy level (0)
|
||||||
|
SamplerCompareMode compareMode : 1; //!< sampler compare mode (NONE)
|
||||||
|
uint8_t padding0 : 2; //!< reserved. must be 0.
|
||||||
|
|
||||||
|
SamplerCompareFunc compareFunc : 3; //!< sampler comparison function (LE)
|
||||||
|
uint8_t padding1 : 5; //!< reserved. must be 0.
|
||||||
|
uint8_t padding2 : 8; //!< reserved. must be 0.
|
||||||
|
struct EqualTo {
|
||||||
|
bool operator()(TextureSampler lhs, TextureSampler rhs) const noexcept {
|
||||||
|
auto* pLhs = reinterpret_cast<uint32_t const*>(reinterpret_cast<char const*>(&lhs));
|
||||||
|
auto* pRhs = reinterpret_cast<uint32_t const*>(reinterpret_cast<char const*>(&rhs));
|
||||||
|
return *pLhs == *pRhs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LessThan {
|
||||||
|
bool operator()(TextureSampler lhs, TextureSampler rhs) const noexcept {
|
||||||
|
auto* pLhs = reinterpret_cast<uint32_t const*>(reinterpret_cast<char const*>(&lhs));
|
||||||
|
auto* pRhs = reinterpret_cast<uint32_t const*>(reinterpret_cast<char const*>(&rhs));
|
||||||
|
return *pLhs == *pRhs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend inline bool operator < (TextureSampler lhs, TextureSampler rhs) noexcept {
|
||||||
|
return TextureSampler::LessThan{}(lhs, rhs);
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
friend inline bool operator== (TextureSampler lhs, TextureSampler rhs) noexcept {
|
||||||
|
return TextureSampler::EqualTo{}(lhs, rhs);
|
||||||
|
}
|
||||||
|
};
|
||||||
struct MaterialResource {
|
struct MaterialResource {
|
||||||
Name name;
|
Name name;
|
||||||
bool isDirty;
|
bool isDirty;
|
||||||
@ -209,6 +294,16 @@ namespace api {
|
|||||||
uint8_t layerCount;
|
uint8_t layerCount;
|
||||||
uint8_t baseMipLevel;
|
uint8_t baseMipLevel;
|
||||||
uint8_t levelCount;
|
uint8_t levelCount;
|
||||||
|
friend inline bool operator==(const TextureViewKey& k1, const TextureViewKey& k2) {
|
||||||
|
if (k1.image != k2.image) return false;
|
||||||
|
if (k1.format != k2.format) return false;
|
||||||
|
if (k1.dimension != k2.dimension) return false;
|
||||||
|
if (k1.baseArrayLayer != k2.baseArrayLayer) return false;
|
||||||
|
if (k1.layerCount != k2.layerCount) return false;
|
||||||
|
if (k1.baseMipLevel != k2.baseMipLevel) return false;
|
||||||
|
if (k1.levelCount != k2.levelCount) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
struct TextureKey {
|
struct TextureKey {
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
@ -220,6 +315,17 @@ namespace api {
|
|||||||
TextureDimension dimension;
|
TextureDimension dimension;
|
||||||
uint8_t mipLevel;
|
uint8_t mipLevel;
|
||||||
uint8_t arraySize;
|
uint8_t arraySize;
|
||||||
|
friend inline bool operator==(const TextureKey& k1, const TextureKey& k2) {
|
||||||
|
if (k1.format != k2.format) return false;
|
||||||
|
if (k1.dimension != k2.dimension) return false;
|
||||||
|
if (k1.width != k2.width) return false;
|
||||||
|
if (k1.height != k2.height) return false;
|
||||||
|
if (k1.arraySize != k2.arraySize) return false;
|
||||||
|
if (k1.mipLevel != k2.mipLevel) return false;
|
||||||
|
if (k1.sampleCount != k2.sampleCount) return false;
|
||||||
|
if (k1.depth != k2.depth) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
struct TextureDesc : TextureKey {
|
struct TextureDesc : TextureKey {
|
||||||
ImagePtr image;
|
ImagePtr image;
|
||||||
@ -303,27 +409,6 @@ namespace api {
|
|||||||
barrier.mTexture = texture;
|
barrier.mTexture = texture;
|
||||||
return barrier;
|
return barrier;
|
||||||
}
|
}
|
||||||
inline bool operator==(const TextureViewKey& k1, const TextureViewKey& k2) {
|
|
||||||
if (k1.image != k2.image) return false;
|
|
||||||
if (k1.format != k2.format) return false;
|
|
||||||
if (k1.dimension != k2.dimension) return false;
|
|
||||||
if (k1.baseArrayLayer != k2.baseArrayLayer) return false;
|
|
||||||
if (k1.layerCount != k2.layerCount) return false;
|
|
||||||
if (k1.baseMipLevel != k2.baseMipLevel) return false;
|
|
||||||
if (k1.levelCount != k2.levelCount) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
inline bool operator==(const TextureKey& k1, const TextureKey& k2) {
|
|
||||||
if (k1.format != k2.format) return false;
|
|
||||||
if (k1.dimension != k2.dimension) return false;
|
|
||||||
if (k1.width != k2.width) return false;
|
|
||||||
if (k1.height != k2.height) return false;
|
|
||||||
if (k1.arraySize != k2.arraySize) return false;
|
|
||||||
if (k1.mipLevel != k2.mipLevel) return false;
|
|
||||||
if (k1.sampleCount != k2.sampleCount) return false;
|
|
||||||
if (k1.depth != k2.depth) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#include "meta/hash.h"
|
#include "meta/hash.h"
|
||||||
namespace std {
|
namespace std {
|
||||||
@ -343,4 +428,12 @@ namespace std {
|
|||||||
return meta::MurmurHashFn(key);
|
return meta::MurmurHashFn(key);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
template<>
|
||||||
|
struct hash<api::TextureSampler>
|
||||||
|
{
|
||||||
|
size_t operator()(const api::TextureSampler& key) const noexcept
|
||||||
|
{
|
||||||
|
return std::hash<int>{}(*(int*)&key);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
@ -17,7 +17,8 @@ namespace api {
|
|||||||
}
|
}
|
||||||
void FrameGraph::InitSurface(TextureDesc* surfaces, uint32_t frames)
|
void FrameGraph::InitSurface(TextureDesc* surfaces, uint32_t frames)
|
||||||
{
|
{
|
||||||
mTexturePool.reserve(frames);
|
mTexturePool.reserve(frames + 1);
|
||||||
|
mTexturePool.push_back(TextureDesc{});
|
||||||
for (uint32_t i = 0; i < frames;i++) {
|
for (uint32_t i = 0; i < frames;i++) {
|
||||||
surfaces[i].id = mTexturePool.size() + 1;
|
surfaces[i].id = mTexturePool.size() + 1;
|
||||||
mTexturePool.push_back(surfaces[i]);
|
mTexturePool.push_back(surfaces[i]);
|
||||||
@ -40,10 +41,8 @@ namespace api {
|
|||||||
void FrameGraph::CullGraph()
|
void FrameGraph::CullGraph()
|
||||||
{
|
{
|
||||||
pmr::vector<RenderPassNode*> outputNodes{FramePool()};
|
pmr::vector<RenderPassNode*> outputNodes{FramePool()};
|
||||||
std::stack<RenderPassNode*> stack;
|
|
||||||
for (auto& node : mNodes) {
|
for (auto& node : mNodes) {
|
||||||
if (node->IsOutput()) {
|
if (node->IsOutput()) {
|
||||||
stack.push(node.node);
|
|
||||||
outputNodes.push_back(node.node);
|
outputNodes.push_back(node.node);
|
||||||
if ((!mLastOutputNode || node->type > mLastOutputNode->type)) {
|
if ((!mLastOutputNode || node->type > mLastOutputNode->type)) {
|
||||||
mLastOutputNode = node.node;
|
mLastOutputNode = node.node;
|
||||||
@ -56,23 +55,6 @@ namespace api {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (!stack.empty()) {
|
|
||||||
RenderPassNode* node = stack.top();
|
|
||||||
stack.pop();
|
|
||||||
if (node->isActive) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
node->isActive = true;
|
|
||||||
for (auto& edge : node->inEdges) {
|
|
||||||
if (edge->node && !edge->node->isActive) {
|
|
||||||
stack.push(edge->node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auto end = std::remove_if(mNodes.begin(), mNodes.end(), [this](FrameGraphNodePtr& node) {
|
|
||||||
return !node->isActive;
|
|
||||||
});
|
|
||||||
mNodes.erase(end, mNodes.end());
|
|
||||||
if (outputNodes.size() > 1) {
|
if (outputNodes.size() > 1) {
|
||||||
std::sort(outputNodes.begin(), outputNodes.end(), [](RenderPassNode* a, RenderPassNode* b) {
|
std::sort(outputNodes.begin(), outputNodes.end(), [](RenderPassNode* a, RenderPassNode* b) {
|
||||||
if (a->type != b->type) {
|
if (a->type != b->type) {
|
||||||
@ -84,20 +66,43 @@ namespace api {
|
|||||||
outputNodes[i]->dependencies.push_back(outputNodes[i - 1]);
|
outputNodes[i]->dependencies.push_back(outputNodes[i - 1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//todo 需要考虑拓扑排序
|
||||||
|
std::stack<RenderPassNode*> stack;
|
||||||
|
stack.push(mLastOutputNode);
|
||||||
|
while (!stack.empty()) {
|
||||||
|
RenderPassNode* node = stack.top();
|
||||||
|
stack.pop();
|
||||||
|
if (node->isActive) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
node->isActive = true;
|
||||||
|
for (auto& rely : node->dependencies) {
|
||||||
|
if (!rely->isActive) {
|
||||||
|
stack.push(rely);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto end = std::remove_if(mNodes.begin(), mNodes.end(), [this](FrameGraphNodePtr& node) {
|
||||||
|
return !node->isActive;
|
||||||
|
});
|
||||||
|
mNodes.erase(end, mNodes.end());
|
||||||
}
|
}
|
||||||
void FrameGraph::FillGraph()
|
void FrameGraph::FillGraph()
|
||||||
{
|
{
|
||||||
std::pmr::unordered_set<RenderPassNode*> seenNodes{FramePool()};
|
std::pmr::unordered_set<RenderPassNode*> seenNodes{FramePool()};
|
||||||
|
pmr::vector<RenderPassNode*> result{ FramePool() };
|
||||||
for (auto& node : mNodes) {
|
for (auto& node : mNodes) {
|
||||||
if (!node->dependencies.empty()) {
|
bool isChange = false;
|
||||||
seenNodes.insert(node->dependencies[0]);
|
for (auto& rely : node->dependencies) {
|
||||||
}
|
bool isInsert = seenNodes.insert(rely).second;
|
||||||
for (auto& edge : node->inEdges) {
|
isChange = isChange || !isInsert;
|
||||||
RenderPassNode* srcNode = edge->node;
|
if (isInsert) {
|
||||||
if (srcNode && seenNodes.insert(srcNode).second) {
|
result.push_back(rely);
|
||||||
node->dependencies.push_back(srcNode);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(isChange)
|
||||||
|
node->dependencies = result;
|
||||||
|
result.clear();
|
||||||
seenNodes.clear();
|
seenNodes.clear();
|
||||||
}
|
}
|
||||||
if (mLastOutputNode) {
|
if (mLastOutputNode) {
|
||||||
@ -105,6 +110,14 @@ namespace api {
|
|||||||
mLastOutputNode->flag |= RenderPassNodeFlag::LastOutput;
|
mLastOutputNode->flag |= RenderPassNodeFlag::LastOutput;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
TextureDesc& FrameGraph::GetRenderSurface()
|
||||||
|
{
|
||||||
|
#ifdef WITH_EDITOR
|
||||||
|
return ResolveTexture(mIsRenderEditorSurface ? mEditorSurfaceID: mSurfaceID);
|
||||||
|
#else
|
||||||
|
return ResolveTexture(mSurfaceID);
|
||||||
|
#endif // WITH_EDITOR
|
||||||
|
}
|
||||||
void FrameGraph::Execute(FRenderView& view)
|
void FrameGraph::Execute(FRenderView& view)
|
||||||
{
|
{
|
||||||
for (auto& node : mNodes) {
|
for (auto& node : mNodes) {
|
||||||
@ -141,13 +154,8 @@ namespace api {
|
|||||||
}
|
}
|
||||||
void FrameGraph::ExecutePresentPass(FRenderView& view)
|
void FrameGraph::ExecutePresentPass(FRenderView& view)
|
||||||
{
|
{
|
||||||
#ifdef WITH_EDITOR
|
TextureDesc& surface = GetRenderSurface();
|
||||||
TextureDesc& surface = ResolveTexture(mIsRenderEditorSurface ? mEditorSurface : mSurface);
|
|
||||||
#else
|
|
||||||
TextureDesc& surface = ResolveTexture(mSurface);
|
|
||||||
#endif // WITH_EDITOR
|
|
||||||
if (surface.state == ResourceState::PRESENT) {
|
if (surface.state == ResourceState::PRESENT) {
|
||||||
surface.state = ResourceState::UNDEFINED;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
TextureBarrier barrier{};
|
TextureBarrier barrier{};
|
||||||
@ -159,7 +167,6 @@ namespace api {
|
|||||||
desc.textureBarriersCount = 1;
|
desc.textureBarriersCount = 1;
|
||||||
desc.pTextureBarriers = &barrier;
|
desc.pTextureBarriers = &barrier;
|
||||||
view.context->ExecuteSurfaceBarriers(desc);
|
view.context->ExecuteSurfaceBarriers(desc);
|
||||||
surface.state = ResourceState::UNDEFINED;
|
|
||||||
}
|
}
|
||||||
void FrameGraph::ExecuteComputePass(RenderPassNode* node, FRenderView& view)
|
void FrameGraph::ExecuteComputePass(RenderPassNode* node, FRenderView& view)
|
||||||
{
|
{
|
||||||
@ -204,32 +211,17 @@ namespace api {
|
|||||||
}
|
}
|
||||||
void FrameGraph::TransitionState(TextureDesc& desc, ResourceState state)
|
void FrameGraph::TransitionState(TextureDesc& desc, ResourceState state)
|
||||||
{
|
{
|
||||||
TextureDesc& texture = ResolveTexture(desc);
|
TextureDesc& texture = ResolveTexture(desc.id);
|
||||||
desc.state = state;
|
desc.state = state;
|
||||||
texture.state = state;
|
texture.state = state;
|
||||||
if (texture.id == mSurface.id) {
|
|
||||||
mSurface.state = state;
|
|
||||||
}
|
|
||||||
#ifdef WITH_EDITOR
|
|
||||||
else if (texture.id == mEditorSurface.id) {
|
|
||||||
mEditorSurface.state = state;
|
|
||||||
}
|
|
||||||
#endif // WITH_EDITOR
|
|
||||||
}
|
}
|
||||||
bool FrameGraph::ResolveState(TextureDesc& desc, ResourceState& srcstart, ResourceState& dststate)
|
bool FrameGraph::ResolveState(TextureDesc& desc, ResourceState& srcstart, ResourceState& dststate)
|
||||||
{
|
{
|
||||||
TextureDesc& texture = ResolveTexture(desc);
|
TextureDesc& texture = ResolveTexture(desc.id);
|
||||||
srcstart = texture.state;
|
srcstart = texture.state;
|
||||||
dststate = desc.state;
|
dststate = desc.state;
|
||||||
texture.state = dststate;
|
texture.state = dststate;
|
||||||
if (texture.id == mSurface.id) {
|
desc.image = texture.image;
|
||||||
mSurface.state = dststate;
|
|
||||||
}
|
|
||||||
#ifdef WITH_EDITOR
|
|
||||||
else if (texture.id == mEditorSurface.id) {
|
|
||||||
mEditorSurface.state = dststate;
|
|
||||||
}
|
|
||||||
#endif // WITH_EDITOR
|
|
||||||
return srcstart == dststate;
|
return srcstart == dststate;
|
||||||
}
|
}
|
||||||
bool FrameGraph::ResolveState(AttachmentDesc& desc, ResourceState& srcstart, ResourceState& dststate)
|
bool FrameGraph::ResolveState(AttachmentDesc& desc, ResourceState& srcstart, ResourceState& dststate)
|
||||||
@ -240,12 +232,12 @@ namespace api {
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
TextureDesc& FrameGraph::ResolveTexture(TextureDesc& desc)
|
TextureDesc& FrameGraph::ResolveTexture(uint32_t id)
|
||||||
{
|
{
|
||||||
if (!desc.id || desc.id > mTexturePool.size()) {
|
if (!id || id > mTexturePool.size()) {
|
||||||
return desc;
|
return mTexturePool[0];//empty
|
||||||
}
|
}
|
||||||
TextureDesc& texture = mTexturePool[desc.id - 1];
|
TextureDesc& texture = mTexturePool[id - 1];
|
||||||
if (!texture.image) {
|
if (!texture.image) {
|
||||||
RenderAPI::Ptr()->CreateTexture(texture);
|
RenderAPI::Ptr()->CreateTexture(texture);
|
||||||
}
|
}
|
||||||
@ -254,7 +246,8 @@ namespace api {
|
|||||||
ImageViewPtr FrameGraph::ResolveTextureView(TextureDesc& desc)
|
ImageViewPtr FrameGraph::ResolveTextureView(TextureDesc& desc)
|
||||||
{
|
{
|
||||||
if (!desc.image) {
|
if (!desc.image) {
|
||||||
desc = ResolveTexture(desc);
|
TextureDesc& texture = ResolveTexture(desc.id);
|
||||||
|
desc.image = texture.image;
|
||||||
}
|
}
|
||||||
return ResolveTextureView(desc.ToTextureView());
|
return ResolveTextureView(desc.ToTextureView());
|
||||||
}
|
}
|
||||||
@ -268,14 +261,22 @@ namespace api {
|
|||||||
mTextureViewPool.emplace(key, view);
|
mTextureViewPool.emplace(key, view);
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
void* FrameGraph::ResolveTextureSampler(TextureSampler sampler)
|
||||||
|
{
|
||||||
|
auto iter = mTextureSamplerPool.find(sampler);
|
||||||
|
if (iter != mTextureSamplerPool.end()) {
|
||||||
|
return iter->second;
|
||||||
|
}
|
||||||
|
return RenderAPI::Ptr()->CreateTextureSampler(sampler);
|
||||||
|
}
|
||||||
TextureDesc FrameGraph::ResourceTexture(Name name, int num)
|
TextureDesc FrameGraph::ResourceTexture(Name name, int num)
|
||||||
{
|
{
|
||||||
Tag tag(name, num);
|
Tag tag(name, num);
|
||||||
auto it = mTextureTagMap.find(tag);
|
auto it = mTextureTagMap.find(tag);
|
||||||
if (it != mTextureTagMap.end()) {
|
if (it != mTextureTagMap.end()) {
|
||||||
return it->second;
|
return ResolveTexture(it->second);
|
||||||
}
|
}
|
||||||
return TextureDesc{};
|
return mTexturePool[0];
|
||||||
}
|
}
|
||||||
void FrameGraph::ResourceTexture(TextureDesc& desc)
|
void FrameGraph::ResourceTexture(TextureDesc& desc)
|
||||||
{
|
{
|
||||||
@ -289,17 +290,28 @@ namespace api {
|
|||||||
mTexturePool.push_back(desc);
|
mTexturePool.push_back(desc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
uint32_t FrameGraph::GetTextureID(Name name, int num)
|
||||||
|
{
|
||||||
|
Tag tag(name, num);
|
||||||
|
auto it = mTextureTagMap.find(tag);
|
||||||
|
if (it != mTextureTagMap.end()) {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
void FrameGraph::SetResourceTexture(TextureDesc desc, Name name, int num)
|
void FrameGraph::SetResourceTexture(TextureDesc desc, Name name, int num)
|
||||||
{
|
{
|
||||||
if (!desc.id) {
|
Tag tag(name, num);
|
||||||
|
auto it = mTextureTagMap.find(tag);
|
||||||
|
if (it != mTextureTagMap.end()) {
|
||||||
|
//todo: destroy texture
|
||||||
|
desc.id = it->second;
|
||||||
|
mTexturePool[desc.id - 1] = desc;
|
||||||
|
}
|
||||||
|
else {
|
||||||
desc.id = mTexturePool.size() + 1;
|
desc.id = mTexturePool.size() + 1;
|
||||||
mTexturePool.push_back(desc);
|
mTexturePool.push_back(desc);
|
||||||
}
|
mTextureTagMap[tag] = desc.id;
|
||||||
Tag tag(name, num);
|
}
|
||||||
//auto it = mTextureTagMap.find(tag);
|
|
||||||
//if (it != mTextureTagMap.end()) {
|
|
||||||
//todo: destroy texture
|
|
||||||
//}
|
|
||||||
mTextureTagMap[tag] = desc;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,10 +13,18 @@ namespace api {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RenderPassBuilder& RenderPassBuilder::Read(TextureDesc desc, ResourceState state, pmr::Name name)
|
||||||
|
{
|
||||||
|
desc.state = state;
|
||||||
|
FrameGraphEdgePtr edge = FrameResource::Make(name, desc);
|
||||||
|
node->inEdges.push_back(edge);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
RenderPassBuilder& RenderPassBuilder::Write(AttachmentDesc desc, ResourceState state, pmr::Name name)
|
RenderPassBuilder& RenderPassBuilder::Write(AttachmentDesc desc, ResourceState state, pmr::Name name)
|
||||||
{
|
{
|
||||||
desc.texture.state = state;
|
desc.texture.state = state;
|
||||||
FrameGraphEdgePtr edge = FrameResource::Make(name, desc, node.node);
|
FrameGraphEdgePtr edge = FrameResource::Make(name, desc);
|
||||||
node->outEdges.push_back(edge);
|
node->outEdges.push_back(edge);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@ namespace api {
|
|||||||
static RscHandle<Mesh> mesh;
|
static RscHandle<Mesh> mesh;
|
||||||
void DemoPass::Setup(FrameGraph& graph, RenderPassBuilder& builder)
|
void DemoPass::Setup(FrameGraph& graph, RenderPassBuilder& builder)
|
||||||
{
|
{
|
||||||
AttachmentDesc surface{ graph.mSurface };
|
AttachmentDesc surface{ graph.GetSurface()};
|
||||||
builder.Name("MiniPass")
|
builder.Name("MiniPass")
|
||||||
.Type(RenderPassNodeType::Scene, RenderPassNodeFlag::Output)
|
.Type(RenderPassNodeType::Scene, RenderPassNodeFlag::Output)
|
||||||
.Write(surface, ResourceState::COLOR_ATTACHMENT);
|
.Write(surface, ResourceState::COLOR_ATTACHMENT);
|
||||||
@ -41,7 +41,7 @@ namespace api {
|
|||||||
auto materialInstance = mesh->GetMaterialInstance();
|
auto materialInstance = mesh->GetMaterialInstance();
|
||||||
materialInstance.SetClassResource(Name("uColor"), Vector4{1,0,0,1});
|
materialInstance.SetClassResource(Name("uColor"), Vector4{1,0,0,1});
|
||||||
}
|
}
|
||||||
auto& surface = graph.mSurface;
|
auto& surface = graph.GetSurface();
|
||||||
ctx->SetViewport(0.0f, 0.0f,(float)surface.width,(float)surface.height, 0.f, 1.f);
|
ctx->SetViewport(0.0f, 0.0f,(float)surface.width,(float)surface.height, 0.f, 1.f);
|
||||||
ctx->SetScissor(0, 0, surface.width, surface.height);
|
ctx->SetScissor(0, 0, surface.width, surface.height);
|
||||||
RenderAPI::Ptr()->DrawStaticMesh(*mesh);
|
RenderAPI::Ptr()->DrawStaticMesh(*mesh);
|
||||||
|
|||||||
@ -23,6 +23,8 @@ namespace vkn {
|
|||||||
using api::ImagePtr;
|
using api::ImagePtr;
|
||||||
using api::TextureDimension;
|
using api::TextureDimension;
|
||||||
using api::SampleCount;
|
using api::SampleCount;
|
||||||
|
using api::TextureSampler;
|
||||||
|
using api::SamplerPtr;
|
||||||
using api::ResourceState;
|
using api::ResourceState;
|
||||||
using api::TextureDesc;
|
using api::TextureDesc;
|
||||||
using api::BufferDesc;
|
using api::BufferDesc;
|
||||||
@ -78,6 +80,17 @@ namespace vkn {
|
|||||||
uint32_t width;
|
uint32_t width;
|
||||||
uint32_t height;
|
uint32_t height;
|
||||||
uint32_t layers;
|
uint32_t layers;
|
||||||
|
friend inline bool operator==(const FramebufferKey& k1, const FramebufferKey& k2) {
|
||||||
|
if (k1.pass != k2.pass) return false;
|
||||||
|
if (k1.attachmentCount != k2.attachmentCount) return false;
|
||||||
|
for (int i = 0; i < k1.attachmentCount; i++) {
|
||||||
|
if (k1.imageViews[i] != k2.imageViews[i]) return false;
|
||||||
|
}
|
||||||
|
if (k1.height != k2.height) return false;
|
||||||
|
if (k1.width != k2.width) return false;
|
||||||
|
if (k1.layers != k2.layers) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
// Equivalent to VkVertexInputAttributeDescription but half as big.
|
// Equivalent to VkVertexInputAttributeDescription but half as big.
|
||||||
struct VertexInputAttributeDescription {
|
struct VertexInputAttributeDescription {
|
||||||
@ -121,17 +134,6 @@ namespace vkn {
|
|||||||
uint32_t descCount = 0;
|
uint32_t descCount = 0;
|
||||||
bool inUse = false;
|
bool inUse = false;
|
||||||
};
|
};
|
||||||
inline bool operator==(const FramebufferKey& k1, const FramebufferKey& k2) {
|
|
||||||
if (k1.pass != k2.pass) return false;
|
|
||||||
if (k1.attachmentCount != k2.attachmentCount) return false;
|
|
||||||
for (int i = 0; i < k1.attachmentCount; i++) {
|
|
||||||
if (k1.imageViews[i] != k2.imageViews[i]) return false;
|
|
||||||
}
|
|
||||||
if (k1.height != k2.height) return false;
|
|
||||||
if (k1.width != k2.width) return false;
|
|
||||||
if (k1.layers != k2.layers) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
namespace std {
|
namespace std {
|
||||||
template<>
|
template<>
|
||||||
|
|||||||
@ -2,6 +2,11 @@
|
|||||||
#include "vulkan_context.h"
|
#include "vulkan_context.h"
|
||||||
#include "asset/res/guid.h"
|
#include "asset/res/guid.h"
|
||||||
#include "backend.h"
|
#include "backend.h"
|
||||||
|
#ifdef API_DEBUG
|
||||||
|
#define gLogSemaphore(...) //zlog::info(__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define gLogSemaphore(...)
|
||||||
|
#endif
|
||||||
namespace vkn {
|
namespace vkn {
|
||||||
class VulkanWindow;
|
class VulkanWindow;
|
||||||
using api::Guid;
|
using api::Guid;
|
||||||
@ -34,7 +39,7 @@ namespace vkn {
|
|||||||
void CreateBuffer(BufferDesc& desc) override;
|
void CreateBuffer(BufferDesc& desc) override;
|
||||||
void CreateTexture(TextureDesc& desc)override;
|
void CreateTexture(TextureDesc& desc)override;
|
||||||
ImageViewPtr CreateTextureView(TextureViewKey desc)override;
|
ImageViewPtr CreateTextureView(TextureViewKey desc)override;
|
||||||
|
SamplerPtr CreateTextureSampler(TextureSampler sampler) override;
|
||||||
void BeginFrame()override;
|
void BeginFrame()override;
|
||||||
void EndFrame()override;
|
void EndFrame()override;
|
||||||
void BeginRenderPass(RenderPassNode* node, FnEnterRenderPass callback) override;
|
void BeginRenderPass(RenderPassNode* node, FnEnterRenderPass callback) override;
|
||||||
|
|||||||
@ -26,4 +26,5 @@ namespace vkn {
|
|||||||
VkDescriptorType vkApiGetDescriptorType(ShaderDescriptorType type);
|
VkDescriptorType vkApiGetDescriptorType(ShaderDescriptorType type);
|
||||||
VkShaderStageFlags vkApiGetShaderStageFlags(ShaderStage stage);
|
VkShaderStageFlags vkApiGetShaderStageFlags(ShaderStage stage);
|
||||||
VkBufferUsageFlagBits vkApiGetBufferUsage(BufferUsage usage);
|
VkBufferUsageFlagBits vkApiGetBufferUsage(BufferUsage usage);
|
||||||
|
VkSamplerCreateInfo vkApiGetSamplerCreateInfo(TextureSampler sampler);
|
||||||
}
|
}
|
||||||
@ -1,8 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "render/editor_system.h"
|
#include "render/editor_system.h"
|
||||||
#include "render/graph/frame_graph.h"
|
#include "render/graph/frame_graph.h"
|
||||||
|
#include "vkn/vulkan_api.h"
|
||||||
namespace vkn {
|
namespace vkn {
|
||||||
using api::TextureDesc;
|
|
||||||
using api::FrameGraph;
|
using api::FrameGraph;
|
||||||
using api::RenderPassContext;
|
using api::RenderPassContext;
|
||||||
using api::RenderPassBuilder;
|
using api::RenderPassBuilder;
|
||||||
@ -12,7 +12,7 @@ namespace vkn {
|
|||||||
void Initialize() override;
|
void Initialize() override;
|
||||||
void Finalize() override;
|
void Finalize() override;
|
||||||
|
|
||||||
ImTextureID AddTexture(const TextureDesc& desc) override;
|
ImTextureID AddTexture(ImageViewPtr imageview, SamplerPtr sampler, ResourceState state) override;
|
||||||
|
|
||||||
void Render(FrameGraph& graph, RenderEditorContext& ctx);
|
void Render(FrameGraph& graph, RenderEditorContext& ctx);
|
||||||
void OnBeginRenderFrame(FrameGraph& graph, uint32_t frame);
|
void OnBeginRenderFrame(FrameGraph& graph, uint32_t frame);
|
||||||
|
|||||||
@ -325,6 +325,13 @@ namespace vkn {
|
|||||||
vkCreateImageView(backend.GetDevice().Ptr(), &createInfo, nullptr, &imageView);
|
vkCreateImageView(backend.GetDevice().Ptr(), &createInfo, nullptr, &imageView);
|
||||||
return (ImageViewPtr)imageView;
|
return (ImageViewPtr)imageView;
|
||||||
}
|
}
|
||||||
|
SamplerPtr VulkanAPI::CreateTextureSampler(TextureSampler key)
|
||||||
|
{
|
||||||
|
VkSamplerCreateInfo samplerInfo = vkApiGetSamplerCreateInfo(key);
|
||||||
|
VkSampler sampler;
|
||||||
|
vkCreateSampler(backend.GetDevice().Ptr(), &samplerInfo, nullptr, &sampler);
|
||||||
|
return sampler;
|
||||||
|
}
|
||||||
void VulkanAPI::BeginFrame()
|
void VulkanAPI::BeginFrame()
|
||||||
{
|
{
|
||||||
VulkanContext& ctx = *(VulkanContext*)&context;
|
VulkanContext& ctx = *(VulkanContext*)&context;
|
||||||
@ -435,13 +442,13 @@ namespace vkn {
|
|||||||
if (node->IsFirstInput()) {
|
if (node->IsFirstInput()) {
|
||||||
waitDstStageMasks[semaphoreCount] = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
waitDstStageMasks[semaphoreCount] = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
waitSemaphores[semaphoreCount++] = ctx.surfaceSemaphore;
|
waitSemaphores[semaphoreCount++] = ctx.surfaceSemaphore;
|
||||||
//zlog::info("-----wait {:#x}", (uintptr_t)ctx.surfaceSemaphore);
|
gLogSemaphore("-----wait {:#x}", (uintptr_t)ctx.surfaceSemaphore);
|
||||||
}
|
}
|
||||||
for (auto& it : node->dependencies) {
|
for (auto& it : node->dependencies) {
|
||||||
RenderPassInfo* inputInfo = GetRenderPassInfo(it->name ,it->hash);
|
RenderPassInfo* inputInfo = GetRenderPassInfo(it->name ,it->hash);
|
||||||
waitDstStageMasks[semaphoreCount] = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
waitDstStageMasks[semaphoreCount] = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
waitSemaphores[semaphoreCount++] = inputInfo->semaphores[context.frame];
|
waitSemaphores[semaphoreCount++] = inputInfo->semaphores[context.frame];
|
||||||
//zlog::info("-----wait {:#x}", (uintptr_t)inputInfo->semaphores[context.frame]);
|
gLogSemaphore("-----wait {:#x}", (uintptr_t)inputInfo->semaphores[context.frame]);
|
||||||
}
|
}
|
||||||
VkSubmitInfo submitInfo{};
|
VkSubmitInfo submitInfo{};
|
||||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
@ -455,11 +462,12 @@ namespace vkn {
|
|||||||
VkFence fence = nullptr;
|
VkFence fence = nullptr;
|
||||||
if (node->IsLastOutput()) {
|
if (node->IsLastOutput()) {
|
||||||
ctx.graphSemaphore = passInfo->semaphores[context.frame];
|
ctx.graphSemaphore = passInfo->semaphores[context.frame];
|
||||||
if (graph.mSurface.state == ResourceState::PRESENT) {
|
TextureDesc& surface = graph.GetRenderSurface();
|
||||||
|
if (surface.state == ResourceState::PRESENT) {
|
||||||
fence = ctx.surfaceFence;
|
fence = ctx.surfaceFence;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//zlog::info("+++++sign {:#x}", (uintptr_t)passInfo->semaphores[context.frame]);
|
gLogSemaphore("+++++sign {:#x}", (uintptr_t)passInfo->semaphores[context.frame]);
|
||||||
vkQueueSubmit(Backend::RenderWorker->GetQueue().Ptr(), 1, &submitInfo, fence);
|
vkQueueSubmit(Backend::RenderWorker->GetQueue().Ptr(), 1, &submitInfo, fence);
|
||||||
}
|
}
|
||||||
RenderPassInfo* VulkanAPI::GetRenderPassInfo(Name name, size_t hash) {
|
RenderPassInfo* VulkanAPI::GetRenderPassInfo(Name name, size_t hash) {
|
||||||
|
|||||||
@ -184,8 +184,10 @@ namespace vkn {
|
|||||||
VkImageUsageFlags usageFlags = 0;
|
VkImageUsageFlags usageFlags = 0;
|
||||||
if (any(usage & TextureUsage::COLOR_ATTACHMENT))
|
if (any(usage & TextureUsage::COLOR_ATTACHMENT))
|
||||||
usageFlags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
usageFlags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||||
else if (any(usage & TextureUsage::DEPTH_ATTACHMENT))
|
if (any(usage & TextureUsage::DEPTH_ATTACHMENT))
|
||||||
usageFlags |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
usageFlags |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||||
|
if(any(usage & TextureUsage::SAMPLEABLE))
|
||||||
|
usageFlags |= VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||||
return usageFlags;
|
return usageFlags;
|
||||||
}
|
}
|
||||||
VkImageViewType vkApiGetImageViewType(TextureDimension dimension, uint32_t arraySize)
|
VkImageViewType vkApiGetImageViewType(TextureDimension dimension, uint32_t arraySize)
|
||||||
@ -267,4 +269,115 @@ namespace vkn {
|
|||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
using api::SamplerWrapMode;
|
||||||
|
using api::SamplerMinFilter;
|
||||||
|
using api::SamplerMagFilter;
|
||||||
|
using api::SamplerCompareMode;
|
||||||
|
using api::SamplerCompareFunc;
|
||||||
|
constexpr inline VkSamplerAddressMode getWrapMode(SamplerWrapMode mode) noexcept {
|
||||||
|
switch (mode) {
|
||||||
|
case SamplerWrapMode::REPEAT:
|
||||||
|
return VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||||
|
case SamplerWrapMode::CLAMP_TO_EDGE:
|
||||||
|
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||||
|
case SamplerWrapMode::MIRRORED_REPEAT:
|
||||||
|
return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr inline VkFilter getFilter(SamplerMinFilter filter) noexcept {
|
||||||
|
switch (filter) {
|
||||||
|
case SamplerMinFilter::NEAREST:
|
||||||
|
return VK_FILTER_NEAREST;
|
||||||
|
case SamplerMinFilter::LINEAR:
|
||||||
|
return VK_FILTER_LINEAR;
|
||||||
|
case SamplerMinFilter::NEAREST_MIPMAP_NEAREST:
|
||||||
|
return VK_FILTER_NEAREST;
|
||||||
|
case SamplerMinFilter::LINEAR_MIPMAP_NEAREST:
|
||||||
|
return VK_FILTER_LINEAR;
|
||||||
|
case SamplerMinFilter::NEAREST_MIPMAP_LINEAR:
|
||||||
|
return VK_FILTER_NEAREST;
|
||||||
|
case SamplerMinFilter::LINEAR_MIPMAP_LINEAR:
|
||||||
|
return VK_FILTER_LINEAR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr inline VkFilter getFilter(SamplerMagFilter filter) noexcept {
|
||||||
|
switch (filter) {
|
||||||
|
case SamplerMagFilter::NEAREST:
|
||||||
|
return VK_FILTER_NEAREST;
|
||||||
|
case SamplerMagFilter::LINEAR:
|
||||||
|
return VK_FILTER_LINEAR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr inline VkSamplerMipmapMode getMipmapMode(SamplerMinFilter filter) noexcept {
|
||||||
|
switch (filter) {
|
||||||
|
case SamplerMinFilter::NEAREST:
|
||||||
|
return VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
||||||
|
case SamplerMinFilter::LINEAR:
|
||||||
|
return VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
||||||
|
case SamplerMinFilter::NEAREST_MIPMAP_NEAREST:
|
||||||
|
return VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
||||||
|
case SamplerMinFilter::LINEAR_MIPMAP_NEAREST:
|
||||||
|
return VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
||||||
|
case SamplerMinFilter::NEAREST_MIPMAP_LINEAR:
|
||||||
|
return VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||||
|
case SamplerMinFilter::LINEAR_MIPMAP_LINEAR:
|
||||||
|
return VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr inline float getMaxLod(SamplerMinFilter filter) noexcept {
|
||||||
|
switch (filter) {
|
||||||
|
case SamplerMinFilter::NEAREST:
|
||||||
|
case SamplerMinFilter::LINEAR:
|
||||||
|
// The Vulkan spec recommends a max LOD of 0.25 to "disable" mipmapping.
|
||||||
|
// See "Mapping of OpenGL to Vulkan filter modes" in the VK Spec.
|
||||||
|
return 0.25f;
|
||||||
|
case SamplerMinFilter::NEAREST_MIPMAP_NEAREST:
|
||||||
|
case SamplerMinFilter::LINEAR_MIPMAP_NEAREST:
|
||||||
|
case SamplerMinFilter::NEAREST_MIPMAP_LINEAR:
|
||||||
|
case SamplerMinFilter::LINEAR_MIPMAP_LINEAR:
|
||||||
|
return VK_LOD_CLAMP_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr inline VkBool32 getCompareEnable(SamplerCompareMode mode) noexcept {
|
||||||
|
return mode == SamplerCompareMode::NONE ? VK_FALSE : VK_TRUE;
|
||||||
|
}
|
||||||
|
VkCompareOp getCompareOp(SamplerCompareFunc func) {
|
||||||
|
using Compare = SamplerCompareFunc;
|
||||||
|
switch (func) {
|
||||||
|
case Compare::LE: return VK_COMPARE_OP_LESS_OR_EQUAL;
|
||||||
|
case Compare::GE: return VK_COMPARE_OP_GREATER_OR_EQUAL;
|
||||||
|
case Compare::L: return VK_COMPARE_OP_LESS;
|
||||||
|
case Compare::G: return VK_COMPARE_OP_GREATER;
|
||||||
|
case Compare::E: return VK_COMPARE_OP_EQUAL;
|
||||||
|
case Compare::NE: return VK_COMPARE_OP_NOT_EQUAL;
|
||||||
|
case Compare::A: return VK_COMPARE_OP_ALWAYS;
|
||||||
|
case Compare::N: return VK_COMPARE_OP_NEVER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VkSamplerCreateInfo vkApiGetSamplerCreateInfo(TextureSampler sampler)
|
||||||
|
{
|
||||||
|
VkSamplerCreateInfo samplerInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
|
||||||
|
.magFilter = getFilter(sampler.filterMag),
|
||||||
|
.minFilter = getFilter(sampler.filterMin),
|
||||||
|
.mipmapMode = getMipmapMode(sampler.filterMin),
|
||||||
|
.addressModeU = getWrapMode(sampler.wrapS),
|
||||||
|
.addressModeV = getWrapMode(sampler.wrapT),
|
||||||
|
.addressModeW = getWrapMode(sampler.wrapR),
|
||||||
|
.anisotropyEnable = sampler.anisotropyLog2 == 0 ? 0u : 1u,
|
||||||
|
.maxAnisotropy = (float)(1u << sampler.anisotropyLog2),
|
||||||
|
.compareEnable = getCompareEnable(sampler.compareMode),
|
||||||
|
.compareOp = getCompareOp(sampler.compareFunc),
|
||||||
|
.minLod = 0.0f,
|
||||||
|
.maxLod = getMaxLod(sampler.filterMin),
|
||||||
|
.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK,
|
||||||
|
.unnormalizedCoordinates = VK_FALSE
|
||||||
|
};
|
||||||
|
return samplerInfo;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -83,8 +83,8 @@ namespace vkn {
|
|||||||
|
|
||||||
submitInfo.signalSemaphoreCount = 1;
|
submitInfo.signalSemaphoreCount = 1;
|
||||||
submitInfo.pSignalSemaphores = signalSemaphores;
|
submitInfo.pSignalSemaphores = signalSemaphores;
|
||||||
//zlog::info("-----wait {:#x}", (uintptr_t)waitSemaphores[0]);
|
gLogSemaphore("-----wait {:#x}", (uintptr_t)waitSemaphores[0]);
|
||||||
//zlog::info("+++++sign {:#x}", (uintptr_t)signalSemaphores[0]);
|
gLogSemaphore("+++++sign {:#x}", (uintptr_t)signalSemaphores[0]);
|
||||||
vkQueueSubmit(queue, 1, &submitInfo, surfaceFence);
|
vkQueueSubmit(queue, 1, &submitInfo, surfaceFence);
|
||||||
graphSemaphore = presentSemaphore;
|
graphSemaphore = presentSemaphore;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
#include "vkn/vulkan_imgui_editor.h"
|
#include "vkn/vulkan_imgui_editor.h"
|
||||||
#include "vkn/vulkan_window.h"
|
#include "vkn/vulkan_window.h"
|
||||||
#include "vkn/vulkan_api.h"
|
|
||||||
#include "vkn/vulkan_api_help.h"
|
#include "vkn/vulkan_api_help.h"
|
||||||
#include "vkn/backend.h"
|
#include "vkn/backend.h"
|
||||||
#include "vkn/wrapper/device.h"
|
#include "vkn/wrapper/device.h"
|
||||||
@ -110,8 +109,8 @@ namespace vkn {
|
|||||||
//gEngineConfig.IsRenderEditorSurface = true;
|
//gEngineConfig.IsRenderEditorSurface = true;
|
||||||
if (gEngineConfig.IsRenderEditorSurface) {
|
if (gEngineConfig.IsRenderEditorSurface) {
|
||||||
TextureDesc desc{};
|
TextureDesc desc{};
|
||||||
desc.width = 200;
|
desc.width = 512;
|
||||||
desc.height = 200;
|
desc.height = 512;
|
||||||
desc.format = TinyImageFormat_FromVkFormat((TinyImageFormat_VkFormat)VK_FORMAT_B8G8R8A8_SRGB);
|
desc.format = TinyImageFormat_FromVkFormat((TinyImageFormat_VkFormat)VK_FORMAT_B8G8R8A8_SRGB);
|
||||||
desc.state = ResourceState::UNDEFINED;
|
desc.state = ResourceState::UNDEFINED;
|
||||||
desc.sampleCount = SampleCount::SAMPLE_COUNT_1;
|
desc.sampleCount = SampleCount::SAMPLE_COUNT_1;
|
||||||
@ -119,7 +118,7 @@ namespace vkn {
|
|||||||
desc.mipLevel = 1;
|
desc.mipLevel = 1;
|
||||||
desc.depth = 1;
|
desc.depth = 1;
|
||||||
desc.dimension = TextureDimension::TEX_2D;
|
desc.dimension = TextureDimension::TEX_2D;
|
||||||
desc.usage = TextureUsage::COLOR_ATTACHMENT;
|
desc.usage = TextureUsage::COLOR_ATTACHMENT | TextureUsage::SAMPLEABLE;
|
||||||
for (uint32_t i = 0; i < API->context.frameCount; i++) {
|
for (uint32_t i = 0; i < API->context.frameCount; i++) {
|
||||||
API->graph.SetResourceTexture(desc, FrameGraph::NameEditorSurface, i);
|
API->graph.SetResourceTexture(desc, FrameGraph::NameEditorSurface, i);
|
||||||
}
|
}
|
||||||
@ -130,12 +129,10 @@ namespace vkn {
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
ImTextureID VulkanImguiEditor::AddTexture(const TextureDesc& desc)
|
ImTextureID VulkanImguiEditor::AddTexture(ImageViewPtr imageview, SamplerPtr sampler, ResourceState state)
|
||||||
{
|
{
|
||||||
// 2. 通过 ImGui_ImplVulkan_AddTexture 连接 Vulkan 纹理和 ImGui
|
VkDescriptorSet descriptorSet = ImGui_ImplVulkan_AddTexture((VkSampler)sampler, (VkImageView)imageview, vkApiGetImageLayout(state));
|
||||||
//ImTextureID textureID = (ImTextureID)(intptr_t)textureImageView;
|
return reinterpret_cast<ImTextureID>(descriptorSet);
|
||||||
//ImGui_ImplVulkan_AddTexture(textureSampler, textureImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
|
||||||
return ImTextureID{};
|
|
||||||
}
|
}
|
||||||
void VulkanImguiEditor::Render(FrameGraph& graph, RenderEditorContext& ctx)
|
void VulkanImguiEditor::Render(FrameGraph& graph, RenderEditorContext& ctx)
|
||||||
{
|
{
|
||||||
@ -148,28 +145,31 @@ namespace vkn {
|
|||||||
{
|
{
|
||||||
graph.mIsRenderEditorSurface = gEngineConfig.IsRenderEditorSurface;
|
graph.mIsRenderEditorSurface = gEngineConfig.IsRenderEditorSurface;
|
||||||
if (gEngineConfig.IsRenderEditorSurface) {
|
if (gEngineConfig.IsRenderEditorSurface) {
|
||||||
graph.mEditorSurface = graph.mSurface;
|
graph.mEditorSurfaceID = graph.mSurfaceID;
|
||||||
graph.mSurface = graph.ResourceTexture(FrameGraph::NameEditorSurface, frame);
|
graph.mSurfaceID = graph.GetTextureID(FrameGraph::NameEditorSurface, frame);
|
||||||
}
|
}
|
||||||
graph.AddRenderPass<VulkanImguiEditor>();
|
graph.AddRenderPass<VulkanImguiEditor>();
|
||||||
}
|
}
|
||||||
void VulkanImguiEditor::Setup(FrameGraph& graph, RenderPassBuilder& builder)
|
void VulkanImguiEditor::Setup(FrameGraph& graph, RenderPassBuilder& builder)
|
||||||
{
|
{
|
||||||
AttachmentDesc surface{ gEngineConfig.IsRenderEditorSurface ? graph.mEditorSurface : graph.mSurface };
|
AttachmentDesc surface{ graph.GetRenderSurface() };
|
||||||
builder.Name(ImguiPassName)
|
builder.Name(ImguiPassName)
|
||||||
.Type(RenderPassNodeType::Imgui, RenderPassNodeFlag::Output)
|
.Type(RenderPassNodeType::Imgui, RenderPassNodeFlag::Output)
|
||||||
.Write(surface, ResourceState::COLOR_ATTACHMENT);
|
.Write(surface, ResourceState::COLOR_ATTACHMENT);
|
||||||
|
if (gEngineConfig.IsRenderEditorSurface) {
|
||||||
|
builder.Read(graph.GetSurface(), ResourceState::READ_ONLY);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void VulkanImguiEditor::Execute(FrameGraph& graph, RenderPassContext& context)
|
void VulkanImguiEditor::Execute(FrameGraph& graph, RenderPassContext& context)
|
||||||
{
|
{
|
||||||
TextureDesc& surface = graph.mEditorSurface.image ? graph.mEditorSurface : graph.mSurface;
|
graph.GetRenderSurface().state = ResourceState::PRESENT;
|
||||||
graph.TransitionState(surface, ResourceState::PRESENT);
|
|
||||||
ImGui_ImplVulkan_NewFrame();
|
ImGui_ImplVulkan_NewFrame();
|
||||||
ImGui_ImplSDL2_NewFrame();
|
ImGui_ImplSDL2_NewFrame();
|
||||||
ImGui::NewFrame();
|
ImGui::NewFrame();
|
||||||
|
|
||||||
RenderEditorContext editorContext{};
|
VulkanImguiEditor* editor = VulkanImguiEditor::Ptr();
|
||||||
VulkanImguiEditor::Ptr()->Render(graph, editorContext);
|
RenderEditorContext editorContext{.editor = editor, .frame = context->frame, .frameCount = context->frameCount };
|
||||||
|
editor->Render(graph, editorContext);
|
||||||
|
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
VulkanContext& ctx = *(VulkanContext*)context.parent;
|
VulkanContext& ctx = *(VulkanContext*)context.parent;
|
||||||
|
|||||||
@ -103,11 +103,12 @@ namespace vkn {
|
|||||||
vkAcquireNextImageKHR(mDevice.Ptr(), mPtr, UINT64_MAX, surfaceSemaphore, VK_NULL_HANDLE, &ctx.presentFrame);
|
vkAcquireNextImageKHR(mDevice.Ptr(), mPtr, UINT64_MAX, surfaceSemaphore, VK_NULL_HANDLE, &ctx.presentFrame);
|
||||||
vkResetFences(mDevice.Ptr(), 1, &surfaceFence);
|
vkResetFences(mDevice.Ptr(), 1, &surfaceFence);
|
||||||
ctx.surface = mSurfaces[ctx.presentFrame];
|
ctx.surface = mSurfaces[ctx.presentFrame];
|
||||||
//zlog::info("aquire------------:: {:#x}", (uintptr_t)surfaceSemaphore);
|
ctx.graphSemaphore = nullptr;
|
||||||
|
gLogSemaphore("aquire------------:: {:#x}", (uintptr_t)surfaceSemaphore);
|
||||||
}
|
}
|
||||||
void VulkanSwapchain::Present(VulkanContext& ctx)
|
void VulkanSwapchain::Present(VulkanContext& ctx)
|
||||||
{
|
{
|
||||||
//zlog::info("present+++++++++++:: {:#x}", (uintptr_t)ctx.presentSemaphore);
|
gLogSemaphore("present+++++++++++:: {:#x}", (uintptr_t)ctx.presentSemaphore);
|
||||||
VkPresentInfoKHR presentInfo = {};
|
VkPresentInfoKHR presentInfo = {};
|
||||||
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||||
presentInfo.pWaitSemaphores = &ctx.graphSemaphore;
|
presentInfo.pWaitSemaphores = &ctx.graphSemaphore;
|
||||||
|
|||||||
@ -2,16 +2,19 @@
|
|||||||
#include "data/global.h"
|
#include "data/global.h"
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
namespace api {
|
namespace api {
|
||||||
|
TextureSampler sampler;
|
||||||
|
ImTextureID TextureIDList[10] = {};
|
||||||
void AssetPreviewPanel::DrawPanel(FrameGraph& graph, RenderEditorContext& context) {
|
void AssetPreviewPanel::DrawPanel(FrameGraph& graph, RenderEditorContext& context) {
|
||||||
static float my_float = 0.5f;
|
static float my_float = 0.5f;
|
||||||
ImGui::Text("This is some useful text.");
|
ImGui::Text("This is some useful text.");
|
||||||
ImGui::SliderFloat("float", &my_float, 0.0f, 1.0f);
|
ImGui::SliderFloat("float", &my_float, 0.0f, 1.0f);
|
||||||
if (gEngineConfig.IsRenderEditorSurface) {
|
if (gEngineConfig.IsRenderEditorSurface) {
|
||||||
TextureDesc& surface = graph.mSurface;
|
TextureDesc surface = graph.GetSurface();
|
||||||
// 2. 通过 ImGui_ImplVulkan_AddTexture 连接 Vulkan 纹理和 ImGui
|
if (!TextureIDList[context.frame]) {
|
||||||
//ImTextureID textureID = (ImTextureID)(intptr_t)graph.ResolveTextureView(surface);
|
TextureIDList[context.frame] = context->AddTexture(graph, surface, sampler);
|
||||||
// 3. 在 ImGui 窗口中渲染 Vulkan 纹理
|
}
|
||||||
//ImGui::Image(textureID, ImVec2(surface.width, surface.height));
|
// 每帧渲染时都可以通过 ImTextureID 使用
|
||||||
|
ImGui::Image(TextureIDList[context.frame], ImVec2(surface.width, surface.height));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -21,6 +21,9 @@
|
|||||||
#define RENDER_API_VAL 1
|
#define RENDER_API_VAL 1
|
||||||
#include "renderapi_impl.inl"
|
#include "renderapi_impl.inl"
|
||||||
#include "window_impl.inl"
|
#include "window_impl.inl"
|
||||||
|
#ifdef WITH_EDITOR
|
||||||
|
#include "editor_system_impl.inl"
|
||||||
|
#endif
|
||||||
#endif // !RENDER_API_VAL
|
#endif // !RENDER_API_VAL
|
||||||
|
|
||||||
#ifndef APP_API_VAL
|
#ifndef APP_API_VAL
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user