mirror of https://github.com/axmolengine/axmol.git
305 lines
8.2 KiB
C++
305 lines
8.2 KiB
C++
|
|
#pragma once
|
|
|
|
#include "LLGI.Base.h"
|
|
#include "Utils/LLGI.FixedSizeVector.h"
|
|
#include <functional>
|
|
#include <unordered_map>
|
|
|
|
namespace LLGI
|
|
{
|
|
class CommandListPool;
|
|
|
|
struct TextureParameter
|
|
{
|
|
TextureUsageType Usage = TextureUsageType::NoneFlag;
|
|
TextureFormatType Format = TextureFormatType::R8G8B8A8_UNORM;
|
|
int32_t Dimension = 2;
|
|
Vec3I Size = Vec3I{1, 1, 1};
|
|
int32_t MipLevelCount = 1;
|
|
int SampleCount = 1;
|
|
};
|
|
|
|
struct TextureInitializationParameter
|
|
{
|
|
Vec2I Size;
|
|
TextureFormatType Format = TextureFormatType::R8G8B8A8_UNORM;
|
|
int MipMapCount = 1;
|
|
};
|
|
|
|
struct RenderTextureInitializationParameter
|
|
{
|
|
Vec2I Size;
|
|
TextureFormatType Format = TextureFormatType::R8G8B8A8_UNORM;
|
|
int32_t SamplingCount = 1;
|
|
};
|
|
|
|
enum class DepthTextureMode
|
|
{
|
|
Depth,
|
|
DepthStencil,
|
|
};
|
|
|
|
struct DepthTextureInitializationParameter
|
|
{
|
|
Vec2I Size;
|
|
int32_t SamplingCount = 1;
|
|
DepthTextureMode Mode = DepthTextureMode::Depth;
|
|
};
|
|
|
|
/**
|
|
@brief provide a memory which is available in one frame
|
|
*/
|
|
class SingleFrameMemoryPool : public ReferenceObject
|
|
{
|
|
protected:
|
|
int32_t currentSwapBuffer_ = -1;
|
|
int32_t swapBufferCount_ = 0;
|
|
std::vector<int32_t> offsets_;
|
|
std::vector<std::vector<Buffer*>> buffers_;
|
|
|
|
/**
|
|
@brief create buffer
|
|
*/
|
|
virtual Buffer* CreateBufferInternal(int32_t size) { return nullptr; }
|
|
|
|
/**
|
|
@brief reinitialize buffer with a size
|
|
*/
|
|
virtual Buffer* ReinitializeBuffer(Buffer* cb, int32_t size) { return nullptr; }
|
|
|
|
public:
|
|
SingleFrameMemoryPool(int32_t swapBufferCount = 3);
|
|
~SingleFrameMemoryPool() override;
|
|
|
|
/**
|
|
@brief Start new frame
|
|
*/
|
|
virtual void NewFrame();
|
|
|
|
virtual Buffer* CreateConstantBuffer(int32_t size);
|
|
};
|
|
|
|
struct RenderPassPipelineStateKey
|
|
{
|
|
bool IsPresent = false;
|
|
TextureFormatType DepthFormat = TextureFormatType::Unknown;
|
|
FixedSizeVector<TextureFormatType, RenderTargetMax> RenderTargetFormats;
|
|
bool IsColorCleared = true;
|
|
bool IsDepthCleared = true;
|
|
bool HasResolvedRenderTarget = false;
|
|
bool HasResolvedDepthTarget = false;
|
|
int32_t SamplingCount = 1;
|
|
|
|
bool operator==(const RenderPassPipelineStateKey& value) const
|
|
{
|
|
if (RenderTargetFormats.size() != value.RenderTargetFormats.size())
|
|
return false;
|
|
|
|
for (size_t i = 0; i < RenderTargetFormats.size(); i++)
|
|
{
|
|
if (RenderTargetFormats.at(i) != value.RenderTargetFormats.at(i))
|
|
return false;
|
|
}
|
|
|
|
return (IsPresent == value.IsPresent && DepthFormat == value.DepthFormat && IsColorCleared == value.IsColorCleared &&
|
|
IsDepthCleared == value.IsDepthCleared && SamplingCount == value.SamplingCount &&
|
|
HasResolvedRenderTarget == value.HasResolvedRenderTarget && HasResolvedDepthTarget == value.HasResolvedDepthTarget);
|
|
}
|
|
|
|
struct Hash
|
|
{
|
|
typedef std::size_t result_type;
|
|
|
|
std::size_t operator()(const RenderPassPipelineStateKey& key) const
|
|
{
|
|
auto ret = std::hash<bool>()(key.IsPresent);
|
|
ret += std::hash<TextureFormatType>()(key.DepthFormat);
|
|
ret += std::hash<bool>()(key.IsColorCleared);
|
|
ret += std::hash<bool>()(key.IsDepthCleared);
|
|
ret += std::hash<int32_t>()(key.SamplingCount);
|
|
ret += std::hash<bool>()(key.HasResolvedRenderTarget);
|
|
ret += std::hash<bool>()(key.HasResolvedDepthTarget);
|
|
|
|
for (size_t i = 0; i < key.RenderTargetFormats.size(); i++)
|
|
{
|
|
ret += std::hash<uint64_t>()(static_cast<uint64_t>(key.RenderTargetFormats.at(i)));
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
};
|
|
};
|
|
|
|
class RenderPass : public ReferenceObject
|
|
{
|
|
private:
|
|
bool isColorCleared_ = false;
|
|
|
|
bool isDepthCleared_ = false;
|
|
|
|
Color8 color_;
|
|
|
|
FixedSizeVector<Texture*, RenderTargetMax> renderTextures_;
|
|
Texture* depthTexture_ = nullptr;
|
|
Texture* resolvedRenderTexture_ = nullptr;
|
|
Texture* resolvedDepthTexture_ = nullptr;
|
|
|
|
protected:
|
|
Vec2I screenSize_;
|
|
|
|
bool assignRenderTextures(Texture** textures, int32_t count);
|
|
bool assignDepthTexture(Texture* depthTexture);
|
|
bool assignResolvedRenderTexture(Texture* texture);
|
|
bool assignResolvedDepthTexture(Texture* texture);
|
|
|
|
bool getSize(Vec2I& size,
|
|
const Texture** textures,
|
|
int32_t textureCount,
|
|
Texture* depthTexture,
|
|
Texture* resolvedRenderTexture = nullptr,
|
|
Texture* resolvedDepthTexture = nullptr) const;
|
|
bool sanitize();
|
|
|
|
public:
|
|
RenderPass() = default;
|
|
~RenderPass() override;
|
|
|
|
virtual bool GetIsColorCleared() const { return isColorCleared_; }
|
|
|
|
virtual bool GetIsDepthCleared() const { return isDepthCleared_; }
|
|
|
|
virtual Color8 GetClearColor() const { return color_; }
|
|
|
|
virtual void SetIsColorCleared(bool isColorCleared);
|
|
|
|
virtual void SetIsDepthCleared(bool isDepthCleared);
|
|
|
|
virtual void SetClearColor(const Color8& color);
|
|
|
|
virtual Texture* GetRenderTexture(int index) const { return renderTextures_.at(index); }
|
|
|
|
virtual int GetRenderTextureCount() const { return static_cast<int32_t>(renderTextures_.size()); }
|
|
|
|
Texture* GetDepthTexture() const { return depthTexture_; }
|
|
|
|
bool GetHasDepthTexture() const { return GetDepthTexture() != nullptr; }
|
|
|
|
Texture* GetResolvedRenderTexture() const { return resolvedRenderTexture_; }
|
|
|
|
Texture* GetResolvedDepthTexture() const { return resolvedDepthTexture_; }
|
|
|
|
virtual bool GetIsSwapchainScreen() const;
|
|
|
|
virtual Vec2I GetScreenSize() const { return screenSize_; }
|
|
|
|
RenderPassPipelineStateKey GetKey() const;
|
|
};
|
|
|
|
/**
|
|
@brief A class to send a data for RenderPass
|
|
*/
|
|
class RenderPassPipelineState : public ReferenceObject
|
|
{
|
|
private:
|
|
public:
|
|
RenderPassPipelineState() = default;
|
|
~RenderPassPipelineState() override = default;
|
|
RenderPassPipelineStateKey Key;
|
|
};
|
|
|
|
/**
|
|
@note
|
|
please call WaitFinish before releasing
|
|
*/
|
|
class Graphics : public ReferenceObject
|
|
{
|
|
protected:
|
|
Vec2I windowSize_;
|
|
std::function<void()> disposed_;
|
|
|
|
public:
|
|
Graphics() = default;
|
|
~Graphics() override;
|
|
|
|
/*[[deprecated("use Platform::SetWindowSize.")]]*/ virtual void SetWindowSize(const Vec2I& windowSize);
|
|
|
|
/**
|
|
@brief Execute commands
|
|
@note
|
|
Don't release before finish executing commands.
|
|
*/
|
|
virtual void Execute(CommandList* commandList);
|
|
|
|
/**
|
|
@brief to prevent instances to be disposed before finish rendering, finish all renderings.
|
|
*/
|
|
virtual void WaitFinish() {}
|
|
|
|
virtual Buffer* CreateBuffer(BufferUsageType usage ,int32_t size);
|
|
|
|
virtual Shader* CreateShader(DataStructure* data, int32_t count);
|
|
virtual PipelineState* CreatePiplineState();
|
|
|
|
/**
|
|
@brief create a memory pool
|
|
@param drawingCount(drawingCount is ignored in DirectX12)
|
|
*/
|
|
virtual SingleFrameMemoryPool* CreateSingleFrameMemoryPool(int32_t constantBufferPoolSize, int32_t drawingCount);
|
|
|
|
/**
|
|
@brief
|
|
@param memoryPool if memory pool is null, allocate memory from graphics
|
|
*/
|
|
virtual CommandList* CreateCommandList(SingleFrameMemoryPool* memoryPool);
|
|
|
|
virtual RenderPass* CreateRenderPass(Texture** textures, int32_t textureCount, Texture* depthTexture) { return nullptr; }
|
|
|
|
virtual RenderPass* CreateRenderPass(Texture* texture, Texture* resolvedTexture, Texture* depthTexture, Texture* resolvedDepthTexture)
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
virtual Texture* CreateTexture(const TextureParameter& parameter) { return nullptr; }
|
|
|
|
virtual Texture* CreateTexture(const TextureInitializationParameter& parameter) { return nullptr; }
|
|
|
|
virtual Texture* CreateRenderTexture(const RenderTextureInitializationParameter& parameter) { return nullptr; }
|
|
|
|
virtual Texture* CreateDepthTexture(const DepthTextureInitializationParameter& parameter) { return nullptr; }
|
|
|
|
/**
|
|
@brief create texture from pointer or id in current platform
|
|
*/
|
|
virtual Texture* CreateTexture(uint64_t id);
|
|
|
|
/**
|
|
@brief create a RenderPassPipelineState
|
|
@note
|
|
This is a function to create an object.
|
|
But it is very fast. So it can call it in everyframe.
|
|
*/
|
|
virtual RenderPassPipelineState* CreateRenderPassPipelineState(RenderPass* renderPass);
|
|
|
|
/**
|
|
@brief create a RenderPassPipelineState
|
|
@note
|
|
This is a function to create an object.
|
|
But it is very fast. So it can call it in everyframe.
|
|
*/
|
|
virtual RenderPassPipelineState* CreateRenderPassPipelineState(const RenderPassPipelineStateKey& key) { return nullptr; }
|
|
|
|
/** For testing. Wait for all commands in queue to complete. Then read data from specified render target. */
|
|
virtual std::vector<uint8_t> CaptureRenderTarget(Texture* renderTarget);
|
|
|
|
/**
|
|
@brief specify a function which is called when this instance is disposed.
|
|
@param disposed called function
|
|
*/
|
|
void SetDisposed(const std::function<void()>& disposed);
|
|
|
|
virtual bool IsResolvedDepthSupported() const { return false; }
|
|
};
|
|
|
|
} // namespace LLGI
|