update renderpass
This commit is contained in:
parent
7423dd7656
commit
8f0b9b634b
@ -11,8 +11,8 @@ namespace engineapi {
|
||||
const char* name = "zengine";
|
||||
new AssetManager();
|
||||
_RenderAPI = RenderAPI::MakeInstance();
|
||||
_RenderAPI->SetUpRenderPasses();
|
||||
_Window = Window::MakeInstance(3, 640, 720, name);
|
||||
_RenderAPI->OnInit();
|
||||
auto scene_manager = new SceneManager();
|
||||
scene_manager->LoadScene(path);
|
||||
}
|
||||
|
||||
@ -9,8 +9,4 @@ namespace engineapi {
|
||||
Material::~Material()
|
||||
{
|
||||
}
|
||||
void Material::Use()
|
||||
{
|
||||
RenderAPI::GetSingletonPtr()->UseMaterial(mId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,8 +10,5 @@ namespace engineapi {
|
||||
Material(string name, uint32_t flags);
|
||||
~Material();
|
||||
|
||||
|
||||
void Use();
|
||||
|
||||
};
|
||||
};
|
||||
@ -4,7 +4,6 @@ namespace engineapi {
|
||||
class Texture;
|
||||
class Material;
|
||||
class Mesh : public Asset {
|
||||
friend class RenderVulkanAPI;
|
||||
protected:
|
||||
uint32_t VAO = 0;
|
||||
vector<Vertex> mVertices;
|
||||
@ -12,5 +11,16 @@ namespace engineapi {
|
||||
public:
|
||||
Mesh(string name, uint32_t flags, vector<Vertex>& vertices, vector<uint32_t>& indices);
|
||||
void BeginLoad()override;
|
||||
|
||||
public:
|
||||
uint32_t& GetVAO() {
|
||||
return VAO;
|
||||
}
|
||||
vector<Vertex>& GetVertices() {
|
||||
return mVertices;
|
||||
}
|
||||
vector<uint32_t>& GetIndices() {
|
||||
return mIndices;
|
||||
}
|
||||
};
|
||||
};
|
||||
@ -13,8 +13,4 @@ namespace engineapi {
|
||||
{
|
||||
|
||||
}
|
||||
void Shader::Use()
|
||||
{
|
||||
RenderAPI::GetSingletonPtr()->UseShader(mId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,6 +9,5 @@ namespace engineapi {
|
||||
Shader(string name, uint32_t flags);
|
||||
~Shader();
|
||||
void BeginLoad()override;
|
||||
void Use();
|
||||
};
|
||||
};
|
||||
9
engine/src/engine/render/node/rendernode.cpp
Normal file
9
engine/src/engine/render/node/rendernode.cpp
Normal file
@ -0,0 +1,9 @@
|
||||
#include "rendernode.h"
|
||||
#include "../renderapi.h"
|
||||
namespace engineapi {
|
||||
RenderNode::RenderNode(RenderType type)
|
||||
: mType(type)
|
||||
{
|
||||
mContext = RenderAPI::GetSingletonPtr()->GetContext();
|
||||
}
|
||||
}
|
||||
32
engine/src/engine/render/node/rendernode.h
Normal file
32
engine/src/engine/render/node/rendernode.h
Normal file
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
#include "../asset/material.h"
|
||||
#include "../asset/mesh.h"
|
||||
#include "../asset/texture.h"
|
||||
#include "../render_context.h"
|
||||
namespace engineapi {
|
||||
enum RenderType
|
||||
{
|
||||
RENDER_SHADOW_GENERATION,
|
||||
RENDER_FORWARD_RENDERING,
|
||||
RENDER_RAY_TRACING,
|
||||
RENDER_AFTER_EFFECT_RENDERING,
|
||||
RENDER_UI_RENDERING,
|
||||
RENDER_COUNT
|
||||
};
|
||||
class Camera;
|
||||
class RenderNode
|
||||
{
|
||||
protected:
|
||||
RenderType mType;
|
||||
RenderContext* mContext;
|
||||
public:
|
||||
RenderNode(RenderType type);
|
||||
~RenderNode() {};
|
||||
|
||||
virtual void Render(Camera& camera) = 0;
|
||||
public:
|
||||
RenderType GetType() {
|
||||
return mType;
|
||||
}
|
||||
};
|
||||
};
|
||||
@ -1,32 +1,23 @@
|
||||
#include "renderpass_forward.h"
|
||||
#include "rendernode_forward.h"
|
||||
#include "../renderapi.h"
|
||||
#include "../window.h"
|
||||
#include "object/camera/camera.h"
|
||||
#include "../asset/model.h"
|
||||
#include "asset/asset_manager.h"
|
||||
namespace engineapi {
|
||||
RenderPassForwardRendering::RenderPassForwardRendering()
|
||||
RenderNodeForwardRendering::RenderNodeForwardRendering()
|
||||
:RenderNode(RENDER_FORWARD_RENDERING)
|
||||
{
|
||||
mID = 0;
|
||||
mSky = AssetManager::GetSingletonPtr()->LoadAsset<Model>("assets/models/SkyBoxMesh.ply", Asset::ASSET_SHARED_FLAG | Asset::ASSET_ASYNC_FLAG);
|
||||
//skyBoxMaterial = new Material(new Shader(Resources::GetAssetFullPath("Shaders/SkyBox.zxshader", true), FrameBufferType::Normal));
|
||||
|
||||
|
||||
skyBoxRenderState = new RenderStateSetting();
|
||||
skyBoxRenderState->depthTest = false;
|
||||
skyBoxRenderState->depthWrite = false;
|
||||
|
||||
opaqueRenderState = new RenderStateSetting();
|
||||
|
||||
transparentRenderState = new RenderStateSetting();
|
||||
transparentRenderState->depthWrite = false;
|
||||
|
||||
//drawCommandID = RenderAPI::GetSingletonPtr()->AllocateDrawCommand(CommandType::ForwardRendering);
|
||||
}
|
||||
RenderPassForwardRendering::~RenderPassForwardRendering()
|
||||
RenderNodeForwardRendering::~RenderNodeForwardRendering()
|
||||
{
|
||||
}
|
||||
void RenderPassForwardRendering::Render(Camera& camera)
|
||||
void RenderNodeForwardRendering::Render(Camera& camera)
|
||||
{
|
||||
auto renderAPI = RenderAPI::GetSingletonPtr();
|
||||
auto window = Window::GetSingletonPtr();
|
||||
@ -36,9 +27,10 @@ namespace engineapi {
|
||||
//FBOManager::GetInstance()->SwitchFBO("Forward");
|
||||
// ViewPort设置为窗口大小
|
||||
renderAPI->SetViewPort(width, height);
|
||||
|
||||
mContext->UsePass(mType);
|
||||
mContext->UseContext();
|
||||
}
|
||||
void RenderPassForwardRendering::RenderSkyBox(Camera& camera)
|
||||
void RenderNodeForwardRendering::RenderSkyBox(Camera& camera)
|
||||
{
|
||||
// 先转3x3再回4x4,把相机位移信息去除
|
||||
Matrix4 mat_V = Matrix4(Matrix3(camera.GetViewMatrix()));
|
||||
@ -52,7 +44,7 @@ namespace engineapi {
|
||||
|
||||
//RenderAPI::GetInstance()->Draw(skyBox->VAO);
|
||||
}
|
||||
void RenderPassForwardRendering::RenderBatches(const map<uint32_t, vector<MeshRenderer*>>& batchs)
|
||||
void RenderNodeForwardRendering::RenderBatches(const map<uint32_t, vector<MeshRenderer*>>& batchs)
|
||||
{
|
||||
|
||||
}
|
||||
@ -1,23 +1,19 @@
|
||||
#pragma once
|
||||
#include "renderpass.h"
|
||||
#include "rendernode.h"
|
||||
#include "object/render/mesh_render.h"
|
||||
namespace engineapi {
|
||||
class Camera;
|
||||
class Model;
|
||||
class RenderPassForwardRendering : public RenderPass
|
||||
class RenderNodeForwardRendering : public RenderNode
|
||||
{
|
||||
public:
|
||||
RenderPassForwardRendering();
|
||||
~RenderPassForwardRendering();
|
||||
RenderNodeForwardRendering();
|
||||
~RenderNodeForwardRendering();
|
||||
|
||||
virtual void Render(Camera& camera);
|
||||
|
||||
private:
|
||||
uint32_t mID;
|
||||
Model* mSky;
|
||||
RenderStateSetting* skyBoxRenderState;
|
||||
RenderStateSetting* opaqueRenderState;
|
||||
RenderStateSetting* transparentRenderState;
|
||||
|
||||
void RenderSkyBox(Camera& camera);
|
||||
void RenderBatches(const map<uint32_t, vector<MeshRenderer*>>& batchs);
|
||||
@ -1,43 +0,0 @@
|
||||
#pragma once
|
||||
#include "../asset/material.h"
|
||||
#include "../asset/mesh.h"
|
||||
#include "../asset/texture.h"
|
||||
namespace engineapi {
|
||||
enum RenderPassType
|
||||
{
|
||||
ZX_RENDER_PASS_SHADOW_GENERATION,
|
||||
ZX_RENDER_PASS_FORWARD_RENDERING,
|
||||
ZX_RENDER_PASS_RAY_TRACING,
|
||||
ZX_RENDER_PASS_AFTER_EFFECT_RENDERING,
|
||||
ZX_RENDER_PASS_UI_RENDERING,
|
||||
ZX_RENDER_PASS_COUNT
|
||||
};
|
||||
class Camera;
|
||||
class RenderPass
|
||||
{
|
||||
protected:
|
||||
RenderPassType mType;
|
||||
public:
|
||||
RenderPass(RenderPassType type) : mType(type){};
|
||||
~RenderPass() {};
|
||||
|
||||
virtual void Render(Camera& camera) = 0;
|
||||
public:
|
||||
RenderPassType GetType() {
|
||||
return mType;
|
||||
}
|
||||
};
|
||||
class RenderStateSetting
|
||||
{
|
||||
public:
|
||||
bool depthTest = true;
|
||||
bool depthWrite = true;
|
||||
BlendFactor srcFactor = BlendFactor::SRC_ALPHA;
|
||||
BlendFactor dstFactor = BlendFactor::ONE_MINUS_SRC_ALPHA;
|
||||
Vector4 clearColor = Vector4();
|
||||
float clearDepth = 1.0f;
|
||||
uint32_t clearStencil = 0;
|
||||
bool faceCull = true;
|
||||
FaceCullOption faceCullOption = FaceCullOption::Back;
|
||||
};
|
||||
};
|
||||
@ -3,10 +3,21 @@
|
||||
#include "asset/asset_render.h"
|
||||
namespace engineapi
|
||||
{
|
||||
struct RenderContext {
|
||||
uint32_t MaterialId;
|
||||
uint32_t PassId;
|
||||
uint32_t ShaderId;
|
||||
class RenderContext {
|
||||
public:
|
||||
uint32_t MaterialId{ 0 };
|
||||
uint32_t PassId{ 0 };
|
||||
uint32_t ShaderId{ 0 };
|
||||
public:
|
||||
virtual void UseContext(){};
|
||||
virtual void UseMaterial(uint32_t ID) {
|
||||
MaterialId = ID;
|
||||
};
|
||||
virtual void UseShader(uint32_t ID) {
|
||||
ShaderId = ID;
|
||||
};
|
||||
virtual void UsePass(uint32_t ID) {
|
||||
PassId = ID;
|
||||
};
|
||||
};
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
#include "renderapi.h"
|
||||
#include "pass/renderpass.h"
|
||||
#include "pass/renderpass_forward.h"
|
||||
#include "node/rendernode.h"
|
||||
#include "node/rendernode_forward.h"
|
||||
#ifdef VULKAN_API
|
||||
#include "vulkanapi/vulkanapi.h"
|
||||
#endif // VULKAN_API
|
||||
@ -9,32 +9,32 @@ namespace engineapi {
|
||||
{
|
||||
|
||||
}
|
||||
void RenderAPI::SetUpRenderPasses()
|
||||
void RenderAPI::OnInit()
|
||||
{
|
||||
mAllPasses.resize(ZX_RENDER_PASS_COUNT);
|
||||
|
||||
//mAllPasses[ZX_RENDER_PASS_SHADOW_GENERATION] = new RenderPassShadowGeneration();
|
||||
mAllPasses[ZX_RENDER_PASS_FORWARD_RENDERING] = new RenderPassForwardRendering();
|
||||
//mAllPasses[ZX_RENDER_PASS_RAY_TRACING] = new RenderPassRayTracing();
|
||||
//mAllPasses[ZX_RENDER_PASS_AFTER_EFFECT_RENDERING] = new RenderPassAfterEffectRendering();
|
||||
//mAllPasses[ZX_RENDER_PASS_UI_RENDERING] = new RenderPassUIRendering();
|
||||
|
||||
mCurPasses.clear();
|
||||
InitRenderNode();
|
||||
InitRenderPass();
|
||||
}
|
||||
void RenderAPI::InitRenderNode()
|
||||
{
|
||||
mAllNodes.clear();
|
||||
mAllNodes.resize(RENDER_COUNT);
|
||||
mAllNodes[RENDER_FORWARD_RENDERING] = new RenderNodeForwardRendering();
|
||||
|
||||
//mCurPasses.push_back(mAllPasses[ZX_RENDER_PASS_SHADOW_GENERATION]);
|
||||
mCurPasses.push_back(mAllPasses[ZX_RENDER_PASS_FORWARD_RENDERING]);
|
||||
mCurNodes.push_back(mAllNodes[RENDER_FORWARD_RENDERING]);
|
||||
//mCurPasses.push_back(mAllPasses[ZX_RENDER_PASS_AFTER_EFFECT_RENDERING]);
|
||||
//mCurPasses.push_back(mAllPasses[ZX_RENDER_PASS_UI_RENDERING]);
|
||||
}
|
||||
void RenderAPI::Render(Camera& camera)
|
||||
{
|
||||
for (auto pass : mCurPasses) {
|
||||
pass->Render(camera);
|
||||
for (auto node : mCurNodes) {
|
||||
node->Render(camera);
|
||||
}
|
||||
}
|
||||
RenderAPI* RenderAPI::MakeInstance()
|
||||
{
|
||||
#ifdef VULKAN_API
|
||||
return new RenderVulkanAPI();
|
||||
return new vulkanapi::RenderVulkanAPI();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -5,20 +5,23 @@ namespace engineapi
|
||||
{
|
||||
class Mesh;
|
||||
class Camera;
|
||||
class RenderPass;
|
||||
class RenderNode;
|
||||
class RenderAPI : public Singleton<RenderAPI>
|
||||
{
|
||||
protected:
|
||||
uint32_t mFrame;
|
||||
ViewPortInfo mViewPortInfo;
|
||||
|
||||
RenderContext* mContext;
|
||||
vector<RenderPass*> mCurPasses;
|
||||
vector<RenderPass*> mAllPasses;
|
||||
vector<RenderNode*> mCurNodes;
|
||||
vector<RenderNode*> mAllNodes;
|
||||
public:
|
||||
RenderAPI();
|
||||
virtual ~RenderAPI() {};
|
||||
public:
|
||||
virtual void SetUpRenderPasses();
|
||||
virtual RenderContext* GetContext() = 0;
|
||||
public:
|
||||
virtual void OnInit();
|
||||
virtual void InitRenderNode();
|
||||
virtual void InitRenderPass() = 0;
|
||||
public:
|
||||
virtual void SetViewPort(uint32_t width, uint32_t height, uint32_t xOffset = 0, uint32_t yOffset = 0) = 0;
|
||||
@ -29,16 +32,6 @@ namespace engineapi
|
||||
virtual void DrawStaticMesh(Mesh* mesh) = 0;
|
||||
|
||||
virtual void SwitchContext() = 0;
|
||||
|
||||
virtual void UseMaterial(uint32_t ID) {
|
||||
mContext->MaterialId = ID;
|
||||
};
|
||||
virtual void UseShader(uint32_t ID) {
|
||||
mContext->PassId = ID;
|
||||
};
|
||||
virtual void UsePass(uint32_t ID) {
|
||||
mContext->ShaderId = ID;
|
||||
};
|
||||
public:
|
||||
static RenderAPI* MakeInstance();
|
||||
};
|
||||
|
||||
@ -7,7 +7,7 @@ namespace engineapi {
|
||||
Window* Window::MakeInstance(int frames, uint32_t width, uint32_t height, const char* title)
|
||||
{
|
||||
#ifdef VULKAN_API
|
||||
return new vulkanapi::Window(frames, width, height, title);
|
||||
return new vulkanapi::VulkanWindow(frames, width, height, title);
|
||||
#endif
|
||||
}
|
||||
Window::WindowClass::WindowClass() noexcept
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
namespace vulkanapi {
|
||||
CommandWorker* Backend::TransferWorker = nullptr;
|
||||
CommandWorker* Backend::RenderWorker = nullptr;
|
||||
CommandWorker* Backend::PresentWorker = nullptr;
|
||||
Backend::Backend(const string appName)
|
||||
{
|
||||
auto instanceCreator = InstanceCreator();
|
||||
@ -26,6 +27,7 @@ namespace vulkanapi {
|
||||
|
||||
Backend::TransferWorker = GetWorker(Queue::TransferQueue);
|
||||
Backend::RenderWorker = GetWorker(Queue::RenderQueue);
|
||||
Backend::PresentWorker = GetWorker(Queue::PresentQueue);
|
||||
}
|
||||
Backend::~Backend()
|
||||
{
|
||||
|
||||
@ -27,5 +27,6 @@ namespace vulkanapi {
|
||||
public:
|
||||
static CommandWorker* TransferWorker;
|
||||
static CommandWorker* RenderWorker;
|
||||
static CommandWorker* PresentWorker;
|
||||
};
|
||||
};
|
||||
@ -1,12 +1,30 @@
|
||||
#include "forwardpass.h"
|
||||
#include "../wrapper/renderpass.h"
|
||||
#include "../wrapper/image.h"
|
||||
#include "../wrapper/framebuffer.h"
|
||||
#include "target.h"
|
||||
namespace vulkanapi {
|
||||
void ForwardPass::Record()
|
||||
{
|
||||
|
||||
}
|
||||
ForwardPass* ForwardPass::MakePass(Device& device, GeometryBuffer& gBuffer)
|
||||
void ForwardPass::InitTarget(Device& device, GeometryBuffer& gBuffer, RenderTarget* target)
|
||||
{
|
||||
mTarget = target;
|
||||
target->frames.reserve(target->size);
|
||||
for (int i = 0; i < target->size; i++) {
|
||||
auto outputView = gBuffer.positions[i]->View(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_VIEW_TYPE_2D);
|
||||
auto normalView = gBuffer.normals[i]->View(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_VIEW_TYPE_2D);
|
||||
vector<VkImageView> surfaces = { outputView, normalView };
|
||||
target->frames.emplace_back(device, target, this, surfaces);
|
||||
}
|
||||
mClearValues.resize(2);
|
||||
mClearValues[0].color = { { 0, 0, 0, 0 } };
|
||||
mClearValues[1].depthStencil = { 1, 0 };
|
||||
mPassBeginInfo.pClearValues = mClearValues.data();
|
||||
mPassBeginInfo.clearValueCount = 2;
|
||||
}
|
||||
ForwardPass* ForwardPass::MakePass(Device& device, GeometryBuffer& gBuffer, RenderTarget* target)
|
||||
{
|
||||
VkAttachmentDescription positionAttachment{};
|
||||
positionAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
@ -40,6 +58,9 @@ namespace vulkanapi {
|
||||
vector<VkAttachmentDescription> attachments = { positionAttachment , normalAttachment };
|
||||
vector<VkSubpassDescription> subpasses = { subpass };
|
||||
vector<VkSubpassDependency> dependencies;
|
||||
return new ForwardPass(device, "forward", attachments, subpasses, dependencies);
|
||||
|
||||
auto forwad = new ForwardPass(device, "forward", attachments, subpasses, dependencies);
|
||||
forwad->InitTarget(device, gBuffer, target);
|
||||
return forwad;
|
||||
}
|
||||
}
|
||||
@ -2,13 +2,15 @@
|
||||
#include "../wrapper/renderpass.h"
|
||||
#include "gbuffer.h"
|
||||
namespace vulkanapi {
|
||||
//class MaterialCache;
|
||||
class RenderTarget;
|
||||
class ForwardPass : public RenderPass {
|
||||
//MaterialCache mMaterials;
|
||||
protected:
|
||||
vector<VkClearValue> mClearValues;
|
||||
public:
|
||||
using RenderPass::RenderPass;
|
||||
void Record();
|
||||
void InitTarget(Device& device, GeometryBuffer& gBuffer, RenderTarget* target);
|
||||
public:
|
||||
static ForwardPass* MakePass(Device& device, GeometryBuffer& gBuffer);
|
||||
static ForwardPass* MakePass(Device& device, GeometryBuffer& gBuffer, RenderTarget* target);
|
||||
};
|
||||
}
|
||||
@ -9,11 +9,15 @@ namespace vulkanapi {
|
||||
VkFormat normalFmt = VK_FORMAT_R8G8B8A8_UNORM;
|
||||
VkFormat diffuseFmt = VK_FORMAT_R8G8B8A8_UNORM;
|
||||
|
||||
int usage = 1;
|
||||
int usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||
auto positionArgs = Image::Make2DArgs(width, height, positionFmt, VK_SAMPLE_COUNT_1_BIT, usage | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE);
|
||||
auto normalArgs = Image::Make2DArgs(width, height, positionFmt, VK_SAMPLE_COUNT_1_BIT, usage | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE);
|
||||
auto diffuseArgs = Image::Make2DArgs(width, height, positionFmt, VK_SAMPLE_COUNT_1_BIT, usage | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE);
|
||||
for (int i = 0; i < frames; i++) {
|
||||
positions.push_back(new Image(device, "position", width , height, diffuseFmt, usage));
|
||||
normals.push_back(new Image(device, "normal", width, height, diffuseFmt, usage));
|
||||
diffuses.push_back(new Image(device, "diffuse", width, height, diffuseFmt, usage));
|
||||
string si = to_string(i);
|
||||
positions.push_back(new Image(device, "position" + si, positionArgs));
|
||||
normals.push_back(new Image(device, "normal" + si, normalArgs));
|
||||
diffuses.push_back(new Image(device, "diffuse" + si, diffuseArgs));
|
||||
}
|
||||
}
|
||||
GeometryBuffer::~GeometryBuffer()
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
#include "target.h"
|
||||
#include "../window.h"
|
||||
namespace vulkanapi {
|
||||
void RenderTarget::InitSurface(Device& device, string name)
|
||||
{
|
||||
|
||||
}
|
||||
RenderTarget* RenderTarget::MakeOutputTarget()
|
||||
{
|
||||
auto window = VulkanWindow::GetSingletonPtr();
|
||||
vector<Image*>& surfaces = window->GetSurface();
|
||||
uint32_t width, height;
|
||||
window->GetSize(width, height);
|
||||
return new RenderTarget(width, height, surfaces);
|
||||
}
|
||||
RenderTarget* RenderTarget::MakeDepthTarget()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
RenderTarget* RenderTarget::MakeColorTarget()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,25 @@
|
||||
#pragma once
|
||||
#include "../vulkan.h"
|
||||
#include "../wrapper/framebuffer.h"
|
||||
namespace vulkanapi {
|
||||
class Image;
|
||||
class Device;
|
||||
class RenderTarget {
|
||||
public:
|
||||
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t size;
|
||||
vector<FrameBuffer> frames;
|
||||
vector<Image*> surfaces;
|
||||
public:
|
||||
RenderTarget(uint32_t width, uint32_t height, uint32_t size)
|
||||
:width(width), height(height), size(size) {};
|
||||
RenderTarget(uint32_t width, uint32_t height, vector<Image*>& surfaces)
|
||||
:width(width), height(height), size(surfaces.size()), surfaces(surfaces){};
|
||||
void InitSurface(Device& device, string name);
|
||||
public:
|
||||
static RenderTarget* MakeOutputTarget();
|
||||
static RenderTarget* MakeDepthTarget();
|
||||
static RenderTarget* MakeColorTarget();
|
||||
};
|
||||
}
|
||||
@ -52,4 +52,9 @@ namespace vulkanapi {
|
||||
cmd.WaitFofFence(mDevice.Ptr());
|
||||
mCommandPool.Push(cmd);
|
||||
}
|
||||
bool CommandWorker::Present(VkPresentInfoKHR& presentInfo)
|
||||
{
|
||||
VkResult result = vkQueuePresentKHR(mQueue.Ptr(), &presentInfo);
|
||||
return result == VK_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,5 +25,6 @@ namespace vulkanapi {
|
||||
Buffer(mImmediateExeCmd, fn , callback);
|
||||
}
|
||||
void Draw(commandFn fn);
|
||||
bool Present(VkPresentInfoKHR& presentInfo);
|
||||
};
|
||||
};
|
||||
@ -10,6 +10,7 @@ namespace vulkanapi {
|
||||
#define Z_USE_GRAPHIC_DEBUG
|
||||
class CommandBuffer;
|
||||
using std::string;
|
||||
using std::to_string;
|
||||
using std::vector;
|
||||
using std::map;
|
||||
using voidFn = std::function<void()>;
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
#include "vulkan_context.h"
|
||||
#include "vulkanapi.h"
|
||||
namespace engineapi {
|
||||
namespace vulkanapi {
|
||||
void VulkanContext::UseContext()
|
||||
{
|
||||
Pass = API->VkPasses[PassId];
|
||||
|
||||
Pass = API.PassList[PassId];
|
||||
}
|
||||
}
|
||||
@ -1,11 +1,15 @@
|
||||
#pragma once
|
||||
#include "render/render_context.h"
|
||||
#include "vulkanapi.h"
|
||||
namespace engineapi {
|
||||
struct VulkanContext : public RenderContext {
|
||||
RenderVulkanAPI* API;
|
||||
vulkanapi::RenderPass* Pass;
|
||||
#include "wrapper/renderpass.h"
|
||||
namespace vulkanapi {
|
||||
class RenderVulkanAPI;
|
||||
class VulkanContext : public engineapi::RenderContext {
|
||||
public:
|
||||
RenderVulkanAPI& API;
|
||||
RenderPass* Pass{ nullptr };
|
||||
|
||||
public:
|
||||
VulkanContext(RenderVulkanAPI& API):API(API){};
|
||||
virtual void UseContext()override;
|
||||
};
|
||||
}
|
||||
@ -1,17 +1,20 @@
|
||||
#include "vulkanapi.h"
|
||||
#include "vulkanapi.h"
|
||||
#include "wrapper/queue.h"
|
||||
#include "wrapper/buffer.h"
|
||||
#include "wrapper/commandbuffer.h"
|
||||
#include "thread/worker.h"
|
||||
#include "render/asset/mesh.h"
|
||||
#include "object/camera/camera.h"
|
||||
#include "render/pass/renderpass.h"
|
||||
#include "render/node/rendernode.h"
|
||||
#include "pass/forwardpass.h"
|
||||
namespace engineapi {
|
||||
#include "pass/target.h"
|
||||
#include "wrapper/swapchain.h"
|
||||
#include "window.h"
|
||||
namespace vulkanapi {
|
||||
RenderVulkanAPI::RenderVulkanAPI()
|
||||
:backend("vulkan")
|
||||
,context(*this)
|
||||
{
|
||||
mContext = &context;
|
||||
Buffer::MakeVmaAllocator(backend);
|
||||
}
|
||||
RenderVulkanAPI::~RenderVulkanAPI()
|
||||
@ -24,12 +27,17 @@ namespace engineapi {
|
||||
}
|
||||
void RenderVulkanAPI::InitRenderPass()
|
||||
{
|
||||
VkPasses.resize(RenderPassType::ZX_RENDER_PASS_COUNT);
|
||||
swapchain = VulkanWindow::GetSingletonPtr()->GetSwapchain();
|
||||
RenderTarget* output = RenderTarget::MakeOutputTarget();
|
||||
TargetList.reserve(RENDER_COUNT);
|
||||
TargetList.push_back(output);
|
||||
PassList.resize(RENDER_COUNT);
|
||||
auto gbuffer = GeometryBuffer(backend.GetDevice(), 3, 640, 720);
|
||||
for (auto pass : mAllPasses) {
|
||||
auto type = pass->GetType();
|
||||
if (type == RenderPassType::ZX_RENDER_PASS_FORWARD_RENDERING) {
|
||||
VkPasses[type] = ForwardPass::MakePass(backend.GetDevice(), gbuffer);
|
||||
for (auto node : mAllNodes) {
|
||||
if (!node)continue;
|
||||
auto type = node->GetType();
|
||||
if (type == RENDER_FORWARD_RENDERING) {
|
||||
PassList[type] = ForwardPass::MakePass(backend.GetDevice(), gbuffer, output);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -42,26 +50,28 @@ namespace engineapi {
|
||||
}
|
||||
void RenderVulkanAPI::BeginFrame()
|
||||
{
|
||||
|
||||
mFrame = swapchain->Aquire();
|
||||
}
|
||||
void RenderVulkanAPI::EndFrame()
|
||||
{
|
||||
|
||||
swapchain->Present(mFrame);
|
||||
}
|
||||
void RenderVulkanAPI::SetStaticMesh(Mesh* mesh)
|
||||
{
|
||||
auto meshBuffer = GetNextVAO(mesh->VAO);
|
||||
meshBuffer->indexCount = mesh->mIndices.size();
|
||||
meshBuffer->vertexCount = mesh->mVertices.size();
|
||||
auto Indices = mesh->GetIndices();
|
||||
auto Vertices = mesh->GetVertices();
|
||||
auto meshBuffer = GetNextVAO(mesh->GetVAO());
|
||||
meshBuffer->indexCount = Indices.size();
|
||||
meshBuffer->vertexCount = Vertices.size();
|
||||
|
||||
// ----------------------------------------------- Vertex Buffer -----------------------------------------------
|
||||
VkDeviceSize vertexBufferSize = sizeof(Vertex) * mesh->mVertices.size();
|
||||
VkDeviceSize vertexBufferSize = sizeof(Vertex) * Vertices.size();
|
||||
VmaAllocationCreateInfo vertexVmaStagingInfo = {};
|
||||
VmaAllocation vertexVmaStagingAlloc;
|
||||
VkBuffer vertexStagingBuffer = Buffer::CreateStageBuffer(vertexVmaStagingInfo, vertexVmaStagingAlloc, vertexBufferSize);
|
||||
|
||||
// 拷贝数据到StagingBuffer
|
||||
Buffer::CopyData(vertexVmaStagingAlloc, mesh->mVertices.data(), vertexBufferSize);
|
||||
Buffer::CopyData(vertexVmaStagingAlloc, Vertices.data(), vertexBufferSize);
|
||||
|
||||
VkBufferUsageFlags vertexFlags = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;//加入光线追踪
|
||||
VmaAllocationCreateInfo vertexVmaCreateInfo = {};
|
||||
@ -69,12 +79,12 @@ namespace engineapi {
|
||||
meshBuffer->vertexBuffer = Buffer::CreateBuffer(vertexCreateInfo, vertexVmaCreateInfo, meshBuffer->vertexBufferAlloc);
|
||||
|
||||
// ----------------------------------------------- Index Buffer -----------------------------------------------
|
||||
VkDeviceSize indexBufferSize = sizeof(uint32_t) * mesh->mIndices.size();
|
||||
VkDeviceSize indexBufferSize = sizeof(uint32_t) * Indices.size();
|
||||
VmaAllocationCreateInfo indexVmaStagingInfo = {};
|
||||
VmaAllocation indexVmaStagingAlloc;
|
||||
VkBuffer indexStagingBuffer = Buffer::CreateStageBuffer(indexVmaStagingInfo, indexVmaStagingAlloc, vertexBufferSize);
|
||||
// 拷贝数据到StagingBuffer
|
||||
Buffer::CopyData(indexVmaStagingAlloc, mesh->mIndices.data(), indexBufferSize);
|
||||
Buffer::CopyData(indexVmaStagingAlloc, Indices.data(), indexBufferSize);
|
||||
|
||||
VmaAllocationCreateInfo indexVmaCreateInfo = {};
|
||||
VkBufferCreateInfo indexCreateInfo = Buffer::MakeDeviceInfo(indexVmaCreateInfo, indexBufferSize, VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
|
||||
@ -99,19 +109,18 @@ namespace engineapi {
|
||||
}
|
||||
void RenderVulkanAPI::DrawStaticMesh(Mesh* mesh)
|
||||
{
|
||||
|
||||
}
|
||||
void RenderVulkanAPI::DrawStaticMesh(Mesh* mesh)
|
||||
{
|
||||
auto vulkanVAO = VAOList[mesh->VAO];
|
||||
auto vulkanVAO = VAOList[mesh->GetVAO()];
|
||||
context.Pass->SetViewPort(mViewPortInfo.width, mViewPortInfo.height, mViewPortInfo.xOffset, mViewPortInfo.yOffset);
|
||||
Backend::RenderWorker->Draw([=](CommandBuffer& cmd) {
|
||||
VkCommandBuffer ptr = cmd.Ptr();
|
||||
context.Pass->BeginPass(cmd);
|
||||
context.Pass->BeginPass(cmd, mFrame);
|
||||
VkBuffer vertexBuffers[] = { vulkanVAO->vertexBuffer };
|
||||
VkDeviceSize offsets[] = { 0 };
|
||||
vkCmdBindVertexBuffers(ptr, 0, 1, vertexBuffers, offsets);
|
||||
vkCmdBindIndexBuffer(ptr, vulkanVAO->indexBuffer, 0, VK_INDEX_TYPE_UINT32);
|
||||
vkCmdDrawIndexed(ptr, vulkanVAO->indexCount, 1, 0, 0, 0);
|
||||
vkCmdBindPipeline(ptr, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->pipeline);
|
||||
vkCmdBindDescriptorSets(ptr, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->pipelineLayout, 0, 1, &materialData->descriptorSets[currentFrame], 0, VK_NULL_HANDLE);
|
||||
vkCmdDrawIndexed(ptr, vulkanVAO->indexCount, 1, 0, 0, 0);
|
||||
context.Pass->EndPass(cmd);
|
||||
});
|
||||
}
|
||||
|
||||
@ -2,21 +2,29 @@
|
||||
#include "backend.h"
|
||||
#include "wrapper/renderpass.h"
|
||||
#include "render/renderapi.h"
|
||||
#include "vulkan_context.h"
|
||||
#include "vulkan_struct.h"
|
||||
using namespace vulkanapi;
|
||||
namespace engineapi
|
||||
#include "vulkan_context.h"
|
||||
using namespace engineapi;
|
||||
namespace vulkanapi
|
||||
{
|
||||
class RenderTarget;
|
||||
class Swapchain;
|
||||
class RenderVulkanAPI : public RenderAPI
|
||||
{
|
||||
public:
|
||||
Backend backend;
|
||||
VulkanContext context;
|
||||
Swapchain* swapchain;
|
||||
vector<RenderTarget*> TargetList;
|
||||
vector<VulkanVAO*> VAOList;
|
||||
vector<vulkanapi::RenderPass*> VkPasses;
|
||||
vector<RenderPass*> PassList;
|
||||
public:
|
||||
RenderVulkanAPI();
|
||||
virtual ~RenderVulkanAPI()override;
|
||||
public:
|
||||
virtual RenderContext* GetContext() override {
|
||||
return &context;
|
||||
};
|
||||
public:
|
||||
virtual void SwitchContext()override;
|
||||
public:
|
||||
|
||||
@ -2,13 +2,11 @@
|
||||
#include "backend.h"
|
||||
#include "wrapper/instance.h"
|
||||
#include "wrapper/device.h"
|
||||
#include "wrapper/swapchain.h"
|
||||
#include "wrapper/swapchain_creator.h"
|
||||
#include "vulkanapi.h"
|
||||
#include "zlog.h"
|
||||
using engineapi::RenderVulkanAPI;
|
||||
namespace vulkanapi {
|
||||
Window::Window(int frames, uint32_t width, uint32_t height, const char* title)
|
||||
VulkanWindow::VulkanWindow(int frames, uint32_t width, uint32_t height, const char* title)
|
||||
:engineapi::Window(width, height , title)
|
||||
, mSurfaceKHR(nullptr)
|
||||
, mSwapchain(nullptr)
|
||||
|
||||
@ -1,13 +1,25 @@
|
||||
#pragma once
|
||||
#include "render/window.h"
|
||||
#include "wrapper/swapchain.h"
|
||||
#include "vulkan.h"
|
||||
namespace vulkanapi {
|
||||
class Swapchain;
|
||||
class Window : public engineapi::Window {
|
||||
class Image;
|
||||
class VulkanWindow : public engineapi::Window {
|
||||
protected:
|
||||
VkSurfaceKHR mSurfaceKHR;
|
||||
Swapchain* mSwapchain;
|
||||
public:
|
||||
Window(int frames, uint32_t width, uint32_t height, const char* title);
|
||||
VulkanWindow(int frames, uint32_t width, uint32_t height, const char* title);
|
||||
|
||||
vector<Image*>& GetSurface() {
|
||||
return mSwapchain->GetSurface();
|
||||
}
|
||||
Swapchain* GetSwapchain() {
|
||||
return mSwapchain;
|
||||
}
|
||||
public:
|
||||
static VulkanWindow* GetSingletonPtr() {
|
||||
return (VulkanWindow*)engineapi::Window::GetSingletonPtr();
|
||||
}
|
||||
};
|
||||
};
|
||||
@ -69,4 +69,10 @@ namespace vulkanapi {
|
||||
// 销毁StagingBuffer
|
||||
vmaDestroyBuffer(vmaAllocator, buffer, bufferAlloc);
|
||||
}
|
||||
void Buffer::CreateImage(VkImageCreateInfo& imageInfo, VkImage& ptr, VmaAllocation& allocation, VmaMemoryUsage usage)
|
||||
{
|
||||
VmaAllocationCreateInfo allocationInfo = {};
|
||||
allocationInfo.usage = usage;
|
||||
vmaCreateImage(vmaAllocator, &imageInfo, &allocationInfo, &ptr, &allocation, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,5 +16,6 @@ namespace vulkanapi {
|
||||
static VkBuffer CreateStageBuffer(VmaAllocationCreateInfo& allocationCreateInfo, VmaAllocation& allocation, VkDeviceSize vertexBufferSize);
|
||||
static void CopyData(VmaAllocation& allocation,void* data, VkDeviceSize size);
|
||||
static void DestroyBuffer(VkBuffer buffer, VmaAllocation bufferAlloc);
|
||||
static void CreateImage(VkImageCreateInfo& imageInfo, VkImage& ptr, VmaAllocation& allocation, VmaMemoryUsage usage);
|
||||
};
|
||||
}
|
||||
@ -70,5 +70,12 @@ namespace vulkanapi {
|
||||
VkResult result = vkCreateFence(mPtr, &fenceInfo, nullptr, &fence);
|
||||
return result == VK_SUCCESS;
|
||||
}
|
||||
bool Device::CreateSemaphore(VkSemaphore& semaphore)
|
||||
{
|
||||
VkSemaphoreCreateInfo semaphoreInfo = {};
|
||||
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||
VkResult result = vkCreateSemaphore(mPtr, &semaphoreInfo, nullptr, &semaphore);
|
||||
return result == VK_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -23,5 +23,6 @@ namespace vulkanapi {
|
||||
|
||||
Queue* GetQueue(const string& name);
|
||||
bool CreateFence(VkFence& fence);
|
||||
bool CreateSemaphore(VkSemaphore& semaphore);
|
||||
};
|
||||
};
|
||||
22
engine/src/engine/vulkanapi/wrapper/framebuffer.cpp
Normal file
22
engine/src/engine/vulkanapi/wrapper/framebuffer.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
#include "framebuffer.h"
|
||||
#include "device.h"
|
||||
#include "renderpass.h"
|
||||
#include "image.h"
|
||||
#include "../pass/target.h"
|
||||
namespace vulkanapi {
|
||||
FrameBuffer::FrameBuffer(Device& device, RenderTarget* target, RenderPass* pass, vector<VkImageView>& surfaces)
|
||||
: mSurfaces(surfaces)
|
||||
{
|
||||
uint32_t size = mSurfaces.size();
|
||||
VkFramebufferCreateInfo framebufferInfo{};
|
||||
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||
// 指定可以兼容的render pass(这个frame buffer和指定的render pass的attachment的数量和类型需要一致)
|
||||
framebufferInfo.renderPass = pass->Ptr();
|
||||
framebufferInfo.attachmentCount = size;
|
||||
framebufferInfo.pAttachments = mSurfaces.data();
|
||||
framebufferInfo.width = target->width;
|
||||
framebufferInfo.height = target->height;
|
||||
framebufferInfo.layers = 1;
|
||||
vkCreateFramebuffer(device.Ptr(), &framebufferInfo, nullptr, &mPtr);
|
||||
}
|
||||
}
|
||||
19
engine/src/engine/vulkanapi/wrapper/framebuffer.h
Normal file
19
engine/src/engine/vulkanapi/wrapper/framebuffer.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include "../vulkan.h"
|
||||
namespace vulkanapi {
|
||||
class Device;
|
||||
class RenderPass;
|
||||
class RenderTarget;
|
||||
class Image;
|
||||
class FrameBuffer {
|
||||
protected:
|
||||
VkFramebuffer mPtr;
|
||||
vector<VkImageView> mSurfaces;
|
||||
public:
|
||||
FrameBuffer(Device& device, RenderTarget* target,RenderPass* pass, vector<VkImageView>& surfaces);
|
||||
|
||||
VkFramebuffer& Ptr() {
|
||||
return mPtr;
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -1,28 +1,87 @@
|
||||
#include "image.h"
|
||||
#include "device.h"
|
||||
#include "buffer.h"
|
||||
namespace vulkanapi {
|
||||
Image::Image(const Device& device, const char* name, int width, int height, VkFormat format, VkImageUsageFlags usage)
|
||||
:Image(device, Args{
|
||||
1,
|
||||
"",
|
||||
width,height,
|
||||
1,1,1,
|
||||
format,usage,
|
||||
1,1,1,1 })
|
||||
{
|
||||
|
||||
}
|
||||
Image::Image(const Device& device, const Args& args)
|
||||
Image::Image(Device& device, string name, const Args& args)
|
||||
: mArgs(args)
|
||||
, mName(name)
|
||||
, mDevice(device)
|
||||
, mPtr(nullptr)
|
||||
{
|
||||
VkImageCreateInfo imageInfo{};
|
||||
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
imageInfo.imageType = mArgs.Type;
|
||||
imageInfo.extent.width = mArgs.Width;
|
||||
imageInfo.extent.height = mArgs.Height;
|
||||
// 纹理第三个维度的像素数量,如果不是3D纹理应该都是1
|
||||
imageInfo.extent.depth = 1;
|
||||
imageInfo.mipLevels = mArgs.Levels;
|
||||
imageInfo.arrayLayers = mArgs.Layers;
|
||||
imageInfo.format = mArgs.Format;
|
||||
// VK_IMAGE_TILING_LINEAR: texel以行为主序排列为数组
|
||||
// VK_IMAGE_TILING_OPTIMAL: texel按照Vulkan的具体实现来定义的一种顺序排列,以实现最佳访问
|
||||
// 这个和layout不一样,一旦设置之后是固定的不能改,如果CPU需要读取这个数据,就设置为VK_IMAGE_TILING_LINEAR
|
||||
// 如果只是GPU使用,就设置为VK_IMAGE_TILING_OPTIMAL性能更好
|
||||
imageInfo.tiling = mArgs.Tiling;
|
||||
// 这里只能填VK_IMAGE_LAYOUT_UNDEFINED或者VK_IMAGE_LAYOUT_PREINITIALIZED
|
||||
// VK_IMAGE_LAYOUT_UNDEFINED意味着第一次transition数据的时候数据会被丢弃
|
||||
// VK_IMAGE_LAYOUT_PREINITIALIZED是第一次transition数据的时候数据会被保留
|
||||
// 不是很懂这个什么意思,如果是一个用来从CPU写入数据,然后transfer到其它VkImage的stagingImage,就要用VK_IMAGE_LAYOUT_PREINITIALIZED
|
||||
imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
imageInfo.usage = mArgs.Usage;
|
||||
imageInfo.sharingMode = mArgs.Sharing;
|
||||
imageInfo.samples = mArgs.Samples;
|
||||
// 这个只影响当作attachments使用的VkImage(自己创建的frame buffer才支持这个,交换链用的那个默认buffer不支持)
|
||||
imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
|
||||
Buffer::CreateImage(imageInfo, mPtr, mAllocation, mArgs.Memory);
|
||||
}
|
||||
Image::Image(const Device& device, VkImage ptr, const Args& args)
|
||||
Image::Image(Device& device, string name, VkImage ptr, const Args& args)
|
||||
: mArgs(args)
|
||||
, mName(name)
|
||||
, mDevice(device)
|
||||
, mPtr(ptr)
|
||||
{
|
||||
|
||||
}
|
||||
VkImageView Image::View(VkFormat format, VkImageAspectFlags aspectFlags, VkImageViewType viewType)
|
||||
{
|
||||
VkImageViewCreateInfo createInfo = {};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
createInfo.image = mPtr;
|
||||
createInfo.viewType = viewType;
|
||||
createInfo.format = format;
|
||||
|
||||
// components字段允许调整颜色通道的最终的映射逻辑
|
||||
// 比如,我们可以将所有颜色通道映射为红色通道,以实现单色纹理,我们也可以将通道映射具体的常量数值0和1
|
||||
// 这里用默认的
|
||||
createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
createInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
|
||||
// subresourceRangle字段用于描述图像的使用目标是什么,以及可以被访问的有效区域
|
||||
// 这个图像用作填充color还是depth stencil等
|
||||
createInfo.subresourceRange.aspectMask = aspectFlags;
|
||||
// 默认处理所有Mipmap
|
||||
createInfo.subresourceRange.baseMipLevel = 0;
|
||||
createInfo.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
|
||||
// 默认处理所有Layers
|
||||
createInfo.subresourceRange.baseArrayLayer = 0;
|
||||
createInfo.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
|
||||
|
||||
VkImageView imageView;
|
||||
vkCreateImageView(mDevice.Ptr(), &createInfo, nullptr, &imageView);
|
||||
return imageView;
|
||||
}
|
||||
Image::Args Image::Make2DArgs(uint32_t width, uint32_t height, VkFormat format, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VmaMemoryUsage memory)
|
||||
{
|
||||
return Args{
|
||||
VK_IMAGE_TYPE_2D,
|
||||
width,height,
|
||||
1,1,1,
|
||||
format,usage,
|
||||
VK_IMAGE_TILING_LINEAR,VK_SHARING_MODE_EXCLUSIVE,
|
||||
samples,1,memory };
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,35 +1,47 @@
|
||||
#pragma once
|
||||
#include "../vulkan.h"
|
||||
#include "vk_mem_alloc.h"
|
||||
namespace vulkanapi {
|
||||
class Device;
|
||||
class Image {
|
||||
public:
|
||||
struct Args {
|
||||
int Type;
|
||||
const char* Key;
|
||||
int Width;
|
||||
int Height;
|
||||
int Depth;
|
||||
int Layers;
|
||||
int Levels;
|
||||
VkImageType Type;
|
||||
uint32_t Width;
|
||||
uint32_t Height;
|
||||
uint32_t Depth;
|
||||
uint32_t Layers;
|
||||
uint32_t Levels;
|
||||
VkFormat Format;
|
||||
VkImageUsageFlags Usage;
|
||||
int Tiling;
|
||||
int Sharing;
|
||||
VkImageTiling Tiling;
|
||||
VkSharingMode Sharing;
|
||||
VkSampleCountFlagBits Samples;
|
||||
int Layout;
|
||||
int Memory;
|
||||
VmaMemoryUsage Memory;
|
||||
};
|
||||
protected:
|
||||
string mName;
|
||||
VkImage mPtr;
|
||||
Args mArgs;
|
||||
const Device& mDevice;
|
||||
VmaAllocation mAllocation{nullptr};
|
||||
Device& mDevice;
|
||||
public:
|
||||
Image(const Device& device, const char* name, int width, int height, VkFormat format, VkImageUsageFlags usage);
|
||||
Image(const Device& device, const Args& args);
|
||||
Image(const Device& device, VkImage ptr, const Args& args);
|
||||
Image(Device& device, string name, const Args& args);
|
||||
Image(Device& device, string name, VkImage ptr, const Args& args);
|
||||
|
||||
VkFormat Format() {
|
||||
return mArgs.Format;
|
||||
};
|
||||
};
|
||||
VkImage& Ptr() {
|
||||
return mPtr;
|
||||
}
|
||||
VkImageView View(VkImageAspectFlags aspectFlags, VkImageViewType viewType) {
|
||||
return View(mArgs.Format, aspectFlags, viewType);
|
||||
};
|
||||
VkImageView View(VkFormat format, VkImageAspectFlags aspectFlags, VkImageViewType viewType);
|
||||
|
||||
public:
|
||||
static Args Make2DArgs(uint32_t width, uint32_t height, VkFormat format, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VmaMemoryUsage memory);
|
||||
};
|
||||
}
|
||||
@ -1,11 +1,14 @@
|
||||
#include "renderpass.h"
|
||||
#include "device.h"
|
||||
#include "commandbuffer.h"
|
||||
#include "../pass/target.h"
|
||||
#include "framebuffer.h"
|
||||
namespace vulkanapi {
|
||||
RenderPass::RenderPass(Device& device, const char* name,
|
||||
vector<VkAttachmentDescription>& attachments,
|
||||
vector<VkSubpassDescription>& subpasses,
|
||||
vector<VkSubpassDependency>& dependencies)
|
||||
:mAttachments(attachments)
|
||||
{
|
||||
//pAttachments
|
||||
VkRenderPassCreateInfo create_info{
|
||||
@ -24,8 +27,9 @@ namespace vulkanapi {
|
||||
mPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||
mPassBeginInfo.renderPass = mPtr;
|
||||
}
|
||||
void RenderPass::BeginPass(CommandBuffer& cmd)
|
||||
void RenderPass::BeginPass(CommandBuffer& cmd,int frame)
|
||||
{
|
||||
mPassBeginInfo.framebuffer = mTarget->frames.at(frame).Ptr();
|
||||
vkCmdBeginRenderPass(cmd.Ptr(), &mPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||
}
|
||||
void RenderPass::EndPass(CommandBuffer& cmd)
|
||||
|
||||
@ -5,21 +5,24 @@
|
||||
namespace vulkanapi {
|
||||
class Device;
|
||||
class CommandBuffer;
|
||||
class RenderTarget;
|
||||
class RenderPass {
|
||||
protected:
|
||||
VkRenderPass mPtr;
|
||||
RenderTarget* mTarget;
|
||||
VkRenderPassBeginInfo mPassBeginInfo{};
|
||||
|
||||
vector<VkAttachmentDescription> mAttachments;
|
||||
public:
|
||||
RenderPass(Device& device, const char* name,
|
||||
vector<VkAttachmentDescription>& attachments,
|
||||
vector<VkSubpassDescription>& subpasses,
|
||||
vector<VkSubpassDependency>& dependencies);
|
||||
|
||||
VkRenderPass& Ptr() {
|
||||
return mPtr;
|
||||
}
|
||||
public:
|
||||
void BeginPass(CommandBuffer& cmd);
|
||||
void BeginPass(CommandBuffer& cmd, int frame);
|
||||
void EndPass(CommandBuffer& cmd);
|
||||
|
||||
public:
|
||||
void SetViewPort(uint32_t width, uint32_t height, int32_t xoffset, int32_t yoffset);
|
||||
};
|
||||
|
||||
@ -2,10 +2,13 @@
|
||||
#include "swapchain_creator.h"
|
||||
#include "device.h"
|
||||
#include "image.h"
|
||||
#include "../backend.h"
|
||||
#include "../thread/worker.h"
|
||||
#include "zlog.h"
|
||||
namespace vulkanapi {
|
||||
Swapchain::Swapchain(SwapchainCreator& Creator)
|
||||
: mPtr(nullptr)
|
||||
, mDevice(Creator.device)
|
||||
{
|
||||
VkSurfaceCapabilitiesKHR capabilities{};
|
||||
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(Creator.device.GetPhysical(), Creator.presentation_surface, &capabilities);
|
||||
@ -36,15 +39,31 @@ namespace vulkanapi {
|
||||
}
|
||||
vector<VkImage> swapchain_images;
|
||||
Creator.CreateSwapchainImages(mPtr, swapchain_images);
|
||||
uint32_t image_count = swapchain_images.size();
|
||||
for (auto img : swapchain_images) {
|
||||
mImages.push_back(new Image(Creator.device, img, Image::Args{
|
||||
1,
|
||||
"",
|
||||
(int)Creator.width, (int)Creator.height,
|
||||
1, 1, 1,
|
||||
Creator.imageFormat, Creator.imageUsage,
|
||||
1, 1, 1, 1}));
|
||||
auto args = Image::Make2DArgs(Creator.width, Creator.height, Creator.imageFormat, VK_SAMPLE_COUNT_8_BIT, Creator.imageUsage, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE);
|
||||
args.Sharing = VK_SHARING_MODE_CONCURRENT;
|
||||
for (int i = 0; i < Creator.frames;i++) {
|
||||
mSurfaces.push_back(new Image(Creator.device,"swapchain" + to_string(i), swapchain_images[i], args));
|
||||
}
|
||||
Creator.device.CreateSemaphore(mSemaphore);
|
||||
}
|
||||
uint32_t Swapchain::Aquire()
|
||||
{
|
||||
uint32_t curPresentImageIdx;
|
||||
VkResult result = vkAcquireNextImageKHR(mDevice.Ptr(), mPtr, UINT64_MAX, mSemaphore, VK_NULL_HANDLE, &curPresentImageIdx);
|
||||
return curPresentImageIdx;
|
||||
}
|
||||
void Swapchain::Present(uint32_t frame)
|
||||
{
|
||||
VkSwapchainKHR swapChains[] = { mPtr };
|
||||
VkSemaphore waitSemaphores[] = { mSemaphore };
|
||||
VkPresentInfoKHR presentInfo = {};
|
||||
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||
presentInfo.pWaitSemaphores = waitSemaphores;
|
||||
presentInfo.waitSemaphoreCount = 1;
|
||||
presentInfo.pSwapchains = swapChains;
|
||||
presentInfo.swapchainCount = 1;
|
||||
presentInfo.pImageIndices = &frame;
|
||||
presentInfo.pResults = VK_NULL_HANDLE;
|
||||
Backend::PresentWorker->Present(presentInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,12 +4,20 @@
|
||||
namespace vulkanapi {
|
||||
class Image;
|
||||
class SwapchainCreator;
|
||||
class Device;
|
||||
class Swapchain {
|
||||
friend class SwapchainCreator;
|
||||
protected:
|
||||
VkSwapchainKHR mPtr;
|
||||
vector<Image*> mImages;
|
||||
Device& mDevice;
|
||||
vector<Image*> mSurfaces;
|
||||
VkSemaphore mSemaphore;
|
||||
public:
|
||||
Swapchain(SwapchainCreator& Creator);
|
||||
uint32_t Aquire();
|
||||
void Present(uint32_t frame);
|
||||
vector<Image*>& GetSurface(){
|
||||
return mSurfaces;
|
||||
}
|
||||
};
|
||||
};
|
||||
@ -9,10 +9,10 @@ namespace vulkanapi {
|
||||
, frames(frames)
|
||||
, width(width)
|
||||
, height(height)
|
||||
, imageFormat(VkFormat::VK_FORMAT_B8G8R8A8_SRGB)
|
||||
, imageColorSpace(VkColorSpaceKHR::VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
|
||||
, presentMode(VkPresentModeKHR::VK_PRESENT_MODE_MAILBOX_KHR)
|
||||
, imageUsage(VkImageUsageFlagBits::VK_IMAGE_USAGE_TRANSFER_DST_BIT)
|
||||
, imageFormat(VK_FORMAT_B8G8R8A8_SRGB)
|
||||
, imageColorSpace(VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
|
||||
, presentMode(VK_PRESENT_MODE_MAILBOX_KHR)
|
||||
, imageUsage(VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT)
|
||||
, maxFrameInFlightCount(2)
|
||||
{
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user