mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-15 00:16:48 +00:00
208 lines
No EOL
6.1 KiB
C++
208 lines
No EOL
6.1 KiB
C++
#pragma once
|
|
|
|
#include <deko3d.hpp>
|
|
#include <map>
|
|
#include <memory>
|
|
#include <vector>
|
|
#include <optional>
|
|
|
|
#include "framework/CDescriptorSet.h"
|
|
#include "framework/CMemPool.h"
|
|
#include "framework/CShader.h"
|
|
#include "framework/CCmdMemRing.h"
|
|
#include "nanovg.h"
|
|
|
|
// Create flags
|
|
enum NVGcreateFlags {
|
|
// Flag indicating if geometry based anti-aliasing is used (may not be needed when using MSAA).
|
|
NVG_ANTIALIAS = 1<<0,
|
|
// Flag indicating if strokes should be drawn using stencil buffer. The rendering will be a little
|
|
// slower, but path overlaps (i.e. self-intersecting or sharp turns) will be drawn just once.
|
|
NVG_STENCIL_STROKES = 1<<1,
|
|
// Flag indicating that additional debug checks are done.
|
|
NVG_DEBUG = 1<<2,
|
|
};
|
|
|
|
enum DKNVGuniformLoc
|
|
{
|
|
DKNVG_LOC_VIEWSIZE,
|
|
DKNVG_LOC_TEX,
|
|
DKNVG_LOC_FRAG,
|
|
DKNVG_MAX_LOCS
|
|
};
|
|
|
|
enum VKNVGshaderType {
|
|
NSVG_SHADER_FILLGRAD,
|
|
NSVG_SHADER_FILLIMG,
|
|
NSVG_SHADER_SIMPLE,
|
|
NSVG_SHADER_IMG
|
|
};
|
|
|
|
struct DKNVGtextureDescriptor {
|
|
int width, height;
|
|
int type;
|
|
int flags;
|
|
};
|
|
|
|
struct DKNVGblend {
|
|
int srcRGB;
|
|
int dstRGB;
|
|
int srcAlpha;
|
|
int dstAlpha;
|
|
};
|
|
|
|
enum DKNVGcallType {
|
|
DKNVG_NONE = 0,
|
|
DKNVG_FILL,
|
|
DKNVG_CONVEXFILL,
|
|
DKNVG_STROKE,
|
|
DKNVG_TRIANGLES,
|
|
};
|
|
|
|
struct DKNVGcall {
|
|
int type;
|
|
int image;
|
|
int pathOffset;
|
|
int pathCount;
|
|
int triangleOffset;
|
|
int triangleCount;
|
|
int uniformOffset;
|
|
DKNVGblend blendFunc;
|
|
};
|
|
|
|
struct DKNVGpath {
|
|
int fillOffset;
|
|
int fillCount;
|
|
int strokeOffset;
|
|
int strokeCount;
|
|
};
|
|
|
|
struct DKNVGfragUniforms {
|
|
float scissorMat[12]; // matrices are actually 3 vec4s
|
|
float paintMat[12];
|
|
struct NVGcolor innerCol;
|
|
struct NVGcolor outerCol;
|
|
float scissorExt[2];
|
|
float scissorScale[2];
|
|
float extent[2];
|
|
float radius;
|
|
float feather;
|
|
float strokeMult;
|
|
float strokeThr;
|
|
int texType;
|
|
int type;
|
|
};
|
|
|
|
namespace nvg {
|
|
class DkRenderer;
|
|
}
|
|
|
|
struct DKNVGcontext {
|
|
nvg::DkRenderer *renderer;
|
|
float view[2];
|
|
int fragSize;
|
|
int flags;
|
|
// Per frame buffers
|
|
DKNVGcall* calls;
|
|
int ccalls;
|
|
int ncalls;
|
|
DKNVGpath* paths;
|
|
int cpaths;
|
|
int npaths;
|
|
struct NVGvertex* verts;
|
|
int cverts;
|
|
int nverts;
|
|
unsigned char* uniforms;
|
|
int cuniforms;
|
|
int nuniforms;
|
|
};
|
|
|
|
namespace nvg {
|
|
|
|
class Texture {
|
|
private:
|
|
const int m_id;
|
|
dk::Image m_image;
|
|
dk::ImageDescriptor m_image_descriptor;
|
|
CMemPool::Handle m_image_mem;
|
|
DKNVGtextureDescriptor m_texture_descriptor;
|
|
public:
|
|
Texture(int id);
|
|
~Texture();
|
|
|
|
void Initialize(CMemPool &image_pool, CMemPool &scratch_pool, dk::Device device, dk::Queue transfer_queue, int type, int w, int h, int image_flags, const u8 *data);
|
|
void Update(CMemPool &image_pool, CMemPool &scratch_pool, dk::Device device, dk::Queue transfer_queue, int type, int w, int h, int image_flags, const u8 *data);
|
|
|
|
int GetId();
|
|
const DKNVGtextureDescriptor &GetDescriptor();
|
|
|
|
dk::Image &GetImage();
|
|
dk::ImageDescriptor &GetImageDescriptor();
|
|
};
|
|
|
|
class DkRenderer {
|
|
private:
|
|
enum SamplerType : u8 {
|
|
SamplerType_MipFilter = 1 << 0,
|
|
SamplerType_Nearest = 1 << 1,
|
|
SamplerType_RepeatX = 1 << 2,
|
|
SamplerType_RepeatY = 1 << 3,
|
|
SamplerType_Total = 0x10,
|
|
};
|
|
private:
|
|
static constexpr size_t DynamicCmdSize = 0x20000;
|
|
static constexpr size_t FragmentUniformSize = sizeof(DKNVGfragUniforms) + 4 - sizeof(DKNVGfragUniforms) % 4;
|
|
static constexpr size_t MaxImages = 0x1000;
|
|
|
|
/* From the application. */
|
|
u32 m_view_width;
|
|
u32 m_view_height;
|
|
dk::Device m_device;
|
|
dk::Queue m_queue;
|
|
CMemPool &m_image_mem_pool;
|
|
CMemPool &m_code_mem_pool;
|
|
CMemPool &m_data_mem_pool;
|
|
|
|
/* State. */
|
|
dk::UniqueCmdBuf m_dyn_cmd_buf;
|
|
CCmdMemRing<1> m_dyn_cmd_mem;
|
|
std::optional<CMemPool::Handle> m_vertex_buffer;
|
|
CShader m_vertex_shader;
|
|
CShader m_fragment_shader;
|
|
CMemPool::Handle m_view_uniform_buffer;
|
|
CMemPool::Handle m_frag_uniform_buffer;
|
|
|
|
u32 m_next_texture_id = 1;
|
|
std::vector<std::shared_ptr<Texture>> m_textures;
|
|
CDescriptorSet<MaxImages> m_image_descriptor_set;
|
|
CDescriptorSet<SamplerType_Total> m_sampler_descriptor_set;
|
|
std::array<int, MaxImages> m_image_descriptor_mappings;
|
|
int m_last_image_descriptor = 0;
|
|
|
|
int AcquireImageDescriptor(std::shared_ptr<Texture> texture, int image);
|
|
void FreeImageDescriptor(int image);
|
|
void SetUniforms(const DKNVGcontext &ctx, int offset, int image);
|
|
|
|
void UpdateVertexBuffer(const void *data, size_t size);
|
|
|
|
void DrawFill(const DKNVGcontext &ctx, const DKNVGcall &call);
|
|
void DrawConvexFill(const DKNVGcontext &ctx, const DKNVGcall &call);
|
|
void DrawStroke(const DKNVGcontext &ctx, const DKNVGcall &call);
|
|
void DrawTriangles(const DKNVGcontext &ctx, const DKNVGcall &call);
|
|
|
|
std::shared_ptr<Texture> FindTexture(int id);
|
|
public:
|
|
DkRenderer(unsigned int view_width, unsigned int view_height, dk::Device device, dk::Queue queue, CMemPool &image_mem_pool, CMemPool &code_mem_pool, CMemPool &data_mem_pool);
|
|
~DkRenderer();
|
|
|
|
int Create(DKNVGcontext &ctx);
|
|
int CreateTexture(const DKNVGcontext &ctx, int type, int w, int h, int image_flags, const u8 *data);
|
|
int DeleteTexture(const DKNVGcontext &ctx, int id);
|
|
int UpdateTexture(const DKNVGcontext &ctx, int id, int x, int y, int w, int h, const u8 *data);
|
|
int GetTextureSize(const DKNVGcontext &ctx, int id, int *w, int *h);
|
|
const DKNVGtextureDescriptor *GetTextureDescriptor(const DKNVGcontext &ctx, int id);
|
|
|
|
void Flush(DKNVGcontext &ctx);
|
|
};
|
|
|
|
} |