mirror of https://github.com/AxioDL/boo.git
OpenGL and metal rendering interface upgrades
This commit is contained in:
parent
73891af56a
commit
05c26a535b
|
@ -31,7 +31,8 @@ public:
|
||||||
ComPtr<ID3DBlob>* vertBlobOut, ComPtr<ID3DBlob>* fragBlobOut,
|
ComPtr<ID3DBlob>* vertBlobOut, ComPtr<ID3DBlob>* fragBlobOut,
|
||||||
ComPtr<ID3DBlob>* pipelineBlob, IVertexFormat* vtxFmt,
|
ComPtr<ID3DBlob>* pipelineBlob, IVertexFormat* vtxFmt,
|
||||||
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
||||||
bool depthTest, bool depthWrite, CullMode culling)=0;
|
ZTest depthTest, bool depthWrite, bool colorWrite,
|
||||||
|
bool alphaWrite, CullMode culling)=0;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ public:
|
||||||
TextureFormat fmt, const void* data, size_t sz);
|
TextureFormat fmt, const void* data, size_t sz);
|
||||||
ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt);
|
ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt);
|
||||||
ITextureR* newRenderTexture(size_t width, size_t height,
|
ITextureR* newRenderTexture(size_t width, size_t height,
|
||||||
bool enableShaderColorBinding, bool enableShaderDepthBinding);
|
size_t colorBindingCount, size_t depthBindingCount);
|
||||||
|
|
||||||
bool bindingNeedsVertexFormat() const {return true;}
|
bool bindingNeedsVertexFormat() const {return true;}
|
||||||
IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements,
|
IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements,
|
||||||
|
@ -40,7 +40,8 @@ public:
|
||||||
size_t texCount, const char** texNames,
|
size_t texCount, const char** texNames,
|
||||||
size_t uniformBlockCount, const char** uniformBlockNames,
|
size_t uniformBlockCount, const char** uniformBlockNames,
|
||||||
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
||||||
bool depthTest, bool depthWrite, CullMode culling);
|
ZTest depthTest, bool depthWrite, bool colorWrite,
|
||||||
|
bool alphaWrite, CullMode culling);
|
||||||
|
|
||||||
IShaderDataBinding*
|
IShaderDataBinding*
|
||||||
newShaderDataBinding(IShaderPipeline* pipeline,
|
newShaderDataBinding(IShaderPipeline* pipeline,
|
||||||
|
@ -48,7 +49,9 @@ public:
|
||||||
IGraphicsBuffer* vbo, IGraphicsBuffer* instVbo, IGraphicsBuffer* ibo,
|
IGraphicsBuffer* vbo, IGraphicsBuffer* instVbo, IGraphicsBuffer* ibo,
|
||||||
size_t ubufCount, IGraphicsBuffer** ubufs, const PipelineStage* ubufStages,
|
size_t ubufCount, IGraphicsBuffer** ubufs, const PipelineStage* ubufStages,
|
||||||
const size_t* ubufOffs, const size_t* ubufSizes,
|
const size_t* ubufOffs, const size_t* ubufSizes,
|
||||||
size_t texCount, ITexture** texs, size_t baseVert = 0, size_t baseInst = 0);
|
size_t texCount, ITexture** texs,
|
||||||
|
const int* texBindIdx, const bool* depthBind,
|
||||||
|
size_t baseVert = 0, size_t baseInst = 0);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,8 @@ struct IGraphicsCommandQueue
|
||||||
virtual void drawInstances(size_t start, size_t count, size_t instCount)=0;
|
virtual void drawInstances(size_t start, size_t count, size_t instCount)=0;
|
||||||
virtual void drawInstancesIndexed(size_t start, size_t count, size_t instCount)=0;
|
virtual void drawInstancesIndexed(size_t start, size_t count, size_t instCount)=0;
|
||||||
|
|
||||||
virtual void resolveBindTexture(ITextureR* texture, const SWindowRect& rect, bool tlOrigin, bool color, bool depth)=0;
|
virtual void resolveBindTexture(ITextureR* texture, const SWindowRect& rect,
|
||||||
|
bool tlOrigin, int bindIdx, bool color, bool depth)=0;
|
||||||
virtual void resolveDisplay(ITextureR* source)=0;
|
virtual void resolveDisplay(ITextureR* source)=0;
|
||||||
virtual void execute()=0;
|
virtual void execute()=0;
|
||||||
|
|
||||||
|
|
|
@ -11,12 +11,22 @@ namespace boo
|
||||||
{
|
{
|
||||||
struct IGraphicsCommandQueue;
|
struct IGraphicsCommandQueue;
|
||||||
|
|
||||||
|
/** Opaque object for maintaining ownership of factory-created resources */
|
||||||
|
struct IGraphicsData { virtual ~IGraphicsData() = default; };
|
||||||
|
class GraphicsDataToken;
|
||||||
|
|
||||||
|
/** Opaque object for maintaining ownership of factory-created pool buffers */
|
||||||
|
struct IGraphicsBufferPool {};
|
||||||
|
class GraphicsBufferPoolToken;
|
||||||
|
|
||||||
struct IGraphicsBuffer
|
struct IGraphicsBuffer
|
||||||
{
|
{
|
||||||
bool dynamic() const {return m_dynamic;}
|
bool dynamic() const {return m_dynamic;}
|
||||||
|
IGraphicsData* m_parentData;
|
||||||
protected:
|
protected:
|
||||||
bool m_dynamic;
|
bool m_dynamic;
|
||||||
IGraphicsBuffer(bool dynamic) : m_dynamic(dynamic) {}
|
IGraphicsBuffer(IGraphicsData* parent, bool dynamic)
|
||||||
|
: m_parentData(parent), m_dynamic(dynamic) {}
|
||||||
virtual ~IGraphicsBuffer() = default;
|
virtual ~IGraphicsBuffer() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -24,7 +34,7 @@ protected:
|
||||||
struct IGraphicsBufferS : IGraphicsBuffer
|
struct IGraphicsBufferS : IGraphicsBuffer
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
IGraphicsBufferS() : IGraphicsBuffer(false) {}
|
IGraphicsBufferS(IGraphicsData* parent) : IGraphicsBuffer(parent, false) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Dynamic resource buffer for verts, indices, uniform constants */
|
/** Dynamic resource buffer for verts, indices, uniform constants */
|
||||||
|
@ -34,7 +44,7 @@ struct IGraphicsBufferD : IGraphicsBuffer
|
||||||
virtual void* map(size_t sz)=0;
|
virtual void* map(size_t sz)=0;
|
||||||
virtual void unmap()=0;
|
virtual void unmap()=0;
|
||||||
protected:
|
protected:
|
||||||
IGraphicsBufferD() : IGraphicsBuffer(true) {}
|
IGraphicsBufferD(IGraphicsData* parent) : IGraphicsBuffer(parent, true) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Supported buffer uses */
|
/** Supported buffer uses */
|
||||||
|
@ -57,9 +67,11 @@ enum class TextureType
|
||||||
struct ITexture
|
struct ITexture
|
||||||
{
|
{
|
||||||
TextureType type() const {return m_type;}
|
TextureType type() const {return m_type;}
|
||||||
|
IGraphicsData* m_parentData;
|
||||||
protected:
|
protected:
|
||||||
TextureType m_type;
|
TextureType m_type;
|
||||||
ITexture(TextureType type) : m_type(type) {}
|
ITexture(IGraphicsData* parent, TextureType type)
|
||||||
|
: m_parentData(parent), m_type(type) {}
|
||||||
virtual ~ITexture() {}
|
virtual ~ITexture() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -67,14 +79,14 @@ protected:
|
||||||
struct ITextureS : ITexture
|
struct ITextureS : ITexture
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
ITextureS() : ITexture(TextureType::Static) {}
|
ITextureS(IGraphicsData* parent) : ITexture(parent, TextureType::Static) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Static-array resource buffer for array textures */
|
/** Static-array resource buffer for array textures */
|
||||||
struct ITextureSA : ITexture
|
struct ITextureSA : ITexture
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
ITextureSA() : ITexture(TextureType::StaticArray) {}
|
ITextureSA(IGraphicsData* parent) : ITexture(parent, TextureType::StaticArray) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Dynamic resource buffer for textures */
|
/** Dynamic resource buffer for textures */
|
||||||
|
@ -84,14 +96,14 @@ struct ITextureD : ITexture
|
||||||
virtual void* map(size_t sz)=0;
|
virtual void* map(size_t sz)=0;
|
||||||
virtual void unmap()=0;
|
virtual void unmap()=0;
|
||||||
protected:
|
protected:
|
||||||
ITextureD() : ITexture(TextureType::Dynamic) {}
|
ITextureD(IGraphicsData* parent) : ITexture(parent, TextureType::Dynamic) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Resource buffer for render-target textures */
|
/** Resource buffer for render-target textures */
|
||||||
struct ITextureR : ITexture
|
struct ITextureR : ITexture
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
ITextureR() : ITexture(TextureType::Render) {}
|
ITextureR(IGraphicsData* parent) : ITexture(parent, TextureType::Render) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Supported texture formats */
|
/** Supported texture formats */
|
||||||
|
@ -106,7 +118,12 @@ enum class TextureFormat
|
||||||
/** Opaque token for representing the data layout of a vertex
|
/** Opaque token for representing the data layout of a vertex
|
||||||
* in a VBO. Also able to reference buffers for platforms like
|
* in a VBO. Also able to reference buffers for platforms like
|
||||||
* OpenGL that cache object refs */
|
* OpenGL that cache object refs */
|
||||||
struct IVertexFormat {};
|
struct IVertexFormat
|
||||||
|
{
|
||||||
|
IGraphicsData* m_parentData;
|
||||||
|
protected:
|
||||||
|
IVertexFormat(IGraphicsData* parent) : m_parentData(parent) {}
|
||||||
|
};
|
||||||
|
|
||||||
/** Types of vertex attributes */
|
/** Types of vertex attributes */
|
||||||
enum class VertexSemantic
|
enum class VertexSemantic
|
||||||
|
@ -141,21 +158,18 @@ struct VertexElementDescriptor
|
||||||
|
|
||||||
/** Opaque token for referencing a complete graphics pipeline state necessary
|
/** Opaque token for referencing a complete graphics pipeline state necessary
|
||||||
* to rasterize geometry (shaders and blending modes mainly) */
|
* to rasterize geometry (shaders and blending modes mainly) */
|
||||||
struct IShaderPipeline {};
|
struct IShaderPipeline
|
||||||
|
{
|
||||||
|
IGraphicsData* m_parentData;
|
||||||
|
protected:
|
||||||
|
IShaderPipeline(IGraphicsData* parent) : m_parentData(parent) {}
|
||||||
|
};
|
||||||
|
|
||||||
/** Opaque token serving as indirection table for shader resources
|
/** Opaque token serving as indirection table for shader resources
|
||||||
* and IShaderPipeline reference. Each renderable surface-material holds one
|
* and IShaderPipeline reference. Each renderable surface-material holds one
|
||||||
* as a reference */
|
* as a reference */
|
||||||
struct IShaderDataBinding {};
|
struct IShaderDataBinding {};
|
||||||
|
|
||||||
/** Opaque object for maintaining ownership of factory-created resources */
|
|
||||||
struct IGraphicsData {};
|
|
||||||
class GraphicsDataToken;
|
|
||||||
|
|
||||||
/** Opaque object for maintaining ownership of factory-created pool buffers */
|
|
||||||
struct IGraphicsBufferPool {};
|
|
||||||
class GraphicsBufferPoolToken;
|
|
||||||
|
|
||||||
/** Used wherever distinction of pipeline stages is needed */
|
/** Used wherever distinction of pipeline stages is needed */
|
||||||
enum class PipelineStage
|
enum class PipelineStage
|
||||||
{
|
{
|
||||||
|
@ -178,6 +192,15 @@ enum class CullMode
|
||||||
Frontface
|
Frontface
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Used by platform shader pipeline constructors */
|
||||||
|
enum class ZTest
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
LEqual, /* Flipped on Vulkan, D3D, Metal */
|
||||||
|
Greater,
|
||||||
|
Equal
|
||||||
|
};
|
||||||
|
|
||||||
/** Used by platform shader pipeline constructors */
|
/** Used by platform shader pipeline constructors */
|
||||||
enum class BlendFactor
|
enum class BlendFactor
|
||||||
{
|
{
|
||||||
|
@ -234,7 +257,7 @@ struct IGraphicsDataFactory
|
||||||
newDynamicTexture(size_t width, size_t height, TextureFormat fmt)=0;
|
newDynamicTexture(size_t width, size_t height, TextureFormat fmt)=0;
|
||||||
virtual ITextureR*
|
virtual ITextureR*
|
||||||
newRenderTexture(size_t width, size_t height,
|
newRenderTexture(size_t width, size_t height,
|
||||||
bool enableShaderColorBinding, bool enableShaderDepthBinding)=0;
|
size_t colorBindingCount, size_t depthBindingCount)=0;
|
||||||
|
|
||||||
virtual bool bindingNeedsVertexFormat() const=0;
|
virtual bool bindingNeedsVertexFormat() const=0;
|
||||||
virtual IVertexFormat*
|
virtual IVertexFormat*
|
||||||
|
@ -247,28 +270,33 @@ struct IGraphicsDataFactory
|
||||||
IGraphicsBuffer* vbo, IGraphicsBuffer* instVbo, IGraphicsBuffer* ibo,
|
IGraphicsBuffer* vbo, IGraphicsBuffer* instVbo, IGraphicsBuffer* ibo,
|
||||||
size_t ubufCount, IGraphicsBuffer** ubufs, const PipelineStage* ubufStages,
|
size_t ubufCount, IGraphicsBuffer** ubufs, const PipelineStage* ubufStages,
|
||||||
const size_t* ubufOffs, const size_t* ubufSizes,
|
const size_t* ubufOffs, const size_t* ubufSizes,
|
||||||
size_t texCount, ITexture** texs, size_t baseVert = 0, size_t baseInst = 0)=0;
|
size_t texCount, ITexture** texs,
|
||||||
|
const int* texBindIdx, const bool* depthBind,
|
||||||
|
size_t baseVert = 0, size_t baseInst = 0)=0;
|
||||||
|
|
||||||
IShaderDataBinding*
|
IShaderDataBinding*
|
||||||
newShaderDataBinding(IShaderPipeline* pipeline,
|
newShaderDataBinding(IShaderPipeline* pipeline,
|
||||||
IVertexFormat* vtxFormat,
|
IVertexFormat* vtxFormat,
|
||||||
IGraphicsBuffer* vbo, IGraphicsBuffer* instVbo, IGraphicsBuffer* ibo,
|
IGraphicsBuffer* vbo, IGraphicsBuffer* instVbo, IGraphicsBuffer* ibo,
|
||||||
size_t ubufCount, IGraphicsBuffer** ubufs, const PipelineStage* ubufStages,
|
size_t ubufCount, IGraphicsBuffer** ubufs, const PipelineStage* ubufStages,
|
||||||
size_t texCount, ITexture** texs, size_t baseVert = 0, size_t baseInst = 0)
|
size_t texCount, ITexture** texs,
|
||||||
|
const int* texBindIdx, const bool* depthBind,
|
||||||
|
size_t baseVert = 0, size_t baseInst = 0)
|
||||||
{
|
{
|
||||||
return newShaderDataBinding(pipeline, vtxFormat, vbo, instVbo, ibo,
|
return newShaderDataBinding(pipeline, vtxFormat, vbo, instVbo, ibo,
|
||||||
ubufCount, ubufs, ubufStages, nullptr,
|
ubufCount, ubufs, ubufStages, nullptr,
|
||||||
nullptr, texCount, texs, baseVert, baseInst);
|
nullptr, texCount, texs, texBindIdx, depthBind,
|
||||||
|
baseVert, baseInst);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual GraphicsDataToken commitTransaction(const std::function<bool(Context& ctx)>&)=0;
|
virtual GraphicsDataToken commitTransaction(const std::function<bool(Context& ctx)>&)=0;
|
||||||
virtual GraphicsBufferPoolToken newBufferPool()=0;
|
virtual GraphicsBufferPoolToken newBufferPool()=0;
|
||||||
|
|
||||||
|
virtual void destroyAllData()=0;
|
||||||
private:
|
private:
|
||||||
friend class GraphicsDataToken;
|
friend class GraphicsDataToken;
|
||||||
virtual void destroyData(IGraphicsData*)=0;
|
virtual void destroyData(IGraphicsData*)=0;
|
||||||
virtual void destroyAllData()=0;
|
|
||||||
|
|
||||||
friend class GraphicsBufferPoolToken;
|
friend class GraphicsBufferPoolToken;
|
||||||
virtual void destroyPool(IGraphicsBufferPool*)=0;
|
virtual void destroyPool(IGraphicsBufferPool*)=0;
|
||||||
|
|
|
@ -31,7 +31,7 @@ public:
|
||||||
TextureFormat fmt, const void* data, size_t sz);
|
TextureFormat fmt, const void* data, size_t sz);
|
||||||
ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt);
|
ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt);
|
||||||
ITextureR* newRenderTexture(size_t width, size_t height,
|
ITextureR* newRenderTexture(size_t width, size_t height,
|
||||||
bool enableShaderColorBinding, bool enableShaderDepthBinding);
|
size_t colorBindCount, size_t depthBindCount);
|
||||||
|
|
||||||
bool bindingNeedsVertexFormat() const {return false;}
|
bool bindingNeedsVertexFormat() const {return false;}
|
||||||
IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements,
|
IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements,
|
||||||
|
@ -40,7 +40,8 @@ public:
|
||||||
IShaderPipeline* newShaderPipeline(const char* vertSource, const char* fragSource,
|
IShaderPipeline* newShaderPipeline(const char* vertSource, const char* fragSource,
|
||||||
IVertexFormat* vtxFmt, unsigned targetSamples,
|
IVertexFormat* vtxFmt, unsigned targetSamples,
|
||||||
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
||||||
bool depthTest, bool depthWrite, CullMode culling);
|
ZTest depthTest, bool depthWrite, bool colorWrite,
|
||||||
|
bool alphaWrite, CullMode culling);
|
||||||
|
|
||||||
IShaderDataBinding*
|
IShaderDataBinding*
|
||||||
newShaderDataBinding(IShaderPipeline* pipeline,
|
newShaderDataBinding(IShaderPipeline* pipeline,
|
||||||
|
@ -48,7 +49,9 @@ public:
|
||||||
IGraphicsBuffer* vbo, IGraphicsBuffer* instVbo, IGraphicsBuffer* ibo,
|
IGraphicsBuffer* vbo, IGraphicsBuffer* instVbo, IGraphicsBuffer* ibo,
|
||||||
size_t ubufCount, IGraphicsBuffer** ubufs, const PipelineStage* ubufStages,
|
size_t ubufCount, IGraphicsBuffer** ubufs, const PipelineStage* ubufStages,
|
||||||
const size_t* ubufOffs, const size_t* ubufSizes,
|
const size_t* ubufOffs, const size_t* ubufSizes,
|
||||||
size_t texCount, ITexture** texs, size_t baseVert = 0, size_t baseInst = 0);
|
size_t texCount, ITexture** texs,
|
||||||
|
const int* texBindIdxs, const bool* depthBind,
|
||||||
|
size_t baseVert = 0, size_t baseInst = 0);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -132,11 +132,12 @@ public:
|
||||||
std::vector<unsigned int>* vertBlobOut, std::vector<unsigned int>* fragBlobOut,
|
std::vector<unsigned int>* vertBlobOut, std::vector<unsigned int>* fragBlobOut,
|
||||||
std::vector<unsigned char>* pipelineBlob, IVertexFormat* vtxFmt,
|
std::vector<unsigned char>* pipelineBlob, IVertexFormat* vtxFmt,
|
||||||
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
||||||
bool depthTest, bool depthWrite, CullMode culling);
|
ZTest depthTest, bool depthWrite, CullMode culling);
|
||||||
|
|
||||||
IShaderPipeline* newShaderPipeline(const char* vertSource, const char* fragSource, IVertexFormat* vtxFmt,
|
IShaderPipeline* newShaderPipeline(const char* vertSource, const char* fragSource, IVertexFormat* vtxFmt,
|
||||||
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
||||||
bool depthTest, bool depthWrite, CullMode culling)
|
ZTest depthTest, bool depthWrite, bool colorWrite,
|
||||||
|
bool alphaWrite, CullMode culling)
|
||||||
{
|
{
|
||||||
return newShaderPipeline(vertSource, fragSource, nullptr, nullptr, nullptr,
|
return newShaderPipeline(vertSource, fragSource, nullptr, nullptr, nullptr,
|
||||||
vtxFmt, srcFac, dstFac, prim, depthTest, depthWrite, culling);
|
vtxFmt, srcFac, dstFac, prim, depthTest, depthWrite, culling);
|
||||||
|
|
|
@ -5,12 +5,12 @@
|
||||||
* binding lifetimes through rendering cycle */
|
* binding lifetimes through rendering cycle */
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <vector>
|
||||||
#include "boo/graphicsdev/IGraphicsDataFactory.hpp"
|
#include "boo/graphicsdev/IGraphicsDataFactory.hpp"
|
||||||
|
|
||||||
namespace boo
|
namespace boo
|
||||||
{
|
{
|
||||||
|
|
||||||
template <class DataImpl>
|
|
||||||
class IGraphicsDataPriv : public IGraphicsData
|
class IGraphicsDataPriv : public IGraphicsData
|
||||||
{
|
{
|
||||||
std::atomic_int m_refCount = {1};
|
std::atomic_int m_refCount = {1};
|
||||||
|
@ -19,35 +19,50 @@ public:
|
||||||
void decrement()
|
void decrement()
|
||||||
{
|
{
|
||||||
if (m_refCount.fetch_sub(1) == 1)
|
if (m_refCount.fetch_sub(1) == 1)
|
||||||
delete static_cast<DataImpl*>(this);
|
delete this;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class DataImpl>
|
|
||||||
class IShaderDataBindingPriv : public IShaderDataBinding
|
class IShaderDataBindingPriv : public IShaderDataBinding
|
||||||
{
|
{
|
||||||
IGraphicsDataPriv<DataImpl>* m_parent;
|
IGraphicsDataPriv* m_parent;
|
||||||
|
std::vector<IGraphicsDataPriv*> m_depDatas;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IShaderDataBindingPriv(IGraphicsDataPriv<DataImpl>* p) : m_parent(p) {}
|
IShaderDataBindingPriv(IGraphicsDataPriv* p) : m_parent(p) {}
|
||||||
class Token
|
class Token
|
||||||
{
|
{
|
||||||
IGraphicsDataPriv<DataImpl>* m_data = nullptr;
|
IGraphicsDataPriv* m_data = nullptr;
|
||||||
public:
|
public:
|
||||||
Token() = default;
|
Token() = default;
|
||||||
Token(const IShaderDataBindingPriv* p)
|
Token(const IShaderDataBindingPriv* p)
|
||||||
: m_data(p->m_parent)
|
: m_data(p->m_parent) { m_data->increment(); }
|
||||||
{ m_data->increment(); }
|
|
||||||
Token& operator=(const Token&) = delete;
|
Token& operator=(const Token&) = delete;
|
||||||
Token(const Token&) = delete;
|
Token(const Token&) = delete;
|
||||||
Token& operator=(Token&& other)
|
Token& operator=(Token&& other)
|
||||||
{ m_data = other.m_data; other.m_data = nullptr; return *this; }
|
{ m_data = other.m_data; other.m_data = nullptr; return *this; }
|
||||||
Token(Token&& other)
|
Token(Token&& other)
|
||||||
{ m_data = other.m_data; other.m_data = nullptr; }
|
{ m_data = other.m_data; other.m_data = nullptr; }
|
||||||
~Token() { if (m_data) m_data->decrement(); }
|
~Token() { if (m_data) { m_data->decrement(); } }
|
||||||
};
|
};
|
||||||
|
|
||||||
Token lock() const { return Token(this); }
|
Token lock() const { return Token(this); }
|
||||||
|
~IShaderDataBindingPriv()
|
||||||
|
{
|
||||||
|
for (IGraphicsDataPriv* dep : m_depDatas)
|
||||||
|
dep->decrement();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void addDepData(IGraphicsData* data)
|
||||||
|
{
|
||||||
|
IGraphicsDataPriv* d = static_cast<IGraphicsDataPriv*>(data);
|
||||||
|
if (d != m_parent)
|
||||||
|
{
|
||||||
|
m_depDatas.push_back(d);
|
||||||
|
d->increment();
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class FactoryImpl, class ShaderImpl>
|
template <class FactoryImpl, class ShaderImpl>
|
||||||
|
|
|
@ -501,7 +501,7 @@ class D3D11ShaderPipeline : public IShaderPipeline
|
||||||
D3D11ShareableShader::Token&& pixel,
|
D3D11ShareableShader::Token&& pixel,
|
||||||
const D3D11VertexFormat* vtxFmt,
|
const D3D11VertexFormat* vtxFmt,
|
||||||
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
||||||
bool depthTest, bool depthWrite, CullMode culling)
|
ZTest depthTest, bool depthWrite, CullMode culling)
|
||||||
: m_vtxFmt(vtxFmt), m_vert(std::move(vert)), m_pixel(std::move(pixel)),
|
: m_vtxFmt(vtxFmt), m_vert(std::move(vert)), m_pixel(std::move(pixel)),
|
||||||
m_topology(PRIMITIVE_TABLE[int(prim)])
|
m_topology(PRIMITIVE_TABLE[int(prim)])
|
||||||
{
|
{
|
||||||
|
@ -538,6 +538,8 @@ class D3D11ShaderPipeline : public IShaderPipeline
|
||||||
blDesc.RenderTarget[0].BlendEnable = (dstFac != BlendFactor::Zero);
|
blDesc.RenderTarget[0].BlendEnable = (dstFac != BlendFactor::Zero);
|
||||||
blDesc.RenderTarget[0].SrcBlend = BLEND_FACTOR_TABLE[int(srcFac)];
|
blDesc.RenderTarget[0].SrcBlend = BLEND_FACTOR_TABLE[int(srcFac)];
|
||||||
blDesc.RenderTarget[0].DestBlend = BLEND_FACTOR_TABLE[int(dstFac)];
|
blDesc.RenderTarget[0].DestBlend = BLEND_FACTOR_TABLE[int(dstFac)];
|
||||||
|
blDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
|
||||||
|
blDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
|
||||||
ThrowIfFailed(ctx->m_dev->CreateBlendState(&blDesc, &m_blState));
|
ThrowIfFailed(ctx->m_dev->CreateBlendState(&blDesc, &m_blState));
|
||||||
|
|
||||||
const auto& vertBuf = m_vert.get().m_vtxBlob;
|
const auto& vertBuf = m_vert.get().m_vtxBlob;
|
||||||
|
@ -1008,7 +1010,7 @@ struct D3D11CommandQueue : IGraphicsCommandQueue
|
||||||
func();
|
func();
|
||||||
}
|
}
|
||||||
|
|
||||||
float m_clearColor[4] = {0.0,0.0,0.0,1.0};
|
float m_clearColor[4] = {0.0,0.0,0.0,0.0};
|
||||||
void setClearColor(const float rgba[4])
|
void setClearColor(const float rgba[4])
|
||||||
{
|
{
|
||||||
m_clearColor[0] = rgba[0];
|
m_clearColor[0] = rgba[0];
|
||||||
|
@ -1336,7 +1338,7 @@ public:
|
||||||
ComPtr<ID3DBlob>* vertBlobOut, ComPtr<ID3DBlob>* fragBlobOut,
|
ComPtr<ID3DBlob>* vertBlobOut, ComPtr<ID3DBlob>* fragBlobOut,
|
||||||
ComPtr<ID3DBlob>* pipelineBlob, IVertexFormat* vtxFmt,
|
ComPtr<ID3DBlob>* pipelineBlob, IVertexFormat* vtxFmt,
|
||||||
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
||||||
bool depthTest, bool depthWrite, CullMode culling)
|
ZTest depthTest, bool depthWrite, CullMode culling)
|
||||||
{
|
{
|
||||||
XXH64_state_t hashState;
|
XXH64_state_t hashState;
|
||||||
uint64_t srcHashes[2] = {};
|
uint64_t srcHashes[2] = {};
|
||||||
|
|
|
@ -470,7 +470,6 @@ class D3D12TextureR : public ITextureR
|
||||||
|
|
||||||
D3D12_CLEAR_VALUE colorClear = {};
|
D3D12_CLEAR_VALUE colorClear = {};
|
||||||
colorClear.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
colorClear.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
colorClear.Color[3] = 1.f;
|
|
||||||
ThrowIfFailed(ctx->m_dev->CreateCommittedResource(&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE,
|
ThrowIfFailed(ctx->m_dev->CreateCommittedResource(&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE,
|
||||||
&rtvresdesc, D3D12_RESOURCE_STATE_RENDER_TARGET, &colorClear,
|
&rtvresdesc, D3D12_RESOURCE_STATE_RENDER_TARGET, &colorClear,
|
||||||
__uuidof(ID3D12Resource), &m_colorTex));
|
__uuidof(ID3D12Resource), &m_colorTex));
|
||||||
|
@ -654,7 +653,7 @@ class D3D12ShaderPipeline : public IShaderPipeline
|
||||||
D3D12ShareableShader::Token&& pixel, ID3DBlob* pipeline,
|
D3D12ShareableShader::Token&& pixel, ID3DBlob* pipeline,
|
||||||
const D3D12VertexFormat* vtxFmt,
|
const D3D12VertexFormat* vtxFmt,
|
||||||
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
||||||
bool depthTest, bool depthWrite, CullMode culling)
|
ZTest depthTest, bool depthWrite, CullMode culling)
|
||||||
: m_vtxFmt(vtxFmt), m_vert(std::move(vert)), m_pixel(std::move(pixel)),
|
: m_vtxFmt(vtxFmt), m_vert(std::move(vert)), m_pixel(std::move(pixel)),
|
||||||
m_topology(PRIMITIVE_TABLE[int(prim)])
|
m_topology(PRIMITIVE_TABLE[int(prim)])
|
||||||
{
|
{
|
||||||
|
@ -685,6 +684,8 @@ class D3D12ShaderPipeline : public IShaderPipeline
|
||||||
desc.BlendState.RenderTarget[0].BlendEnable = true;
|
desc.BlendState.RenderTarget[0].BlendEnable = true;
|
||||||
desc.BlendState.RenderTarget[0].SrcBlend = BLEND_FACTOR_TABLE[int(srcFac)];
|
desc.BlendState.RenderTarget[0].SrcBlend = BLEND_FACTOR_TABLE[int(srcFac)];
|
||||||
desc.BlendState.RenderTarget[0].DestBlend = BLEND_FACTOR_TABLE[int(dstFac)];
|
desc.BlendState.RenderTarget[0].DestBlend = BLEND_FACTOR_TABLE[int(dstFac)];
|
||||||
|
desc.BlendState.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_ONE;
|
||||||
|
desc.BlendState.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_ZERO;
|
||||||
}
|
}
|
||||||
desc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
|
desc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
|
||||||
desc.RasterizerState.FrontCounterClockwise = TRUE;
|
desc.RasterizerState.FrontCounterClockwise = TRUE;
|
||||||
|
@ -1260,7 +1261,7 @@ struct D3D12CommandQueue : IGraphicsCommandQueue
|
||||||
func();
|
func();
|
||||||
}
|
}
|
||||||
|
|
||||||
float m_clearColor[4] = {0.0,0.0,0.0,1.0};
|
float m_clearColor[4] = {0.0,0.0,0.0,0.0};
|
||||||
void setClearColor(const float rgba[4])
|
void setClearColor(const float rgba[4])
|
||||||
{
|
{
|
||||||
m_clearColor[0] = rgba[0];
|
m_clearColor[0] = rgba[0];
|
||||||
|
@ -1767,7 +1768,7 @@ public:
|
||||||
ComPtr<ID3DBlob>* vertBlobOut, ComPtr<ID3DBlob>* fragBlobOut,
|
ComPtr<ID3DBlob>* vertBlobOut, ComPtr<ID3DBlob>* fragBlobOut,
|
||||||
ComPtr<ID3DBlob>* pipelineBlob, IVertexFormat* vtxFmt,
|
ComPtr<ID3DBlob>* pipelineBlob, IVertexFormat* vtxFmt,
|
||||||
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
||||||
bool depthTest, bool depthWrite, CullMode culling)
|
ZTest depthTest, bool depthWrite, CullMode culling)
|
||||||
{
|
{
|
||||||
XXH64_state_t hashState;
|
XXH64_state_t hashState;
|
||||||
uint64_t srcHashes[2] = {};
|
uint64_t srcHashes[2] = {};
|
||||||
|
|
|
@ -65,7 +65,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
ThreadLocalPtr<struct GLData> GLDataFactoryImpl::m_deferredData;
|
ThreadLocalPtr<struct GLData> GLDataFactoryImpl::m_deferredData;
|
||||||
struct GLData : IGraphicsDataPriv<GLData>
|
struct GLData : IGraphicsDataPriv
|
||||||
{
|
{
|
||||||
std::vector<std::unique_ptr<class GLShaderPipeline>> m_SPs;
|
std::vector<std::unique_ptr<class GLShaderPipeline>> m_SPs;
|
||||||
std::vector<std::unique_ptr<struct GLShaderDataBinding>> m_SBinds;
|
std::vector<std::unique_ptr<struct GLShaderDataBinding>> m_SBinds;
|
||||||
|
@ -78,9 +78,19 @@ struct GLData : IGraphicsDataPriv<GLData>
|
||||||
std::vector<std::unique_ptr<struct GLVertexFormat>> m_VFmts;
|
std::vector<std::unique_ptr<struct GLVertexFormat>> m_VFmts;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct GLPoolItem : IGraphicsDataPriv
|
||||||
|
{
|
||||||
|
std::unique_ptr<class GLGraphicsBufferD> m_buf;
|
||||||
|
};
|
||||||
|
|
||||||
struct GLPool : IGraphicsBufferPool
|
struct GLPool : IGraphicsBufferPool
|
||||||
{
|
{
|
||||||
std::unordered_map<class GLGraphicsBufferD*, std::unique_ptr<class GLGraphicsBufferD>> m_DBufs;
|
std::unordered_set<GLPoolItem*> m_items;
|
||||||
|
~GLPool()
|
||||||
|
{
|
||||||
|
for (auto& item : m_items)
|
||||||
|
item->decrement();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const GLenum USE_TABLE[] =
|
static const GLenum USE_TABLE[] =
|
||||||
|
@ -97,7 +107,8 @@ class GLGraphicsBufferS : public IGraphicsBufferS
|
||||||
friend struct GLCommandQueue;
|
friend struct GLCommandQueue;
|
||||||
GLuint m_buf;
|
GLuint m_buf;
|
||||||
GLenum m_target;
|
GLenum m_target;
|
||||||
GLGraphicsBufferS(BufferUse use, const void* data, size_t sz)
|
GLGraphicsBufferS(IGraphicsData* parent, BufferUse use, const void* data, size_t sz)
|
||||||
|
: IGraphicsBufferS(parent)
|
||||||
{
|
{
|
||||||
m_target = USE_TABLE[int(use)];
|
m_target = USE_TABLE[int(use)];
|
||||||
glGenBuffers(1, &m_buf);
|
glGenBuffers(1, &m_buf);
|
||||||
|
@ -127,8 +138,9 @@ class GLGraphicsBufferD : public IGraphicsBufferD
|
||||||
std::unique_ptr<uint8_t[]> m_cpuBuf;
|
std::unique_ptr<uint8_t[]> m_cpuBuf;
|
||||||
size_t m_cpuSz = 0;
|
size_t m_cpuSz = 0;
|
||||||
int m_validMask = 0;
|
int m_validMask = 0;
|
||||||
GLGraphicsBufferD(BufferUse use, size_t sz)
|
GLGraphicsBufferD(IGraphicsData* parent, BufferUse use, size_t sz)
|
||||||
: m_target(USE_TABLE[int(use)]), m_cpuBuf(new uint8_t[sz]), m_cpuSz(sz)
|
: boo::IGraphicsBufferD(parent),
|
||||||
|
m_target(USE_TABLE[int(use)]), m_cpuBuf(new uint8_t[sz]), m_cpuSz(sz)
|
||||||
{
|
{
|
||||||
glGenBuffers(3, m_bufs);
|
glGenBuffers(3, m_bufs);
|
||||||
for (int i=0 ; i<3 ; ++i)
|
for (int i=0 ; i<3 ; ++i)
|
||||||
|
@ -154,8 +166,9 @@ public:
|
||||||
IGraphicsBufferS*
|
IGraphicsBufferS*
|
||||||
GLDataFactory::Context::newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count)
|
GLDataFactory::Context::newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count)
|
||||||
{
|
{
|
||||||
GLGraphicsBufferS* retval = new GLGraphicsBufferS(use, data, stride * count);
|
GLData* d = GLDataFactoryImpl::m_deferredData.get();
|
||||||
GLDataFactoryImpl::m_deferredData->m_SBufs.emplace_back(retval);
|
GLGraphicsBufferS* retval = new GLGraphicsBufferS(d, use, data, stride * count);
|
||||||
|
d->m_SBufs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,8 +176,9 @@ class GLTextureS : public ITextureS
|
||||||
{
|
{
|
||||||
friend class GLDataFactory;
|
friend class GLDataFactory;
|
||||||
GLuint m_tex;
|
GLuint m_tex;
|
||||||
GLTextureS(size_t width, size_t height, size_t mips,
|
GLTextureS(GLData* parent, size_t width, size_t height, size_t mips,
|
||||||
TextureFormat fmt, const void* data, size_t sz)
|
TextureFormat fmt, const void* data, size_t sz)
|
||||||
|
: ITextureS(parent)
|
||||||
{
|
{
|
||||||
const uint8_t* dataIt = static_cast<const uint8_t*>(data);
|
const uint8_t* dataIt = static_cast<const uint8_t*>(data);
|
||||||
glGenTextures(1, &m_tex);
|
glGenTextures(1, &m_tex);
|
||||||
|
@ -241,8 +255,9 @@ class GLTextureSA : public ITextureSA
|
||||||
{
|
{
|
||||||
friend class GLDataFactory;
|
friend class GLDataFactory;
|
||||||
GLuint m_tex;
|
GLuint m_tex;
|
||||||
GLTextureSA(size_t width, size_t height, size_t layers, size_t mips,
|
GLTextureSA(GLData* parent, size_t width, size_t height, size_t layers, size_t mips,
|
||||||
TextureFormat fmt, const void* data, size_t sz)
|
TextureFormat fmt, const void* data, size_t sz)
|
||||||
|
: ITextureSA(parent)
|
||||||
{
|
{
|
||||||
const uint8_t* dataIt = static_cast<const uint8_t*>(data);
|
const uint8_t* dataIt = static_cast<const uint8_t*>(data);
|
||||||
glGenTextures(1, &m_tex);
|
glGenTextures(1, &m_tex);
|
||||||
|
@ -302,7 +317,7 @@ class GLTextureD : public ITextureD
|
||||||
size_t m_width = 0;
|
size_t m_width = 0;
|
||||||
size_t m_height = 0;
|
size_t m_height = 0;
|
||||||
int m_validMask = 0;
|
int m_validMask = 0;
|
||||||
GLTextureD(size_t width, size_t height, TextureFormat fmt);
|
GLTextureD(IGraphicsData* parent, size_t width, size_t height, TextureFormat fmt);
|
||||||
void update(int b);
|
void update(int b);
|
||||||
public:
|
public:
|
||||||
~GLTextureD();
|
~GLTextureD();
|
||||||
|
@ -314,27 +329,29 @@ public:
|
||||||
void bind(size_t idx, int b);
|
void bind(size_t idx, int b);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MAX_BIND_TEXS 4
|
||||||
|
|
||||||
class GLTextureR : public ITextureR
|
class GLTextureR : public ITextureR
|
||||||
{
|
{
|
||||||
friend class GLDataFactory;
|
friend class GLDataFactory;
|
||||||
friend struct GLCommandQueue;
|
friend struct GLCommandQueue;
|
||||||
struct GLCommandQueue* m_q;
|
struct GLCommandQueue* m_q;
|
||||||
GLuint m_texs[2] = {};
|
GLuint m_texs[2] = {};
|
||||||
GLuint m_bindTexs[2] = {};
|
GLuint m_bindTexs[2][MAX_BIND_TEXS] = {};
|
||||||
GLuint m_fbo = 0;
|
GLuint m_fbo = 0;
|
||||||
size_t m_width = 0;
|
size_t m_width = 0;
|
||||||
size_t m_height = 0;
|
size_t m_height = 0;
|
||||||
size_t m_samples = 0;
|
size_t m_samples = 0;
|
||||||
GLenum m_target;
|
GLenum m_target;
|
||||||
GLTextureR(GLCommandQueue* q, size_t width, size_t height, size_t samples,
|
GLTextureR(IGraphicsData* parent, GLCommandQueue* q, size_t width, size_t height, size_t samples,
|
||||||
bool enableShaderColorBinding, bool enableShaderDepthBinding);
|
size_t colorBindCount, size_t depthBindCount);
|
||||||
public:
|
public:
|
||||||
~GLTextureR();
|
~GLTextureR();
|
||||||
|
|
||||||
void bind(size_t idx) const
|
void bind(size_t idx, int bindIdx, bool depth) const
|
||||||
{
|
{
|
||||||
glActiveTexture(GL_TEXTURE0 + idx);
|
glActiveTexture(GL_TEXTURE0 + idx);
|
||||||
glBindTexture(m_target, m_bindTexs[0]);
|
glBindTexture(m_target, m_bindTexs[depth][bindIdx]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void resize(size_t width, size_t height)
|
void resize(size_t width, size_t height)
|
||||||
|
@ -349,15 +366,22 @@ public:
|
||||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_texs[1]);
|
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_texs[1]);
|
||||||
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, m_samples, GL_DEPTH_COMPONENT24, width, height, GL_FALSE);
|
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, m_samples, GL_DEPTH_COMPONENT24, width, height, GL_FALSE);
|
||||||
|
|
||||||
if (m_bindTexs[0])
|
for (int i=0 ; i<MAX_BIND_TEXS ; ++i)
|
||||||
{
|
{
|
||||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_bindTexs[0]);
|
if (m_bindTexs[0][i])
|
||||||
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, m_samples, GL_RGBA, width, height, GL_FALSE);
|
{
|
||||||
|
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_bindTexs[0][i]);
|
||||||
|
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, m_samples, GL_RGBA, width, height, GL_FALSE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (m_bindTexs[1])
|
|
||||||
|
for (int i=0 ; i<MAX_BIND_TEXS ; ++i)
|
||||||
{
|
{
|
||||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_bindTexs[1]);
|
if (m_bindTexs[1][i])
|
||||||
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, m_samples, GL_DEPTH_COMPONENT24, width, height, GL_FALSE);
|
{
|
||||||
|
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_bindTexs[1][i]);
|
||||||
|
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, m_samples, GL_DEPTH_COMPONENT24, width, height, GL_FALSE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -371,15 +395,22 @@ public:
|
||||||
glDepthMask(GL_TRUE);
|
glDepthMask(GL_TRUE);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
if (m_bindTexs[0])
|
for (int i=0 ; i<MAX_BIND_TEXS ; ++i)
|
||||||
{
|
{
|
||||||
glBindTexture(GL_TEXTURE_2D, m_bindTexs[0]);
|
if (m_bindTexs[0][i])
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
{
|
||||||
|
glBindTexture(GL_TEXTURE_2D, m_bindTexs[0][i]);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (m_bindTexs[1])
|
|
||||||
|
for (int i=0 ; i<MAX_BIND_TEXS ; ++i)
|
||||||
{
|
{
|
||||||
glBindTexture(GL_TEXTURE_2D, m_bindTexs[1]);
|
if (m_bindTexs[1][i])
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
|
{
|
||||||
|
glBindTexture(GL_TEXTURE_2D, m_bindTexs[1][i]);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -389,8 +420,9 @@ ITextureS*
|
||||||
GLDataFactory::Context::newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
|
GLDataFactory::Context::newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
|
||||||
const void* data, size_t sz)
|
const void* data, size_t sz)
|
||||||
{
|
{
|
||||||
GLTextureS* retval = new GLTextureS(width, height, mips, fmt, data, sz);
|
GLData* d = GLDataFactoryImpl::m_deferredData.get();
|
||||||
GLDataFactoryImpl::m_deferredData->m_STexs.emplace_back(retval);
|
GLTextureS* retval = new GLTextureS(d, width, height, mips, fmt, data, sz);
|
||||||
|
d->m_STexs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,8 +430,9 @@ ITextureSA*
|
||||||
GLDataFactory::Context::newStaticArrayTexture(size_t width, size_t height, size_t layers, size_t mips,
|
GLDataFactory::Context::newStaticArrayTexture(size_t width, size_t height, size_t layers, size_t mips,
|
||||||
TextureFormat fmt, const void *data, size_t sz)
|
TextureFormat fmt, const void *data, size_t sz)
|
||||||
{
|
{
|
||||||
GLTextureSA* retval = new GLTextureSA(width, height, layers, mips, fmt, data, sz);
|
GLData* d = GLDataFactoryImpl::m_deferredData.get();
|
||||||
GLDataFactoryImpl::m_deferredData->m_SATexs.emplace_back(retval);
|
GLTextureSA* retval = new GLTextureSA(d, width, height, layers, mips, fmt, data, sz);
|
||||||
|
d->m_SATexs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -414,11 +447,13 @@ class GLShaderPipeline : public IShaderPipeline
|
||||||
GLenum m_sfactor = GL_ONE;
|
GLenum m_sfactor = GL_ONE;
|
||||||
GLenum m_dfactor = GL_ZERO;
|
GLenum m_dfactor = GL_ZERO;
|
||||||
GLenum m_drawPrim = GL_TRIANGLES;
|
GLenum m_drawPrim = GL_TRIANGLES;
|
||||||
bool m_depthTest = true;
|
ZTest m_depthTest = ZTest::LEqual;
|
||||||
bool m_depthWrite = true;
|
bool m_depthWrite = true;
|
||||||
|
bool m_colorWrite = true;
|
||||||
|
bool m_alphaWrite = true;
|
||||||
CullMode m_culling;
|
CullMode m_culling;
|
||||||
std::vector<GLint> m_uniLocs;
|
std::vector<GLint> m_uniLocs;
|
||||||
GLShaderPipeline() = default;
|
GLShaderPipeline(GLData* parent) : IShaderPipeline(parent) {}
|
||||||
public:
|
public:
|
||||||
operator bool() const {return m_prog != 0;}
|
operator bool() const {return m_prog != 0;}
|
||||||
~GLShaderPipeline() { if (m_prog) glDeleteProgram(m_prog); }
|
~GLShaderPipeline() { if (m_prog) glDeleteProgram(m_prog); }
|
||||||
|
@ -435,11 +470,14 @@ public:
|
||||||
m_drawPrim = other.m_drawPrim;
|
m_drawPrim = other.m_drawPrim;
|
||||||
m_depthTest = other.m_depthTest;
|
m_depthTest = other.m_depthTest;
|
||||||
m_depthWrite = other.m_depthWrite;
|
m_depthWrite = other.m_depthWrite;
|
||||||
|
m_colorWrite = other.m_colorWrite;
|
||||||
|
m_alphaWrite = other.m_alphaWrite;
|
||||||
m_culling = other.m_culling;
|
m_culling = other.m_culling;
|
||||||
m_uniLocs = std::move(other.m_uniLocs);
|
m_uniLocs = std::move(other.m_uniLocs);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
GLShaderPipeline(GLShaderPipeline&& other) { *this = std::move(other); }
|
GLShaderPipeline(GLShaderPipeline&& other)
|
||||||
|
: IShaderPipeline(other.m_parentData) { *this = std::move(other); }
|
||||||
|
|
||||||
GLuint bind() const
|
GLuint bind() const
|
||||||
{
|
{
|
||||||
|
@ -448,17 +486,32 @@ public:
|
||||||
if (m_dfactor != GL_ZERO)
|
if (m_dfactor != GL_ZERO)
|
||||||
{
|
{
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendFunc(m_sfactor, m_dfactor);
|
glBlendFuncSeparate(m_sfactor, m_dfactor, GL_ONE, GL_ZERO);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
|
|
||||||
if (m_depthTest)
|
if (m_depthTest != ZTest::None)
|
||||||
|
{
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
switch (m_depthTest)
|
||||||
|
{
|
||||||
|
case ZTest::LEqual:
|
||||||
|
default:
|
||||||
|
glDepthFunc(GL_LEQUAL);
|
||||||
|
break;
|
||||||
|
case ZTest::Greater:
|
||||||
|
glDepthFunc(GL_GREATER);
|
||||||
|
break;
|
||||||
|
case ZTest::Equal:
|
||||||
|
glDepthFunc(GL_EQUAL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
glDepthMask(m_depthWrite);
|
glDepthMask(m_depthWrite);
|
||||||
glDepthFunc(GL_LEQUAL);
|
glColorMask(m_colorWrite, m_colorWrite, m_colorWrite, m_alphaWrite);
|
||||||
|
|
||||||
if (m_culling != CullMode::None)
|
if (m_culling != CullMode::None)
|
||||||
{
|
{
|
||||||
|
@ -499,10 +552,12 @@ IShaderPipeline* GLDataFactory::Context::newShaderPipeline
|
||||||
size_t texCount, const char** texNames,
|
size_t texCount, const char** texNames,
|
||||||
size_t uniformBlockCount, const char** uniformBlockNames,
|
size_t uniformBlockCount, const char** uniformBlockNames,
|
||||||
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
||||||
bool depthTest, bool depthWrite, CullMode culling)
|
ZTest depthTest, bool depthWrite, bool colorWrite,
|
||||||
|
bool alphaWrite, CullMode culling)
|
||||||
{
|
{
|
||||||
|
GLData* d = GLDataFactoryImpl::m_deferredData.get();
|
||||||
GLDataFactoryImpl& factory = static_cast<GLDataFactoryImpl&>(m_parent);
|
GLDataFactoryImpl& factory = static_cast<GLDataFactoryImpl&>(m_parent);
|
||||||
GLShaderPipeline shader;
|
GLShaderPipeline shader(d);
|
||||||
|
|
||||||
XXH64_state_t hashState;
|
XXH64_state_t hashState;
|
||||||
uint64_t hashes[2];
|
uint64_t hashes[2];
|
||||||
|
@ -634,11 +689,13 @@ IShaderPipeline* GLDataFactory::Context::newShaderPipeline
|
||||||
shader.m_dfactor = BLEND_FACTOR_TABLE[int(dstFac)];
|
shader.m_dfactor = BLEND_FACTOR_TABLE[int(dstFac)];
|
||||||
shader.m_depthTest = depthTest;
|
shader.m_depthTest = depthTest;
|
||||||
shader.m_depthWrite = depthWrite;
|
shader.m_depthWrite = depthWrite;
|
||||||
|
shader.m_colorWrite = colorWrite;
|
||||||
|
shader.m_alphaWrite = alphaWrite;
|
||||||
shader.m_culling = culling;
|
shader.m_culling = culling;
|
||||||
shader.m_drawPrim = PRIMITIVE_TABLE[int(prim)];
|
shader.m_drawPrim = PRIMITIVE_TABLE[int(prim)];
|
||||||
|
|
||||||
GLShaderPipeline* retval = new GLShaderPipeline(std::move(shader));
|
GLShaderPipeline* retval = new GLShaderPipeline(std::move(shader));
|
||||||
GLDataFactoryImpl::m_deferredData->m_SPs.emplace_back(retval);
|
d->m_SPs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -649,14 +706,14 @@ struct GLVertexFormat : IVertexFormat
|
||||||
size_t m_elementCount;
|
size_t m_elementCount;
|
||||||
GLuint m_baseVert, m_baseInst;
|
GLuint m_baseVert, m_baseInst;
|
||||||
std::unique_ptr<VertexElementDescriptor[]> m_elements;
|
std::unique_ptr<VertexElementDescriptor[]> m_elements;
|
||||||
GLVertexFormat(GLCommandQueue* q, size_t elementCount,
|
GLVertexFormat(IGraphicsData* parent, GLCommandQueue* q, size_t elementCount,
|
||||||
const VertexElementDescriptor* elements,
|
const VertexElementDescriptor* elements,
|
||||||
size_t baseVert, size_t baseInst);
|
size_t baseVert, size_t baseInst);
|
||||||
~GLVertexFormat();
|
~GLVertexFormat();
|
||||||
void bind(int idx) const {glBindVertexArray(m_vao[idx]);}
|
void bind(int idx) const {glBindVertexArray(m_vao[idx]);}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GLShaderDataBinding : IShaderDataBindingPriv<GLData>
|
struct GLShaderDataBinding : IShaderDataBindingPriv
|
||||||
{
|
{
|
||||||
const GLShaderPipeline* m_pipeline;
|
const GLShaderPipeline* m_pipeline;
|
||||||
const GLVertexFormat* m_vtxFormat;
|
const GLVertexFormat* m_vtxFormat;
|
||||||
|
@ -664,22 +721,32 @@ struct GLShaderDataBinding : IShaderDataBindingPriv<GLData>
|
||||||
std::unique_ptr<IGraphicsBuffer*[]> m_ubufs;
|
std::unique_ptr<IGraphicsBuffer*[]> m_ubufs;
|
||||||
std::vector<std::pair<size_t,size_t>> m_ubufOffs;
|
std::vector<std::pair<size_t,size_t>> m_ubufOffs;
|
||||||
size_t m_texCount;
|
size_t m_texCount;
|
||||||
std::unique_ptr<ITexture*[]> m_texs;
|
struct BoundTex
|
||||||
|
{
|
||||||
|
ITexture* tex;
|
||||||
|
int idx;
|
||||||
|
bool depth;
|
||||||
|
};
|
||||||
|
std::unique_ptr<BoundTex[]> m_texs;
|
||||||
|
|
||||||
GLShaderDataBinding(GLData* d,
|
GLShaderDataBinding(GLData* d,
|
||||||
IShaderPipeline* pipeline,
|
IShaderPipeline* pipeline,
|
||||||
IVertexFormat* vtxFormat,
|
IVertexFormat* vtxFormat,
|
||||||
size_t ubufCount, IGraphicsBuffer** ubufs,
|
size_t ubufCount, IGraphicsBuffer** ubufs,
|
||||||
const size_t* ubufOffs, const size_t* ubufSizes,
|
const size_t* ubufOffs, const size_t* ubufSizes,
|
||||||
size_t texCount, ITexture** texs)
|
size_t texCount, ITexture** texs,
|
||||||
|
const int* bindTexIdx,
|
||||||
|
const bool* depthBind)
|
||||||
: IShaderDataBindingPriv(d),
|
: IShaderDataBindingPriv(d),
|
||||||
m_pipeline(static_cast<GLShaderPipeline*>(pipeline)),
|
m_pipeline(static_cast<GLShaderPipeline*>(pipeline)),
|
||||||
m_vtxFormat(static_cast<GLVertexFormat*>(vtxFormat)),
|
m_vtxFormat(static_cast<GLVertexFormat*>(vtxFormat)),
|
||||||
m_ubufCount(ubufCount),
|
m_ubufCount(ubufCount),
|
||||||
m_ubufs(new IGraphicsBuffer*[ubufCount]),
|
m_ubufs(new IGraphicsBuffer*[ubufCount]),
|
||||||
m_texCount(texCount),
|
m_texCount(texCount),
|
||||||
m_texs(new ITexture*[texCount])
|
m_texs(new BoundTex[texCount])
|
||||||
{
|
{
|
||||||
|
addDepData(m_pipeline->m_parentData);
|
||||||
|
addDepData(m_vtxFormat->m_parentData);
|
||||||
if (ubufOffs && ubufSizes)
|
if (ubufOffs && ubufSizes)
|
||||||
{
|
{
|
||||||
m_ubufOffs.reserve(ubufCount);
|
m_ubufOffs.reserve(ubufCount);
|
||||||
|
@ -699,9 +766,15 @@ struct GLShaderDataBinding : IShaderDataBindingPriv<GLData>
|
||||||
Log.report(logvisor::Fatal, "null uniform-buffer %d provided to newShaderDataBinding", int(i));
|
Log.report(logvisor::Fatal, "null uniform-buffer %d provided to newShaderDataBinding", int(i));
|
||||||
#endif
|
#endif
|
||||||
m_ubufs[i] = ubufs[i];
|
m_ubufs[i] = ubufs[i];
|
||||||
|
if (ubufs[i])
|
||||||
|
addDepData(ubufs[i]->m_parentData);
|
||||||
}
|
}
|
||||||
for (size_t i=0 ; i<texCount ; ++i)
|
for (size_t i=0 ; i<texCount ; ++i)
|
||||||
m_texs[i] = texs[i];
|
{
|
||||||
|
m_texs[i] = {texs[i], bindTexIdx ? bindTexIdx[i] : 0, depthBind ? depthBind[i] : false};
|
||||||
|
if (texs[i])
|
||||||
|
addDepData(texs[i]->m_parentData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void bind(int b) const
|
void bind(int b) const
|
||||||
{
|
{
|
||||||
|
@ -740,22 +813,22 @@ struct GLShaderDataBinding : IShaderDataBindingPriv<GLData>
|
||||||
}
|
}
|
||||||
for (size_t i=0 ; i<m_texCount ; ++i)
|
for (size_t i=0 ; i<m_texCount ; ++i)
|
||||||
{
|
{
|
||||||
ITexture* tex = m_texs[i];
|
BoundTex& tex = m_texs[i];
|
||||||
if (tex)
|
if (tex.tex)
|
||||||
{
|
{
|
||||||
switch (tex->type())
|
switch (tex.tex->type())
|
||||||
{
|
{
|
||||||
case TextureType::Dynamic:
|
case TextureType::Dynamic:
|
||||||
static_cast<GLTextureD*>(tex)->bind(i, b);
|
static_cast<GLTextureD*>(tex.tex)->bind(i, b);
|
||||||
break;
|
break;
|
||||||
case TextureType::Static:
|
case TextureType::Static:
|
||||||
static_cast<GLTextureS*>(tex)->bind(i);
|
static_cast<GLTextureS*>(tex.tex)->bind(i);
|
||||||
break;
|
break;
|
||||||
case TextureType::StaticArray:
|
case TextureType::StaticArray:
|
||||||
static_cast<GLTextureSA*>(tex)->bind(i);
|
static_cast<GLTextureSA*>(tex.tex)->bind(i);
|
||||||
break;
|
break;
|
||||||
case TextureType::Render:
|
case TextureType::Render:
|
||||||
static_cast<GLTextureR*>(tex)->bind(i);
|
static_cast<GLTextureR*>(tex.tex)->bind(i, tex.idx, tex.depth);
|
||||||
break;
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
@ -770,11 +843,13 @@ GLDataFactory::Context::newShaderDataBinding(IShaderPipeline* pipeline,
|
||||||
IGraphicsBuffer*, IGraphicsBuffer*, IGraphicsBuffer*,
|
IGraphicsBuffer*, IGraphicsBuffer*, IGraphicsBuffer*,
|
||||||
size_t ubufCount, IGraphicsBuffer** ubufs, const PipelineStage* ubufStages,
|
size_t ubufCount, IGraphicsBuffer** ubufs, const PipelineStage* ubufStages,
|
||||||
const size_t* ubufOffs, const size_t* ubufSizes,
|
const size_t* ubufOffs, const size_t* ubufSizes,
|
||||||
size_t texCount, ITexture** texs, size_t baseVert, size_t baseInst)
|
size_t texCount, ITexture** texs,
|
||||||
|
const int* texBindIdx, const bool* depthBind,
|
||||||
|
size_t baseVert, size_t baseInst)
|
||||||
{
|
{
|
||||||
GLShaderDataBinding* retval =
|
GLShaderDataBinding* retval =
|
||||||
new GLShaderDataBinding(GLDataFactoryImpl::m_deferredData.get(), pipeline, vtxFormat, ubufCount, ubufs,
|
new GLShaderDataBinding(GLDataFactoryImpl::m_deferredData.get(), pipeline, vtxFormat, ubufCount, ubufs,
|
||||||
ubufOffs, ubufSizes, texCount, texs);
|
ubufOffs, ubufSizes, texCount, texs, texBindIdx, depthBind);
|
||||||
GLDataFactoryImpl::m_deferredData->m_SBinds.emplace_back(retval);
|
GLDataFactoryImpl::m_deferredData->m_SBinds.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -806,7 +881,7 @@ GraphicsDataToken GLDataFactoryImpl::commitTransaction(const FactoryCommitFunc&
|
||||||
/* Let's go ahead and flush to ensure our data gets to the GPU
|
/* Let's go ahead and flush to ensure our data gets to the GPU
|
||||||
While this isn't strictly required, some drivers might behave
|
While this isn't strictly required, some drivers might behave
|
||||||
differently */
|
differently */
|
||||||
glFlush();
|
//glFlush();
|
||||||
return GraphicsDataToken(this, retval);
|
return GraphicsDataToken(this, retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -831,8 +906,8 @@ void GLDataFactoryImpl::destroyAllData()
|
||||||
std::unique_lock<std::mutex> lk(m_committedMutex);
|
std::unique_lock<std::mutex> lk(m_committedMutex);
|
||||||
for (GLData* data : m_committedData)
|
for (GLData* data : m_committedData)
|
||||||
data->decrement();
|
data->decrement();
|
||||||
for (IGraphicsBufferPool* pool : m_committedPools)
|
for (GLPool* pool : m_committedPools)
|
||||||
delete static_cast<GLPool*>(pool);
|
delete pool;
|
||||||
m_committedData.clear();
|
m_committedData.clear();
|
||||||
m_committedPools.clear();
|
m_committedPools.clear();
|
||||||
}
|
}
|
||||||
|
@ -849,15 +924,22 @@ IGraphicsBufferD* GLDataFactoryImpl::newPoolBuffer(IGraphicsBufferPool* p, Buffe
|
||||||
size_t stride, size_t count)
|
size_t stride, size_t count)
|
||||||
{
|
{
|
||||||
GLPool* pool = static_cast<GLPool*>(p);
|
GLPool* pool = static_cast<GLPool*>(p);
|
||||||
GLGraphicsBufferD* retval = new GLGraphicsBufferD(use, stride * count);
|
GLPoolItem* item = new GLPoolItem;
|
||||||
pool->m_DBufs.emplace(std::make_pair(retval, std::unique_ptr<GLGraphicsBufferD>(retval)));
|
GLGraphicsBufferD* retval = new GLGraphicsBufferD(item, use, stride * count);
|
||||||
|
item->m_buf.reset(retval);
|
||||||
|
pool->m_items.emplace(item);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLDataFactoryImpl::deletePoolBuffer(IGraphicsBufferPool *p, IGraphicsBufferD *buf)
|
void GLDataFactoryImpl::deletePoolBuffer(IGraphicsBufferPool* p, IGraphicsBufferD* buf)
|
||||||
{
|
{
|
||||||
GLPool* pool = static_cast<GLPool*>(p);
|
GLPool* pool = static_cast<GLPool*>(p);
|
||||||
pool->m_DBufs.erase(static_cast<GLGraphicsBufferD*>(buf));
|
auto search = pool->m_items.find(static_cast<GLPoolItem*>(buf->m_parentData));
|
||||||
|
if (search != pool->m_items.end())
|
||||||
|
{
|
||||||
|
(*search)->decrement();
|
||||||
|
pool->m_items.erase(search);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const GLint SEMANTIC_COUNT_TABLE[] =
|
static const GLint SEMANTIC_COUNT_TABLE[] =
|
||||||
|
@ -911,6 +993,13 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||||
const SystemChar* platformName() const {return _S("OpenGL");}
|
const SystemChar* platformName() const {return _S("OpenGL");}
|
||||||
IGraphicsContext* m_parent = nullptr;
|
IGraphicsContext* m_parent = nullptr;
|
||||||
|
|
||||||
|
std::mutex m_mt;
|
||||||
|
std::condition_variable m_cv;
|
||||||
|
std::mutex m_initmt;
|
||||||
|
std::condition_variable m_initcv;
|
||||||
|
std::unique_lock<std::mutex> m_initlk;
|
||||||
|
std::thread m_thr;
|
||||||
|
|
||||||
struct Command
|
struct Command
|
||||||
{
|
{
|
||||||
enum class Op
|
enum class Op
|
||||||
|
@ -947,8 +1036,9 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||||
size_t instCount;
|
size_t instCount;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
IShaderDataBindingPriv<GLData>::Token resToken;
|
IShaderDataBindingPriv::Token resToken;
|
||||||
const ITextureR* resolveTex;
|
const ITextureR* resolveTex;
|
||||||
|
int bindIdx;
|
||||||
bool resolveColor : 1;
|
bool resolveColor : 1;
|
||||||
bool resolveDepth : 1;
|
bool resolveDepth : 1;
|
||||||
Command(Op op) : m_op(op) {}
|
Command(Op op) : m_op(op) {}
|
||||||
|
@ -963,13 +1053,6 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||||
size_t m_drawBuf = 0;
|
size_t m_drawBuf = 0;
|
||||||
bool m_running = true;
|
bool m_running = true;
|
||||||
|
|
||||||
std::mutex m_mt;
|
|
||||||
std::condition_variable m_cv;
|
|
||||||
std::mutex m_initmt;
|
|
||||||
std::condition_variable m_initcv;
|
|
||||||
std::unique_lock<std::mutex> m_initlk;
|
|
||||||
std::thread m_thr;
|
|
||||||
|
|
||||||
struct RenderTextureResize
|
struct RenderTextureResize
|
||||||
{
|
{
|
||||||
GLTextureR* tex;
|
GLTextureR* tex;
|
||||||
|
@ -1064,6 +1147,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||||
const GLubyte* version = glGetString(GL_VERSION);
|
const GLubyte* version = glGetString(GL_VERSION);
|
||||||
Log.report(logvisor::Info, "OpenGL Version: %s", version);
|
Log.report(logvisor::Info, "OpenGL Version: %s", version);
|
||||||
self->m_parent->postInit();
|
self->m_parent->postInit();
|
||||||
|
glClearColor(0.f, 0.f, 0.f, 0.f);
|
||||||
}
|
}
|
||||||
self->m_initcv.notify_one();
|
self->m_initcv.notify_one();
|
||||||
while (self->m_running)
|
while (self->m_running)
|
||||||
|
@ -1157,6 +1241,8 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||||
glClearColor(cmd.rgba[0], cmd.rgba[1], cmd.rgba[2], cmd.rgba[3]);
|
glClearColor(cmd.rgba[0], cmd.rgba[1], cmd.rgba[2], cmd.rgba[3]);
|
||||||
break;
|
break;
|
||||||
case Command::Op::ClearTarget:
|
case Command::Op::ClearTarget:
|
||||||
|
if (cmd.flags & GL_COLOR_BUFFER_BIT)
|
||||||
|
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||||
if (cmd.flags & GL_DEPTH_BUFFER_BIT)
|
if (cmd.flags & GL_DEPTH_BUFFER_BIT)
|
||||||
glDepthMask(GL_TRUE);
|
glDepthMask(GL_TRUE);
|
||||||
glClear(cmd.flags);
|
glClear(cmd.flags);
|
||||||
|
@ -1181,16 +1267,16 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||||
GLenum target = (tex->m_samples > 1) ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D;
|
GLenum target = (tex->m_samples > 1) ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D;
|
||||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, tex->m_fbo);
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, tex->m_fbo);
|
||||||
glActiveTexture(GL_TEXTURE9);
|
glActiveTexture(GL_TEXTURE9);
|
||||||
if (cmd.resolveColor && tex->m_bindTexs[0])
|
if (cmd.resolveColor && tex->m_bindTexs[0][cmd.bindIdx])
|
||||||
{
|
{
|
||||||
glBindTexture(target, tex->m_bindTexs[0]);
|
glBindTexture(target, tex->m_bindTexs[0][cmd.bindIdx]);
|
||||||
glCopyTexSubImage2D(target, 0, cmd.viewport.rect.location[0], cmd.viewport.rect.location[1],
|
glCopyTexSubImage2D(target, 0, cmd.viewport.rect.location[0], cmd.viewport.rect.location[1],
|
||||||
cmd.viewport.rect.location[0], cmd.viewport.rect.location[1],
|
cmd.viewport.rect.location[0], cmd.viewport.rect.location[1],
|
||||||
cmd.viewport.rect.size[0], cmd.viewport.rect.size[1]);
|
cmd.viewport.rect.size[0], cmd.viewport.rect.size[1]);
|
||||||
}
|
}
|
||||||
if (cmd.resolveDepth && tex->m_bindTexs[1])
|
if (cmd.resolveDepth && tex->m_bindTexs[1][cmd.bindIdx])
|
||||||
{
|
{
|
||||||
glBindTexture(target, tex->m_bindTexs[1]);
|
glBindTexture(target, tex->m_bindTexs[1][cmd.bindIdx]);
|
||||||
glCopyTexSubImage2D(target, 0, cmd.viewport.rect.location[0], cmd.viewport.rect.location[1],
|
glCopyTexSubImage2D(target, 0, cmd.viewport.rect.location[0], cmd.viewport.rect.location[1],
|
||||||
cmd.viewport.rect.location[0], cmd.viewport.rect.location[1],
|
cmd.viewport.rect.location[0], cmd.viewport.rect.location[1],
|
||||||
cmd.viewport.rect.size[0], cmd.viewport.rect.size[1]);
|
cmd.viewport.rect.size[0], cmd.viewport.rect.size[1]);
|
||||||
|
@ -1230,14 +1316,20 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||||
|
|
||||||
void stopRenderer()
|
void stopRenderer()
|
||||||
{
|
{
|
||||||
m_running = false;
|
if (m_running)
|
||||||
m_cv.notify_one();
|
{
|
||||||
m_thr.join();
|
m_running = false;
|
||||||
|
m_cv.notify_one();
|
||||||
|
if (m_thr.joinable())
|
||||||
|
m_thr.join();
|
||||||
|
for (int i=0 ; i<3 ; ++i)
|
||||||
|
m_cmdBufs[i].clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~GLCommandQueue()
|
~GLCommandQueue()
|
||||||
{
|
{
|
||||||
if (m_running) stopRenderer();
|
stopRenderer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setShaderDataBinding(IShaderDataBinding* binding)
|
void setShaderDataBinding(IShaderDataBinding* binding)
|
||||||
|
@ -1245,7 +1337,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||||
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
|
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
|
||||||
cmds.emplace_back(Command::Op::SetShaderDataBinding);
|
cmds.emplace_back(Command::Op::SetShaderDataBinding);
|
||||||
cmds.back().binding = binding;
|
cmds.back().binding = binding;
|
||||||
cmds.back().resToken = static_cast<IShaderDataBindingPriv<GLData>*>(binding)->lock();
|
cmds.back().resToken = static_cast<IShaderDataBindingPriv*>(binding)->lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setRenderTarget(ITextureR* target)
|
void setRenderTarget(ITextureR* target)
|
||||||
|
@ -1338,12 +1430,14 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||||
cmds.back().instCount = instCount;
|
cmds.back().instCount = instCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
void resolveBindTexture(ITextureR* texture, const SWindowRect& rect, bool tlOrigin, bool color, bool depth)
|
void resolveBindTexture(ITextureR* texture, const SWindowRect& rect, bool tlOrigin,
|
||||||
|
int bindIdx, bool color, bool depth)
|
||||||
{
|
{
|
||||||
GLTextureR* tex = static_cast<GLTextureR*>(texture);
|
GLTextureR* tex = static_cast<GLTextureR*>(texture);
|
||||||
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
|
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
|
||||||
cmds.emplace_back(Command::Op::ResolveBindTexture);
|
cmds.emplace_back(Command::Op::ResolveBindTexture);
|
||||||
cmds.back().resolveTex = texture;
|
cmds.back().resolveTex = texture;
|
||||||
|
cmds.back().bindIdx = bindIdx;
|
||||||
cmds.back().resolveColor = color;
|
cmds.back().resolveColor = color;
|
||||||
cmds.back().resolveDepth = depth;
|
cmds.back().resolveDepth = depth;
|
||||||
SWindowRect intersectRect = rect.intersect(SWindowRect(0, 0, tex->m_width, tex->m_height));
|
SWindowRect intersectRect = rect.intersect(SWindowRect(0, 0, tex->m_width, tex->m_height));
|
||||||
|
@ -1421,11 +1515,11 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||||
}
|
}
|
||||||
for (GLPool* p : gfxF->m_committedPools)
|
for (GLPool* p : gfxF->m_committedPools)
|
||||||
{
|
{
|
||||||
for (auto& b : p->m_DBufs)
|
for (auto& b : p->m_items)
|
||||||
b.second->update(m_completeBuf);
|
b->m_buf->update(m_completeBuf);
|
||||||
}
|
}
|
||||||
datalk.unlock();
|
datalk.unlock();
|
||||||
glFlush();
|
//glFlush();
|
||||||
|
|
||||||
for (auto& p : m_pendingPosts1)
|
for (auto& p : m_pendingPosts1)
|
||||||
m_pendingPosts2.push_back(std::move(p));
|
m_pendingPosts2.push_back(std::move(p));
|
||||||
|
@ -1476,13 +1570,14 @@ void GLGraphicsBufferD::bindUniformRange(size_t idx, GLintptr off, GLsizeiptr si
|
||||||
IGraphicsBufferD*
|
IGraphicsBufferD*
|
||||||
GLDataFactory::Context::newDynamicBuffer(BufferUse use, size_t stride, size_t count)
|
GLDataFactory::Context::newDynamicBuffer(BufferUse use, size_t stride, size_t count)
|
||||||
{
|
{
|
||||||
GLGraphicsBufferD* retval = new GLGraphicsBufferD(use, stride * count);
|
GLData* d = GLDataFactoryImpl::m_deferredData.get();
|
||||||
GLDataFactoryImpl::m_deferredData->m_DBufs.emplace_back(retval);
|
GLGraphicsBufferD* retval = new GLGraphicsBufferD(d, use, stride * count);
|
||||||
|
d->m_DBufs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLTextureD::GLTextureD(size_t width, size_t height, TextureFormat fmt)
|
GLTextureD::GLTextureD(IGraphicsData* parent, size_t width, size_t height, TextureFormat fmt)
|
||||||
: m_width(width), m_height(height)
|
: boo::ITextureD(parent), m_width(width), m_height(height)
|
||||||
{
|
{
|
||||||
int pxPitch = 4;
|
int pxPitch = 4;
|
||||||
switch (fmt)
|
switch (fmt)
|
||||||
|
@ -1551,20 +1646,29 @@ void GLTextureD::bind(size_t idx, int b)
|
||||||
ITextureD*
|
ITextureD*
|
||||||
GLDataFactory::Context::newDynamicTexture(size_t width, size_t height, TextureFormat fmt)
|
GLDataFactory::Context::newDynamicTexture(size_t width, size_t height, TextureFormat fmt)
|
||||||
{
|
{
|
||||||
GLTextureD* retval = new GLTextureD(width, height, fmt);
|
GLData* d = GLDataFactoryImpl::m_deferredData.get();
|
||||||
GLDataFactoryImpl::m_deferredData->m_DTexs.emplace_back(retval);
|
GLTextureD* retval = new GLTextureD(d, width, height, fmt);
|
||||||
|
d->m_DTexs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLTextureR::GLTextureR(GLCommandQueue* q, size_t width, size_t height, size_t samples,
|
GLTextureR::GLTextureR(IGraphicsData* parent, GLCommandQueue* q, size_t width, size_t height, size_t samples,
|
||||||
bool enableShaderColorBinding, bool enableShaderDepthBinding)
|
size_t colorBindingCount, size_t depthBindingCount)
|
||||||
: m_q(q), m_width(width), m_height(height), m_samples(samples)
|
: boo::ITextureR(parent), m_q(q), m_width(width), m_height(height), m_samples(samples)
|
||||||
{
|
{
|
||||||
glGenTextures(2, m_texs);
|
glGenTextures(2, m_texs);
|
||||||
if (enableShaderColorBinding)
|
if (colorBindingCount)
|
||||||
glGenTextures(1, &m_bindTexs[0]);
|
{
|
||||||
if (enableShaderDepthBinding)
|
if (colorBindingCount > MAX_BIND_TEXS)
|
||||||
glGenTextures(1, &m_bindTexs[1]);
|
Log.report(logvisor::Fatal, "too many color bindings for render texture");
|
||||||
|
glGenTextures(colorBindingCount, m_bindTexs[0]);
|
||||||
|
}
|
||||||
|
if (depthBindingCount)
|
||||||
|
{
|
||||||
|
if (depthBindingCount > MAX_BIND_TEXS)
|
||||||
|
Log.report(logvisor::Fatal, "too many depth bindings for render texture");
|
||||||
|
glGenTextures(depthBindingCount, m_bindTexs[1]);
|
||||||
|
}
|
||||||
if (samples > 1)
|
if (samples > 1)
|
||||||
{
|
{
|
||||||
m_target = GL_TEXTURE_2D_MULTISAMPLE;
|
m_target = GL_TEXTURE_2D_MULTISAMPLE;
|
||||||
|
@ -1573,14 +1677,15 @@ GLTextureR::GLTextureR(GLCommandQueue* q, size_t width, size_t height, size_t sa
|
||||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_texs[1]);
|
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_texs[1]);
|
||||||
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_DEPTH_COMPONENT24, width, height, GL_FALSE);
|
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_DEPTH_COMPONENT24, width, height, GL_FALSE);
|
||||||
|
|
||||||
if (enableShaderColorBinding)
|
for (int i=0 ; i<colorBindingCount ; ++i)
|
||||||
{
|
{
|
||||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_bindTexs[0]);
|
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_bindTexs[0][i]);
|
||||||
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGBA, width, height, GL_FALSE);
|
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGBA, width, height, GL_FALSE);
|
||||||
}
|
}
|
||||||
if (enableShaderDepthBinding)
|
|
||||||
|
for (int i=0 ; i<depthBindingCount ; ++i)
|
||||||
{
|
{
|
||||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_bindTexs[1]);
|
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_bindTexs[1][i]);
|
||||||
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_DEPTH_COMPONENT24, width, height, GL_FALSE);
|
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_DEPTH_COMPONENT24, width, height, GL_FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1592,16 +1697,16 @@ GLTextureR::GLTextureR(GLCommandQueue* q, size_t width, size_t height, size_t sa
|
||||||
glBindTexture(GL_TEXTURE_2D, m_texs[1]);
|
glBindTexture(GL_TEXTURE_2D, m_texs[1]);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
|
||||||
|
|
||||||
if (enableShaderColorBinding)
|
for (int i=0 ; i<colorBindingCount ; ++i)
|
||||||
{
|
{
|
||||||
glBindTexture(GL_TEXTURE_2D, m_bindTexs[0]);
|
glBindTexture(GL_TEXTURE_2D, m_bindTexs[0][i]);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
}
|
}
|
||||||
if (enableShaderDepthBinding)
|
for (int i=0 ; i<depthBindingCount ; ++i)
|
||||||
{
|
{
|
||||||
glBindTexture(GL_TEXTURE_2D, m_bindTexs[1]);
|
glBindTexture(GL_TEXTURE_2D, m_bindTexs[1][i]);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
@ -1612,27 +1717,29 @@ GLTextureR::GLTextureR(GLCommandQueue* q, size_t width, size_t height, size_t sa
|
||||||
GLTextureR::~GLTextureR()
|
GLTextureR::~GLTextureR()
|
||||||
{
|
{
|
||||||
glDeleteTextures(2, m_texs);
|
glDeleteTextures(2, m_texs);
|
||||||
glDeleteTextures(2, m_bindTexs);
|
glDeleteTextures(MAX_BIND_TEXS * 2, m_bindTexs[0]);
|
||||||
m_q->delFBO(this);
|
m_q->delFBO(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
ITextureR*
|
ITextureR*
|
||||||
GLDataFactory::Context::newRenderTexture(size_t width, size_t height,
|
GLDataFactory::Context::newRenderTexture(size_t width, size_t height,
|
||||||
bool enableShaderColorBinding, bool enableShaderDepthBinding)
|
size_t colorBindingCount, size_t depthBindingCount)
|
||||||
{
|
{
|
||||||
|
GLData* d = GLDataFactoryImpl::m_deferredData.get();
|
||||||
GLDataFactoryImpl& factory = static_cast<GLDataFactoryImpl&>(m_parent);
|
GLDataFactoryImpl& factory = static_cast<GLDataFactoryImpl&>(m_parent);
|
||||||
GLCommandQueue* q = static_cast<GLCommandQueue*>(factory.m_parent->getCommandQueue());
|
GLCommandQueue* q = static_cast<GLCommandQueue*>(factory.m_parent->getCommandQueue());
|
||||||
GLTextureR* retval = new GLTextureR(q, width, height, factory.m_drawSamples,
|
GLTextureR* retval = new GLTextureR(d, q, width, height, factory.m_drawSamples,
|
||||||
enableShaderColorBinding, enableShaderDepthBinding);
|
colorBindingCount, depthBindingCount);
|
||||||
q->resizeRenderTexture(retval, width, height);
|
q->resizeRenderTexture(retval, width, height);
|
||||||
GLDataFactoryImpl::m_deferredData->m_RTexs.emplace_back(retval);
|
GLDataFactoryImpl::m_deferredData->m_RTexs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLVertexFormat::GLVertexFormat(GLCommandQueue* q, size_t elementCount,
|
GLVertexFormat::GLVertexFormat(IGraphicsData* parent, GLCommandQueue* q, size_t elementCount,
|
||||||
const VertexElementDescriptor* elements,
|
const VertexElementDescriptor* elements,
|
||||||
size_t baseVert, size_t baseInst)
|
size_t baseVert, size_t baseInst)
|
||||||
: m_q(q),
|
: boo::IVertexFormat(parent),
|
||||||
|
m_q(q),
|
||||||
m_elementCount(elementCount),
|
m_elementCount(elementCount),
|
||||||
m_elements(new VertexElementDescriptor[elementCount]),
|
m_elements(new VertexElementDescriptor[elementCount]),
|
||||||
m_baseVert(baseVert), m_baseInst(baseInst)
|
m_baseVert(baseVert), m_baseInst(baseInst)
|
||||||
|
@ -1647,10 +1754,11 @@ IVertexFormat* GLDataFactory::Context::newVertexFormat
|
||||||
(size_t elementCount, const VertexElementDescriptor* elements,
|
(size_t elementCount, const VertexElementDescriptor* elements,
|
||||||
size_t baseVert, size_t baseInst)
|
size_t baseVert, size_t baseInst)
|
||||||
{
|
{
|
||||||
|
GLData* d = GLDataFactoryImpl::m_deferredData.get();
|
||||||
GLDataFactoryImpl& factory = static_cast<GLDataFactoryImpl&>(m_parent);
|
GLDataFactoryImpl& factory = static_cast<GLDataFactoryImpl&>(m_parent);
|
||||||
GLCommandQueue* q = static_cast<GLCommandQueue*>(factory.m_parent->getCommandQueue());
|
GLCommandQueue* q = static_cast<GLCommandQueue*>(factory.m_parent->getCommandQueue());
|
||||||
GLVertexFormat* retval = new struct GLVertexFormat(q, elementCount, elements, baseVert, baseInst);
|
GLVertexFormat* retval = new struct GLVertexFormat(d, q, elementCount, elements, baseVert, baseInst);
|
||||||
GLDataFactoryImpl::m_deferredData->m_VFmts.emplace_back(retval);
|
d->m_VFmts.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
ThreadLocalPtr<struct MetalData> MetalDataFactoryImpl::m_deferredData;
|
ThreadLocalPtr<struct MetalData> MetalDataFactoryImpl::m_deferredData;
|
||||||
struct MetalData : IGraphicsDataPriv<MetalData>
|
struct MetalData : IGraphicsDataPriv
|
||||||
{
|
{
|
||||||
std::vector<std::unique_ptr<class MetalShaderPipeline>> m_SPs;
|
std::vector<std::unique_ptr<class MetalShaderPipeline>> m_SPs;
|
||||||
std::vector<std::unique_ptr<struct MetalShaderDataBinding>> m_SBinds;
|
std::vector<std::unique_ptr<struct MetalShaderDataBinding>> m_SBinds;
|
||||||
|
@ -75,9 +75,19 @@ struct MetalData : IGraphicsDataPriv<MetalData>
|
||||||
std::vector<std::unique_ptr<struct MetalVertexFormat>> m_VFmts;
|
std::vector<std::unique_ptr<struct MetalVertexFormat>> m_VFmts;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MetalPoolItem : IGraphicsDataPriv
|
||||||
|
{
|
||||||
|
std::unique_ptr<class MetalGraphicsBufferD> m_buf;
|
||||||
|
};
|
||||||
|
|
||||||
struct MetalPool : IGraphicsBufferPool
|
struct MetalPool : IGraphicsBufferPool
|
||||||
{
|
{
|
||||||
std::unordered_map<class MetalGraphicsBufferD*, std::unique_ptr<class MetalGraphicsBufferD>> m_DBufs;
|
std::unordered_set<MetalPoolItem*> m_items;
|
||||||
|
~MetalPool()
|
||||||
|
{
|
||||||
|
for (auto& item : m_items)
|
||||||
|
item->decrement();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MTL_STATIC MTLResourceCPUCacheModeWriteCombined|MTLResourceStorageModeShared
|
#define MTL_STATIC MTLResourceCPUCacheModeWriteCombined|MTLResourceStorageModeShared
|
||||||
|
@ -87,8 +97,9 @@ class MetalGraphicsBufferS : public IGraphicsBufferS
|
||||||
{
|
{
|
||||||
friend class MetalDataFactory;
|
friend class MetalDataFactory;
|
||||||
friend struct MetalCommandQueue;
|
friend struct MetalCommandQueue;
|
||||||
MetalGraphicsBufferS(BufferUse use, MetalContext* ctx, const void* data, size_t stride, size_t count)
|
MetalGraphicsBufferS(IGraphicsData* parent, BufferUse use, MetalContext* ctx,
|
||||||
: m_stride(stride), m_count(count), m_sz(stride * count)
|
const void* data, size_t stride, size_t count)
|
||||||
|
: boo::IGraphicsBufferS(parent), m_stride(stride), m_count(count), m_sz(stride * count)
|
||||||
{
|
{
|
||||||
m_buf = [ctx->m_dev newBufferWithBytes:data length:m_sz options:MTL_STATIC];
|
m_buf = [ctx->m_dev newBufferWithBytes:data length:m_sz options:MTL_STATIC];
|
||||||
}
|
}
|
||||||
|
@ -108,8 +119,9 @@ class MetalGraphicsBufferD : public IGraphicsBufferD
|
||||||
MetalCommandQueue* m_q;
|
MetalCommandQueue* m_q;
|
||||||
std::unique_ptr<uint8_t[]> m_cpuBuf;
|
std::unique_ptr<uint8_t[]> m_cpuBuf;
|
||||||
int m_validSlots = 0;
|
int m_validSlots = 0;
|
||||||
MetalGraphicsBufferD(MetalCommandQueue* q, BufferUse use, MetalContext* ctx, size_t stride, size_t count)
|
MetalGraphicsBufferD(IGraphicsData* parent, MetalCommandQueue* q, BufferUse use,
|
||||||
: m_q(q), m_stride(stride), m_count(count), m_sz(stride * count)
|
MetalContext* ctx, size_t stride, size_t count)
|
||||||
|
: boo::IGraphicsBufferD(parent), m_q(q), m_stride(stride), m_count(count), m_sz(stride * count)
|
||||||
{
|
{
|
||||||
m_cpuBuf.reset(new uint8_t[m_sz]);
|
m_cpuBuf.reset(new uint8_t[m_sz]);
|
||||||
m_bufs[0] = [ctx->m_dev newBufferWithLength:m_sz options:MTL_DYNAMIC];
|
m_bufs[0] = [ctx->m_dev newBufferWithLength:m_sz options:MTL_DYNAMIC];
|
||||||
|
@ -131,8 +143,9 @@ public:
|
||||||
class MetalTextureS : public ITextureS
|
class MetalTextureS : public ITextureS
|
||||||
{
|
{
|
||||||
friend class MetalDataFactory;
|
friend class MetalDataFactory;
|
||||||
MetalTextureS(MetalContext* ctx, size_t width, size_t height, size_t mips,
|
MetalTextureS(IGraphicsData* parent, MetalContext* ctx, size_t width, size_t height, size_t mips,
|
||||||
TextureFormat fmt, const void* data, size_t sz)
|
TextureFormat fmt, const void* data, size_t sz)
|
||||||
|
: ITextureS(parent)
|
||||||
{
|
{
|
||||||
MTLPixelFormat pfmt = MTLPixelFormatRGBA8Unorm;
|
MTLPixelFormat pfmt = MTLPixelFormatRGBA8Unorm;
|
||||||
NSUInteger ppitchNum = 4;
|
NSUInteger ppitchNum = 4;
|
||||||
|
@ -182,8 +195,10 @@ public:
|
||||||
class MetalTextureSA : public ITextureSA
|
class MetalTextureSA : public ITextureSA
|
||||||
{
|
{
|
||||||
friend class MetalDataFactory;
|
friend class MetalDataFactory;
|
||||||
MetalTextureSA(MetalContext* ctx, size_t width, size_t height, size_t layers, size_t mips,
|
MetalTextureSA(IGraphicsData* parent, MetalContext* ctx, size_t width,
|
||||||
|
size_t height, size_t layers, size_t mips,
|
||||||
TextureFormat fmt, const void* data, size_t sz)
|
TextureFormat fmt, const void* data, size_t sz)
|
||||||
|
: ITextureSA(parent)
|
||||||
{
|
{
|
||||||
MTLPixelFormat pfmt = MTLPixelFormatRGBA8Unorm;
|
MTLPixelFormat pfmt = MTLPixelFormatRGBA8Unorm;
|
||||||
NSUInteger ppitch = 4;
|
NSUInteger ppitch = 4;
|
||||||
|
@ -243,8 +258,9 @@ class MetalTextureD : public ITextureD
|
||||||
size_t m_cpuSz;
|
size_t m_cpuSz;
|
||||||
size_t m_pxPitch;
|
size_t m_pxPitch;
|
||||||
int m_validSlots = 0;
|
int m_validSlots = 0;
|
||||||
MetalTextureD(MetalCommandQueue* q, MetalContext* ctx, size_t width, size_t height, TextureFormat fmt)
|
MetalTextureD(IGraphicsData* parent, MetalCommandQueue* q, MetalContext* ctx,
|
||||||
: m_q(q), m_width(width), m_height(height)
|
size_t width, size_t height, TextureFormat fmt)
|
||||||
|
: boo::ITextureD(parent), m_q(q), m_width(width), m_height(height)
|
||||||
{
|
{
|
||||||
MTLPixelFormat format;
|
MTLPixelFormat format;
|
||||||
switch (fmt)
|
switch (fmt)
|
||||||
|
@ -285,6 +301,8 @@ public:
|
||||||
void unmap();
|
void unmap();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MAX_BIND_TEXS 4
|
||||||
|
|
||||||
class MetalTextureR : public ITextureR
|
class MetalTextureR : public ITextureR
|
||||||
{
|
{
|
||||||
friend class MetalDataFactory;
|
friend class MetalDataFactory;
|
||||||
|
@ -292,14 +310,20 @@ class MetalTextureR : public ITextureR
|
||||||
size_t m_width = 0;
|
size_t m_width = 0;
|
||||||
size_t m_height = 0;
|
size_t m_height = 0;
|
||||||
size_t m_samples = 0;
|
size_t m_samples = 0;
|
||||||
bool m_enableShaderBindTexture;
|
size_t m_colorBindCount;
|
||||||
|
size_t m_depthBindCount;
|
||||||
|
|
||||||
void Setup(MetalContext* ctx, size_t width, size_t height, size_t samples,
|
void Setup(MetalContext* ctx, size_t width, size_t height, size_t samples,
|
||||||
bool enableShaderBindTexture)
|
size_t colorBindCount, size_t depthBindCount)
|
||||||
{
|
{
|
||||||
m_width = width;
|
m_width = width;
|
||||||
m_height = height;
|
m_height = height;
|
||||||
|
|
||||||
|
if (colorBindCount > MAX_BIND_TEXS)
|
||||||
|
Log.report(logvisor::Fatal, "too many color bindings for render texture");
|
||||||
|
if (depthBindCount > MAX_BIND_TEXS)
|
||||||
|
Log.report(logvisor::Fatal, "too many depth bindings for render texture");
|
||||||
|
|
||||||
@autoreleasepool
|
@autoreleasepool
|
||||||
{
|
{
|
||||||
MTLTextureDescriptor* desc =
|
MTLTextureDescriptor* desc =
|
||||||
|
@ -315,15 +339,23 @@ class MetalTextureR : public ITextureR
|
||||||
desc.usage = MTLTextureUsageRenderTarget;
|
desc.usage = MTLTextureUsageRenderTarget;
|
||||||
m_colorTex = [ctx->m_dev newTextureWithDescriptor:desc];
|
m_colorTex = [ctx->m_dev newTextureWithDescriptor:desc];
|
||||||
|
|
||||||
if (enableShaderBindTexture)
|
if (colorBindCount)
|
||||||
{
|
{
|
||||||
desc.usage = MTLTextureUsageShaderRead;
|
desc.usage = MTLTextureUsageShaderRead;
|
||||||
m_colorBindTex = [ctx->m_dev newTextureWithDescriptor:desc];
|
for (int i=0 ; i<colorBindCount ; ++i)
|
||||||
|
m_colorBindTex[i] = [ctx->m_dev newTextureWithDescriptor:desc];
|
||||||
}
|
}
|
||||||
|
|
||||||
desc.usage = MTLTextureUsageRenderTarget;
|
desc.usage = MTLTextureUsageRenderTarget;
|
||||||
desc.pixelFormat = MTLPixelFormatDepth32Float;
|
desc.pixelFormat = MTLPixelFormatDepth32Float;
|
||||||
m_depthTex = [ctx->m_dev newTextureWithDescriptor:desc];
|
m_depthTex = [ctx->m_dev newTextureWithDescriptor:desc];
|
||||||
|
|
||||||
|
if (depthBindCount)
|
||||||
|
{
|
||||||
|
desc.usage = MTLTextureUsageShaderRead;
|
||||||
|
for (int i=0 ; i<depthBindCount ; ++i)
|
||||||
|
m_depthBindTex[i] = [ctx->m_dev newTextureWithDescriptor:desc];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -332,15 +364,23 @@ class MetalTextureR : public ITextureR
|
||||||
desc.usage = MTLTextureUsageRenderTarget;
|
desc.usage = MTLTextureUsageRenderTarget;
|
||||||
m_colorTex = [ctx->m_dev newTextureWithDescriptor:desc];
|
m_colorTex = [ctx->m_dev newTextureWithDescriptor:desc];
|
||||||
|
|
||||||
if (enableShaderBindTexture)
|
if (colorBindCount)
|
||||||
{
|
{
|
||||||
desc.usage = MTLTextureUsageShaderRead;
|
desc.usage = MTLTextureUsageShaderRead;
|
||||||
m_colorBindTex = [ctx->m_dev newTextureWithDescriptor:desc];
|
for (int i=0 ; i<colorBindCount ; ++i)
|
||||||
|
m_colorBindTex[i] = [ctx->m_dev newTextureWithDescriptor:desc];
|
||||||
}
|
}
|
||||||
|
|
||||||
desc.usage = MTLTextureUsageRenderTarget;
|
desc.usage = MTLTextureUsageRenderTarget;
|
||||||
desc.pixelFormat = MTLPixelFormatDepth32Float;
|
desc.pixelFormat = MTLPixelFormatDepth32Float;
|
||||||
m_depthTex = [ctx->m_dev newTextureWithDescriptor:desc];
|
m_depthTex = [ctx->m_dev newTextureWithDescriptor:desc];
|
||||||
|
|
||||||
|
if (depthBindCount)
|
||||||
|
{
|
||||||
|
desc.usage = MTLTextureUsageShaderRead;
|
||||||
|
for (int i=0 ; i<depthBindCount ; ++i)
|
||||||
|
m_depthBindTex[i] = [ctx->m_dev newTextureWithDescriptor:desc];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -375,6 +415,7 @@ class MetalTextureR : public ITextureR
|
||||||
m_clearColorPassDesc.colorAttachments[0].texture = m_colorTex;
|
m_clearColorPassDesc.colorAttachments[0].texture = m_colorTex;
|
||||||
m_clearColorPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear;
|
m_clearColorPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear;
|
||||||
m_clearColorPassDesc.colorAttachments[0].storeAction = MTLStoreActionStore;
|
m_clearColorPassDesc.colorAttachments[0].storeAction = MTLStoreActionStore;
|
||||||
|
m_clearDepthPassDesc.colorAttachments[0].clearColor = MTLClearColorMake(0.0, 0.0, 0.0, 0.0);
|
||||||
|
|
||||||
m_clearColorPassDesc.depthAttachment.texture = m_depthTex;
|
m_clearColorPassDesc.depthAttachment.texture = m_depthTex;
|
||||||
m_clearColorPassDesc.depthAttachment.loadAction = MTLLoadActionLoad;
|
m_clearColorPassDesc.depthAttachment.loadAction = MTLLoadActionLoad;
|
||||||
|
@ -388,6 +429,7 @@ class MetalTextureR : public ITextureR
|
||||||
m_clearBothPassDesc.colorAttachments[0].texture = m_colorTex;
|
m_clearBothPassDesc.colorAttachments[0].texture = m_colorTex;
|
||||||
m_clearBothPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear;
|
m_clearBothPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear;
|
||||||
m_clearBothPassDesc.colorAttachments[0].storeAction = MTLStoreActionStore;
|
m_clearBothPassDesc.colorAttachments[0].storeAction = MTLStoreActionStore;
|
||||||
|
m_clearBothPassDesc.colorAttachments[0].clearColor = MTLClearColorMake(0.0, 0.0, 0.0, 0.0);
|
||||||
|
|
||||||
m_clearBothPassDesc.depthAttachment.texture = m_depthTex;
|
m_clearBothPassDesc.depthAttachment.texture = m_depthTex;
|
||||||
m_clearBothPassDesc.depthAttachment.loadAction = MTLLoadActionClear;
|
m_clearBothPassDesc.depthAttachment.loadAction = MTLLoadActionClear;
|
||||||
|
@ -397,18 +439,21 @@ class MetalTextureR : public ITextureR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MetalTextureR(MetalContext* ctx, size_t width, size_t height, size_t samples,
|
MetalTextureR(IGraphicsData* parent, MetalContext* ctx, size_t width, size_t height, size_t samples,
|
||||||
bool enableShaderBindTexture)
|
size_t colorBindCount, size_t depthBindCount)
|
||||||
: m_width(width), m_height(height), m_samples(samples), m_enableShaderBindTexture(enableShaderBindTexture)
|
: boo::ITextureR(parent), m_width(width), m_height(height), m_samples(samples),
|
||||||
|
m_colorBindCount(colorBindCount),
|
||||||
|
m_depthBindCount(depthBindCount)
|
||||||
{
|
{
|
||||||
if (samples == 0) m_samples = 1;
|
if (samples == 0) m_samples = 1;
|
||||||
Setup(ctx, width, height, samples, enableShaderBindTexture);
|
Setup(ctx, width, height, samples, colorBindCount, depthBindCount);
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
size_t samples() const {return m_samples;}
|
size_t samples() const {return m_samples;}
|
||||||
id<MTLTexture> m_colorTex;
|
id<MTLTexture> m_colorTex;
|
||||||
id<MTLTexture> m_depthTex;
|
id<MTLTexture> m_depthTex;
|
||||||
id<MTLTexture> m_colorBindTex;
|
id<MTLTexture> m_colorBindTex[MAX_BIND_TEXS] = {};
|
||||||
|
id<MTLTexture> m_depthBindTex[MAX_BIND_TEXS] = {};
|
||||||
MTLRenderPassDescriptor* m_passDesc;
|
MTLRenderPassDescriptor* m_passDesc;
|
||||||
MTLRenderPassDescriptor* m_clearDepthPassDesc;
|
MTLRenderPassDescriptor* m_clearDepthPassDesc;
|
||||||
MTLRenderPassDescriptor* m_clearColorPassDesc;
|
MTLRenderPassDescriptor* m_clearColorPassDesc;
|
||||||
|
@ -423,7 +468,7 @@ public:
|
||||||
height = 1;
|
height = 1;
|
||||||
m_width = width;
|
m_width = width;
|
||||||
m_height = height;
|
m_height = height;
|
||||||
Setup(ctx, width, height, m_samples, m_enableShaderBindTexture);
|
Setup(ctx, width, height, m_samples, m_colorBindCount, m_depthBindCount);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -463,8 +508,8 @@ struct MetalVertexFormat : IVertexFormat
|
||||||
MTLVertexDescriptor* m_vdesc;
|
MTLVertexDescriptor* m_vdesc;
|
||||||
size_t m_stride = 0;
|
size_t m_stride = 0;
|
||||||
size_t m_instStride = 0;
|
size_t m_instStride = 0;
|
||||||
MetalVertexFormat(size_t elementCount, const VertexElementDescriptor* elements)
|
MetalVertexFormat(IGraphicsData* parent, size_t elementCount, const VertexElementDescriptor* elements)
|
||||||
: m_elementCount(elementCount)
|
: boo::IVertexFormat(parent), m_elementCount(elementCount)
|
||||||
{
|
{
|
||||||
for (size_t i=0 ; i<elementCount ; ++i)
|
for (size_t i=0 ; i<elementCount ; ++i)
|
||||||
{
|
{
|
||||||
|
@ -538,10 +583,12 @@ static const MTLPrimitiveType PRIMITIVE_TABLE[] =
|
||||||
MTLPrimitiveTypeTriangleStrip
|
MTLPrimitiveTypeTriangleStrip
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define COLOR_WRITE_MASK (MTLColorWriteMaskRed | MTLColorWriteMaskGreen | MTLColorWriteMaskBlue)
|
||||||
|
|
||||||
class MetalShaderPipeline : public IShaderPipeline
|
class MetalShaderPipeline : public IShaderPipeline
|
||||||
{
|
{
|
||||||
friend class MetalDataFactory;
|
friend class MetalDataFactory;
|
||||||
friend class MetalCommandQueue;
|
friend struct MetalCommandQueue;
|
||||||
friend struct MetalShaderDataBinding;
|
friend struct MetalShaderDataBinding;
|
||||||
MTLCullMode m_cullMode = MTLCullModeNone;
|
MTLCullMode m_cullMode = MTLCullModeNone;
|
||||||
MTLPrimitiveType m_drawPrim;
|
MTLPrimitiveType m_drawPrim;
|
||||||
|
@ -549,13 +596,16 @@ class MetalShaderPipeline : public IShaderPipeline
|
||||||
MetalShareableShader::Token m_vert;
|
MetalShareableShader::Token m_vert;
|
||||||
MetalShareableShader::Token m_frag;
|
MetalShareableShader::Token m_frag;
|
||||||
|
|
||||||
MetalShaderPipeline(MetalContext* ctx,
|
MetalShaderPipeline(IGraphicsData* parent,
|
||||||
|
MetalContext* ctx,
|
||||||
MetalShareableShader::Token&& vert,
|
MetalShareableShader::Token&& vert,
|
||||||
MetalShareableShader::Token&& frag,
|
MetalShareableShader::Token&& frag,
|
||||||
const MetalVertexFormat* vtxFmt, NSUInteger targetSamples,
|
const MetalVertexFormat* vtxFmt, NSUInteger targetSamples,
|
||||||
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
||||||
bool depthTest, bool depthWrite, CullMode culling)
|
ZTest depthTest, bool depthWrite, bool colorWrite,
|
||||||
: m_drawPrim(PRIMITIVE_TABLE[int(prim)]), m_vtxFmt(vtxFmt),
|
bool alphaWrite, CullMode culling)
|
||||||
|
: boo::IShaderPipeline(parent),
|
||||||
|
m_drawPrim(PRIMITIVE_TABLE[int(prim)]), m_vtxFmt(vtxFmt),
|
||||||
m_vert(std::move(vert)), m_frag(std::move(frag))
|
m_vert(std::move(vert)), m_frag(std::move(frag))
|
||||||
{
|
{
|
||||||
switch (culling)
|
switch (culling)
|
||||||
|
@ -578,9 +628,13 @@ class MetalShaderPipeline : public IShaderPipeline
|
||||||
desc.vertexDescriptor = vtxFmt->m_vdesc;
|
desc.vertexDescriptor = vtxFmt->m_vdesc;
|
||||||
desc.sampleCount = targetSamples;
|
desc.sampleCount = targetSamples;
|
||||||
desc.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm;
|
desc.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm;
|
||||||
|
desc.colorAttachments[0].writeMask = (colorWrite ? COLOR_WRITE_MASK : 0) |
|
||||||
|
(alphaWrite ? MTLColorWriteMaskAlpha : 0);
|
||||||
desc.colorAttachments[0].blendingEnabled = dstFac != BlendFactor::Zero;
|
desc.colorAttachments[0].blendingEnabled = dstFac != BlendFactor::Zero;
|
||||||
desc.colorAttachments[0].sourceRGBBlendFactor = BLEND_FACTOR_TABLE[int(srcFac)];
|
desc.colorAttachments[0].sourceRGBBlendFactor = BLEND_FACTOR_TABLE[int(srcFac)];
|
||||||
desc.colorAttachments[0].destinationRGBBlendFactor = BLEND_FACTOR_TABLE[int(dstFac)];
|
desc.colorAttachments[0].destinationRGBBlendFactor = BLEND_FACTOR_TABLE[int(dstFac)];
|
||||||
|
desc.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne;
|
||||||
|
desc.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorZero;
|
||||||
desc.depthAttachmentPixelFormat = MTLPixelFormatDepth32Float;
|
desc.depthAttachmentPixelFormat = MTLPixelFormatDepth32Float;
|
||||||
desc.inputPrimitiveTopology = MTLPrimitiveTopologyClassTriangle;
|
desc.inputPrimitiveTopology = MTLPrimitiveTopologyClassTriangle;
|
||||||
NSError* err = nullptr;
|
NSError* err = nullptr;
|
||||||
|
@ -590,8 +644,23 @@ class MetalShaderPipeline : public IShaderPipeline
|
||||||
[[err localizedDescription] UTF8String]);
|
[[err localizedDescription] UTF8String]);
|
||||||
|
|
||||||
MTLDepthStencilDescriptor* dsDesc = [MTLDepthStencilDescriptor new];
|
MTLDepthStencilDescriptor* dsDesc = [MTLDepthStencilDescriptor new];
|
||||||
if (depthTest)
|
switch (depthTest)
|
||||||
|
{
|
||||||
|
case ZTest::None:
|
||||||
|
default:
|
||||||
|
dsDesc.depthCompareFunction = MTLCompareFunctionAlways;
|
||||||
|
break;
|
||||||
|
case ZTest::LEqual:
|
||||||
dsDesc.depthCompareFunction = MTLCompareFunctionGreaterEqual;
|
dsDesc.depthCompareFunction = MTLCompareFunctionGreaterEqual;
|
||||||
|
break;
|
||||||
|
case ZTest::Greater:
|
||||||
|
dsDesc.depthCompareFunction = MTLCompareFunctionLess;
|
||||||
|
break;
|
||||||
|
case ZTest::Equal:
|
||||||
|
dsDesc.depthCompareFunction = MTLCompareFunctionEqual;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
dsDesc.depthWriteEnabled = depthWrite;
|
dsDesc.depthWriteEnabled = depthWrite;
|
||||||
m_dsState = [ctx->m_dev newDepthStencilStateWithDescriptor:dsDesc];
|
m_dsState = [ctx->m_dev newDepthStencilStateWithDescriptor:dsDesc];
|
||||||
}
|
}
|
||||||
|
@ -624,7 +693,23 @@ static id<MTLBuffer> GetBufferGPUResource(const IGraphicsBuffer* buf, int idx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static id<MTLTexture> GetTextureGPUResource(const ITexture* tex, int idx)
|
static id<MTLBuffer> GetBufferGPUResource(const IGraphicsBuffer* buf, int idx, size_t& strideOut)
|
||||||
|
{
|
||||||
|
if (buf->dynamic())
|
||||||
|
{
|
||||||
|
const MetalGraphicsBufferD* cbuf = static_cast<const MetalGraphicsBufferD*>(buf);
|
||||||
|
strideOut = cbuf->m_stride;
|
||||||
|
return cbuf->m_bufs[idx];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const MetalGraphicsBufferS* cbuf = static_cast<const MetalGraphicsBufferS*>(buf);
|
||||||
|
strideOut = cbuf->m_stride;
|
||||||
|
return cbuf->m_buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static id<MTLTexture> GetTextureGPUResource(const ITexture* tex, int idx, int bindIdx, bool depth)
|
||||||
{
|
{
|
||||||
switch (tex->type())
|
switch (tex->type())
|
||||||
{
|
{
|
||||||
|
@ -646,14 +731,14 @@ static id<MTLTexture> GetTextureGPUResource(const ITexture* tex, int idx)
|
||||||
case TextureType::Render:
|
case TextureType::Render:
|
||||||
{
|
{
|
||||||
const MetalTextureR* ctex = static_cast<const MetalTextureR*>(tex);
|
const MetalTextureR* ctex = static_cast<const MetalTextureR*>(tex);
|
||||||
return ctex->m_colorBindTex;
|
return depth ? ctex->m_depthBindTex[bindIdx] : ctex->m_colorBindTex[bindIdx];
|
||||||
}
|
}
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MetalShaderDataBinding : IShaderDataBindingPriv<MetalData>
|
struct MetalShaderDataBinding : IShaderDataBindingPriv
|
||||||
{
|
{
|
||||||
MetalShaderPipeline* m_pipeline;
|
MetalShaderPipeline* m_pipeline;
|
||||||
IGraphicsBuffer* m_vbuf;
|
IGraphicsBuffer* m_vbuf;
|
||||||
|
@ -664,7 +749,13 @@ struct MetalShaderDataBinding : IShaderDataBindingPriv<MetalData>
|
||||||
std::unique_ptr<size_t[]> m_ubufOffs;
|
std::unique_ptr<size_t[]> m_ubufOffs;
|
||||||
std::unique_ptr<bool[]> m_fubufs;
|
std::unique_ptr<bool[]> m_fubufs;
|
||||||
size_t m_texCount;
|
size_t m_texCount;
|
||||||
std::unique_ptr<ITexture*[]> m_texs;
|
struct BoundTex
|
||||||
|
{
|
||||||
|
ITexture* tex;
|
||||||
|
int idx;
|
||||||
|
bool depth;
|
||||||
|
};
|
||||||
|
std::unique_ptr<BoundTex[]> m_texs;
|
||||||
size_t m_baseVert;
|
size_t m_baseVert;
|
||||||
size_t m_baseInst;
|
size_t m_baseInst;
|
||||||
|
|
||||||
|
@ -674,7 +765,9 @@ struct MetalShaderDataBinding : IShaderDataBindingPriv<MetalData>
|
||||||
IGraphicsBuffer* vbuf, IGraphicsBuffer* instVbo, IGraphicsBuffer* ibuf,
|
IGraphicsBuffer* vbuf, IGraphicsBuffer* instVbo, IGraphicsBuffer* ibuf,
|
||||||
size_t ubufCount, IGraphicsBuffer** ubufs, const PipelineStage* ubufStages,
|
size_t ubufCount, IGraphicsBuffer** ubufs, const PipelineStage* ubufStages,
|
||||||
const size_t* ubufOffs, const size_t* ubufSizes,
|
const size_t* ubufOffs, const size_t* ubufSizes,
|
||||||
size_t texCount, ITexture** texs, size_t baseVert, size_t baseInst)
|
size_t texCount, ITexture** texs,
|
||||||
|
const int* texBindIdxs, const bool* depthBind,
|
||||||
|
size_t baseVert, size_t baseInst)
|
||||||
: IShaderDataBindingPriv(d),
|
: IShaderDataBindingPriv(d),
|
||||||
m_pipeline(static_cast<MetalShaderPipeline*>(pipeline)),
|
m_pipeline(static_cast<MetalShaderPipeline*>(pipeline)),
|
||||||
m_vbuf(vbuf),
|
m_vbuf(vbuf),
|
||||||
|
@ -683,10 +776,12 @@ struct MetalShaderDataBinding : IShaderDataBindingPriv<MetalData>
|
||||||
m_ubufCount(ubufCount),
|
m_ubufCount(ubufCount),
|
||||||
m_ubufs(new IGraphicsBuffer*[ubufCount]),
|
m_ubufs(new IGraphicsBuffer*[ubufCount]),
|
||||||
m_texCount(texCount),
|
m_texCount(texCount),
|
||||||
m_texs(new ITexture*[texCount]),
|
m_texs(new BoundTex[texCount]),
|
||||||
m_baseVert(baseVert),
|
m_baseVert(baseVert),
|
||||||
m_baseInst(baseInst)
|
m_baseInst(baseInst)
|
||||||
{
|
{
|
||||||
|
addDepData(m_pipeline->m_parentData);
|
||||||
|
|
||||||
if (ubufCount && ubufStages)
|
if (ubufCount && ubufStages)
|
||||||
{
|
{
|
||||||
m_fubufs.reset(new bool[ubufCount]);
|
m_fubufs.reset(new bool[ubufCount]);
|
||||||
|
@ -713,10 +808,14 @@ struct MetalShaderDataBinding : IShaderDataBindingPriv<MetalData>
|
||||||
Log.report(logvisor::Fatal, "null uniform-buffer %d provided to newShaderDataBinding", int(i));
|
Log.report(logvisor::Fatal, "null uniform-buffer %d provided to newShaderDataBinding", int(i));
|
||||||
#endif
|
#endif
|
||||||
m_ubufs[i] = ubufs[i];
|
m_ubufs[i] = ubufs[i];
|
||||||
|
if (ubufs[i])
|
||||||
|
addDepData(ubufs[i]->m_parentData);
|
||||||
}
|
}
|
||||||
for (size_t i=0 ; i<texCount ; ++i)
|
for (size_t i=0 ; i<texCount ; ++i)
|
||||||
{
|
{
|
||||||
m_texs[i] = texs[i];
|
m_texs[i] = {texs[i], texBindIdxs ? texBindIdxs[i] : 0, depthBind ? depthBind[i] : false};
|
||||||
|
if (texs[i])
|
||||||
|
addDepData(texs[i]->m_parentData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -724,12 +823,17 @@ struct MetalShaderDataBinding : IShaderDataBindingPriv<MetalData>
|
||||||
{
|
{
|
||||||
m_pipeline->bind(enc);
|
m_pipeline->bind(enc);
|
||||||
|
|
||||||
|
size_t stride;
|
||||||
if (m_vbuf)
|
if (m_vbuf)
|
||||||
[enc setVertexBuffer:GetBufferGPUResource(m_vbuf, b)
|
{
|
||||||
offset:m_pipeline->m_vtxFmt->m_stride * m_baseVert atIndex:0];
|
id<MTLBuffer> buf = GetBufferGPUResource(m_vbuf, b, stride);
|
||||||
|
[enc setVertexBuffer:buf offset:stride * m_baseVert atIndex:0];
|
||||||
|
}
|
||||||
if (m_instVbo)
|
if (m_instVbo)
|
||||||
[enc setVertexBuffer:GetBufferGPUResource(m_instVbo, b)
|
{
|
||||||
offset:m_pipeline->m_vtxFmt->m_instStride * m_baseInst atIndex:1];
|
id<MTLBuffer> buf = GetBufferGPUResource(m_instVbo, b, stride);
|
||||||
|
[enc setVertexBuffer:buf offset:stride * m_baseInst atIndex:1];
|
||||||
|
}
|
||||||
if (m_ubufOffs)
|
if (m_ubufOffs)
|
||||||
for (size_t i=0 ; i<m_ubufCount ; ++i)
|
for (size_t i=0 ; i<m_ubufCount ; ++i)
|
||||||
{
|
{
|
||||||
|
@ -747,8 +851,8 @@ struct MetalShaderDataBinding : IShaderDataBindingPriv<MetalData>
|
||||||
[enc setVertexBuffer:GetBufferGPUResource(m_ubufs[i], b) offset:0 atIndex:i+2];
|
[enc setVertexBuffer:GetBufferGPUResource(m_ubufs[i], b) offset:0 atIndex:i+2];
|
||||||
}
|
}
|
||||||
for (size_t i=0 ; i<m_texCount ; ++i)
|
for (size_t i=0 ; i<m_texCount ; ++i)
|
||||||
if (m_texs[i])
|
if (m_texs[i].tex)
|
||||||
[enc setFragmentTexture:GetTextureGPUResource(m_texs[i], b) atIndex:i];
|
[enc setFragmentTexture:GetTextureGPUResource(m_texs[i].tex, b, m_texs[i].idx, m_texs[i].depth) atIndex:i];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -801,9 +905,9 @@ struct MetalCommandQueue : IGraphicsCommandQueue
|
||||||
void _setRenderTarget(ITextureR* target, bool clearColor, bool clearDepth)
|
void _setRenderTarget(ITextureR* target, bool clearColor, bool clearDepth)
|
||||||
{
|
{
|
||||||
MetalTextureR* ctarget = static_cast<MetalTextureR*>(target);
|
MetalTextureR* ctarget = static_cast<MetalTextureR*>(target);
|
||||||
[m_enc endEncoding];
|
|
||||||
@autoreleasepool
|
@autoreleasepool
|
||||||
{
|
{
|
||||||
|
[m_enc endEncoding];
|
||||||
if (clearColor && clearDepth)
|
if (clearColor && clearDepth)
|
||||||
m_enc = [m_cmdBuf renderCommandEncoderWithDescriptor:ctarget->m_clearBothPassDesc];
|
m_enc = [m_cmdBuf renderCommandEncoderWithDescriptor:ctarget->m_clearBothPassDesc];
|
||||||
else if (clearColor)
|
else if (clearColor)
|
||||||
|
@ -865,7 +969,7 @@ struct MetalCommandQueue : IGraphicsCommandQueue
|
||||||
|
|
||||||
void flushBufferUpdates() {}
|
void flushBufferUpdates() {}
|
||||||
|
|
||||||
float m_clearColor[4] = {0.0,0.0,0.0,1.0};
|
float m_clearColor[4] = {0.0,0.0,0.0,0.0};
|
||||||
void setClearColor(const float rgba[4])
|
void setClearColor(const float rgba[4])
|
||||||
{
|
{
|
||||||
m_clearColor[0] = rgba[0];
|
m_clearColor[0] = rgba[0];
|
||||||
|
@ -911,36 +1015,53 @@ struct MetalCommandQueue : IGraphicsCommandQueue
|
||||||
instanceCount:instCount];
|
instanceCount:instCount];
|
||||||
}
|
}
|
||||||
|
|
||||||
void resolveBindTexture(ITextureR* texture, const SWindowRect& rect, bool tlOrigin, bool color, bool depth)
|
void resolveBindTexture(ITextureR* texture, const SWindowRect& rect, bool tlOrigin,
|
||||||
|
int bindIdx, bool color, bool depth)
|
||||||
{
|
{
|
||||||
MetalTextureR* tex = static_cast<MetalTextureR*>(texture);
|
MetalTextureR* tex = static_cast<MetalTextureR*>(texture);
|
||||||
if (color && tex->m_enableShaderBindTexture)
|
@autoreleasepool
|
||||||
{
|
{
|
||||||
[m_enc endEncoding];
|
[m_enc endEncoding];
|
||||||
@autoreleasepool
|
SWindowRect intersectRect = rect.intersect(SWindowRect(0, 0, tex->m_width, tex->m_height));
|
||||||
|
NSUInteger y = tlOrigin ? intersectRect.location[1] : int(tex->m_height) -
|
||||||
|
intersectRect.location[1] - intersectRect.size[1];
|
||||||
|
MTLOrigin origin = {NSUInteger(intersectRect.location[0]), y, 0};
|
||||||
|
id<MTLBlitCommandEncoder> blitEnc = [m_cmdBuf blitCommandEncoder];
|
||||||
|
|
||||||
|
if (color && tex->m_colorBindTex[bindIdx])
|
||||||
{
|
{
|
||||||
SWindowRect intersectRect = rect.intersect(SWindowRect(0, 0, tex->m_width, tex->m_height));
|
|
||||||
NSUInteger y = tlOrigin ? intersectRect.location[1] : int(tex->m_height) - intersectRect.location[1] - intersectRect.size[1];
|
|
||||||
MTLOrigin origin = {NSUInteger(intersectRect.location[0]), y, 0};
|
|
||||||
id<MTLBlitCommandEncoder> blitEnc = [m_cmdBuf blitCommandEncoder];
|
|
||||||
[blitEnc copyFromTexture:tex->m_colorTex
|
[blitEnc copyFromTexture:tex->m_colorTex
|
||||||
sourceSlice:0
|
sourceSlice:0
|
||||||
sourceLevel:0
|
sourceLevel:0
|
||||||
sourceOrigin:origin
|
sourceOrigin:origin
|
||||||
sourceSize:MTLSizeMake(intersectRect.size[0], intersectRect.size[1], 1)
|
sourceSize:MTLSizeMake(intersectRect.size[0], intersectRect.size[1], 1)
|
||||||
toTexture:tex->m_colorBindTex
|
toTexture:tex->m_colorBindTex[bindIdx]
|
||||||
destinationSlice:0
|
destinationSlice:0
|
||||||
destinationLevel:0
|
destinationLevel:0
|
||||||
destinationOrigin:origin];
|
destinationOrigin:origin];
|
||||||
[blitEnc endEncoding];
|
|
||||||
m_enc = [m_cmdBuf renderCommandEncoderWithDescriptor:tex->m_passDesc];
|
|
||||||
[m_enc setFrontFacingWinding:MTLWindingCounterClockwise];
|
|
||||||
|
|
||||||
if (m_boundVp.width || m_boundVp.height)
|
|
||||||
[m_enc setViewport:m_boundVp];
|
|
||||||
if (m_boundScissor.width || m_boundScissor.height)
|
|
||||||
[m_enc setScissorRect:m_boundScissor];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (depth && tex->m_depthBindTex[bindIdx])
|
||||||
|
{
|
||||||
|
[blitEnc copyFromTexture:tex->m_depthTex
|
||||||
|
sourceSlice:0
|
||||||
|
sourceLevel:0
|
||||||
|
sourceOrigin:origin
|
||||||
|
sourceSize:MTLSizeMake(intersectRect.size[0], intersectRect.size[1], 1)
|
||||||
|
toTexture:tex->m_depthBindTex[bindIdx]
|
||||||
|
destinationSlice:0
|
||||||
|
destinationLevel:0
|
||||||
|
destinationOrigin:origin];
|
||||||
|
}
|
||||||
|
|
||||||
|
[blitEnc endEncoding];
|
||||||
|
m_enc = [m_cmdBuf renderCommandEncoderWithDescriptor:tex->m_passDesc];
|
||||||
|
[m_enc setFrontFacingWinding:MTLWindingCounterClockwise];
|
||||||
|
|
||||||
|
if (m_boundVp.width || m_boundVp.height)
|
||||||
|
[m_enc setViewport:m_boundVp];
|
||||||
|
if (m_boundScissor.width || m_boundScissor.height)
|
||||||
|
[m_enc setScissorRect:m_boundScissor];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -968,8 +1089,8 @@ struct MetalCommandQueue : IGraphicsCommandQueue
|
||||||
}
|
}
|
||||||
for (MetalPool* p : gfxF->m_committedPools)
|
for (MetalPool* p : gfxF->m_committedPools)
|
||||||
{
|
{
|
||||||
for (auto& b : p->m_DBufs)
|
for (auto& b : p->m_items)
|
||||||
b.second->update(m_fillBuf);
|
b->m_buf->update(m_fillBuf);
|
||||||
}
|
}
|
||||||
datalk.unlock();
|
datalk.unlock();
|
||||||
|
|
||||||
|
@ -999,38 +1120,35 @@ struct MetalCommandQueue : IGraphicsCommandQueue
|
||||||
if (m_needsDisplay)
|
if (m_needsDisplay)
|
||||||
{
|
{
|
||||||
MetalContext::Window& w = m_ctx->m_windows[m_parentWindow];
|
MetalContext::Window& w = m_ctx->m_windows[m_parentWindow];
|
||||||
@autoreleasepool
|
|
||||||
{
|
{
|
||||||
|
std::unique_lock<std::mutex> lk(w.m_resizeLock);
|
||||||
|
if (w.m_needsResize)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lk(w.m_resizeLock);
|
w.m_metalLayer.drawableSize = w.m_size;
|
||||||
if (w.m_needsResize)
|
w.m_needsResize = NO;
|
||||||
{
|
m_needsDisplay = nullptr;
|
||||||
w.m_metalLayer.drawableSize = w.m_size;
|
return;
|
||||||
w.m_needsResize = NO;
|
|
||||||
m_needsDisplay = nullptr;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
id<CAMetalDrawable> drawable = [w.m_metalLayer nextDrawable];
|
}
|
||||||
if (drawable)
|
id<CAMetalDrawable> drawable = [w.m_metalLayer nextDrawable];
|
||||||
|
if (drawable)
|
||||||
|
{
|
||||||
|
id<MTLTexture> dest = drawable.texture;
|
||||||
|
if (m_needsDisplay->m_colorTex.width == dest.width &&
|
||||||
|
m_needsDisplay->m_colorTex.height == dest.height)
|
||||||
{
|
{
|
||||||
id<MTLTexture> dest = drawable.texture;
|
id<MTLBlitCommandEncoder> blitEnc = [m_cmdBuf blitCommandEncoder];
|
||||||
if (m_needsDisplay->m_colorTex.width == dest.width &&
|
[blitEnc copyFromTexture:m_needsDisplay->m_colorTex
|
||||||
m_needsDisplay->m_colorTex.height == dest.height)
|
sourceSlice:0
|
||||||
{
|
sourceLevel:0
|
||||||
id<MTLBlitCommandEncoder> blitEnc = [m_cmdBuf blitCommandEncoder];
|
sourceOrigin:MTLOriginMake(0, 0, 0)
|
||||||
[blitEnc copyFromTexture:m_needsDisplay->m_colorTex
|
sourceSize:MTLSizeMake(dest.width, dest.height, 1)
|
||||||
sourceSlice:0
|
toTexture:dest
|
||||||
sourceLevel:0
|
destinationSlice:0
|
||||||
sourceOrigin:MTLOriginMake(0, 0, 0)
|
destinationLevel:0
|
||||||
sourceSize:MTLSizeMake(dest.width, dest.height, 1)
|
destinationOrigin:MTLOriginMake(0, 0, 0)];
|
||||||
toTexture:dest
|
[blitEnc endEncoding];
|
||||||
destinationSlice:0
|
[m_cmdBuf presentDrawable:drawable];
|
||||||
destinationLevel:0
|
|
||||||
destinationOrigin:MTLOriginMake(0, 0, 0)];
|
|
||||||
[blitEnc endEncoding];
|
|
||||||
[m_cmdBuf presentDrawable:drawable];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_needsDisplay = nullptr;
|
m_needsDisplay = nullptr;
|
||||||
|
@ -1107,66 +1225,76 @@ MetalDataFactoryImpl::MetalDataFactoryImpl(IGraphicsContext* parent, MetalContex
|
||||||
|
|
||||||
IGraphicsBufferS* MetalDataFactory::Context::newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count)
|
IGraphicsBufferS* MetalDataFactory::Context::newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count)
|
||||||
{
|
{
|
||||||
|
MetalData* d = MetalDataFactoryImpl::m_deferredData.get();
|
||||||
MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent);
|
MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent);
|
||||||
MetalGraphicsBufferS* retval = new MetalGraphicsBufferS(use, factory.m_ctx, data, stride, count);
|
MetalGraphicsBufferS* retval = new MetalGraphicsBufferS(d, use, factory.m_ctx, data, stride, count);
|
||||||
MetalDataFactoryImpl::m_deferredData->m_SBufs.emplace_back(retval);
|
d->m_SBufs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
IGraphicsBufferD* MetalDataFactory::Context::newDynamicBuffer(BufferUse use, size_t stride, size_t count)
|
IGraphicsBufferD* MetalDataFactory::Context::newDynamicBuffer(BufferUse use, size_t stride, size_t count)
|
||||||
{
|
{
|
||||||
|
MetalData* d = MetalDataFactoryImpl::m_deferredData.get();
|
||||||
MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent);
|
MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent);
|
||||||
MetalCommandQueue* q = static_cast<MetalCommandQueue*>(factory.m_parent->getCommandQueue());
|
MetalCommandQueue* q = static_cast<MetalCommandQueue*>(factory.m_parent->getCommandQueue());
|
||||||
MetalGraphicsBufferD* retval = new MetalGraphicsBufferD(q, use, factory.m_ctx, stride, count);
|
MetalGraphicsBufferD* retval = new MetalGraphicsBufferD(d, q, use, factory.m_ctx, stride, count);
|
||||||
MetalDataFactoryImpl::m_deferredData->m_DBufs.emplace_back(retval);
|
d->m_DBufs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
ITextureS* MetalDataFactory::Context::newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
|
ITextureS* MetalDataFactory::Context::newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
|
||||||
const void* data, size_t sz)
|
const void* data, size_t sz)
|
||||||
{
|
{
|
||||||
|
MetalData* d = MetalDataFactoryImpl::m_deferredData.get();
|
||||||
MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent);
|
MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent);
|
||||||
MetalTextureS* retval = new MetalTextureS(factory.m_ctx, width, height, mips, fmt, data, sz);
|
MetalTextureS* retval = new MetalTextureS(d, factory.m_ctx, width, height, mips, fmt, data, sz);
|
||||||
MetalDataFactoryImpl::m_deferredData->m_STexs.emplace_back(retval);
|
d->m_STexs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
ITextureSA* MetalDataFactory::Context::newStaticArrayTexture(size_t width, size_t height, size_t layers, size_t mips,
|
ITextureSA* MetalDataFactory::Context::newStaticArrayTexture(size_t width, size_t height, size_t layers, size_t mips,
|
||||||
TextureFormat fmt, const void* data, size_t sz)
|
TextureFormat fmt, const void* data, size_t sz)
|
||||||
{
|
{
|
||||||
|
MetalData* d = MetalDataFactoryImpl::m_deferredData.get();
|
||||||
MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent);
|
MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent);
|
||||||
MetalTextureSA* retval = new MetalTextureSA(factory.m_ctx, width, height, layers, mips, fmt, data, sz);
|
MetalTextureSA* retval = new MetalTextureSA(d, factory.m_ctx, width, height, layers, mips, fmt, data, sz);
|
||||||
MetalDataFactoryImpl::m_deferredData->m_SATexs.emplace_back(retval);
|
d->m_SATexs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
ITextureD* MetalDataFactory::Context::newDynamicTexture(size_t width, size_t height, TextureFormat fmt)
|
ITextureD* MetalDataFactory::Context::newDynamicTexture(size_t width, size_t height, TextureFormat fmt)
|
||||||
{
|
{
|
||||||
|
MetalData* d = MetalDataFactoryImpl::m_deferredData.get();
|
||||||
MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent);
|
MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent);
|
||||||
MetalCommandQueue* q = static_cast<MetalCommandQueue*>(factory.m_parent->getCommandQueue());
|
MetalCommandQueue* q = static_cast<MetalCommandQueue*>(factory.m_parent->getCommandQueue());
|
||||||
MetalTextureD* retval = new MetalTextureD(q, factory.m_ctx, width, height, fmt);
|
MetalTextureD* retval = new MetalTextureD(d, q, factory.m_ctx, width, height, fmt);
|
||||||
MetalDataFactoryImpl::m_deferredData->m_DTexs.emplace_back(retval);
|
d->m_DTexs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
ITextureR* MetalDataFactory::Context::newRenderTexture(size_t width, size_t height,
|
ITextureR* MetalDataFactory::Context::newRenderTexture(size_t width, size_t height,
|
||||||
bool enableShaderColorBinding, bool enableShaderDepthBinding)
|
size_t colorBindCount, size_t depthBindCount)
|
||||||
{
|
{
|
||||||
|
MetalData* d = MetalDataFactoryImpl::m_deferredData.get();
|
||||||
MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent);
|
MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent);
|
||||||
MetalTextureR* retval = new MetalTextureR(factory.m_ctx, width, height, factory.m_sampleCount, enableShaderColorBinding);
|
MetalTextureR* retval = new MetalTextureR(d, factory.m_ctx, width, height, factory.m_sampleCount,
|
||||||
MetalDataFactoryImpl::m_deferredData->m_RTexs.emplace_back(retval);
|
colorBindCount, depthBindCount);
|
||||||
|
d->m_RTexs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
IVertexFormat* MetalDataFactory::Context::newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements,
|
IVertexFormat* MetalDataFactory::Context::newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements,
|
||||||
size_t baseVert, size_t baseInst)
|
size_t baseVert, size_t baseInst)
|
||||||
{
|
{
|
||||||
MetalVertexFormat* retval = new struct MetalVertexFormat(elementCount, elements);
|
MetalData* d = MetalDataFactoryImpl::m_deferredData.get();
|
||||||
MetalDataFactoryImpl::m_deferredData->m_VFmts.emplace_back(retval);
|
MetalVertexFormat* retval = new struct MetalVertexFormat(d, elementCount, elements);
|
||||||
|
d->m_VFmts.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
IShaderPipeline* MetalDataFactory::Context::newShaderPipeline(const char* vertSource, const char* fragSource,
|
IShaderPipeline* MetalDataFactory::Context::newShaderPipeline(const char* vertSource, const char* fragSource,
|
||||||
IVertexFormat* vtxFmt, unsigned targetSamples,
|
IVertexFormat* vtxFmt, unsigned targetSamples,
|
||||||
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
||||||
bool depthTest, bool depthWrite, CullMode culling)
|
ZTest depthTest, bool depthWrite, bool colorWrite,
|
||||||
|
bool alphaWrite, CullMode culling)
|
||||||
{
|
{
|
||||||
|
MetalData* d = MetalDataFactoryImpl::m_deferredData.get();
|
||||||
MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent);
|
MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent);
|
||||||
MTLCompileOptions* compOpts = [MTLCompileOptions new];
|
MTLCompileOptions* compOpts = [MTLCompileOptions new];
|
||||||
compOpts.languageVersion = MTLLanguageVersion1_1;
|
compOpts.languageVersion = MTLLanguageVersion1_1;
|
||||||
|
@ -1228,10 +1356,11 @@ IShaderPipeline* MetalDataFactory::Context::newShaderPipeline(const char* vertSo
|
||||||
fragShader = it->second->lock();
|
fragShader = it->second->lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
MetalShaderPipeline* retval = new MetalShaderPipeline(factory.m_ctx, std::move(vertShader), std::move(fragShader),
|
MetalShaderPipeline* retval = new MetalShaderPipeline(d, factory.m_ctx, std::move(vertShader), std::move(fragShader),
|
||||||
static_cast<const MetalVertexFormat*>(vtxFmt), targetSamples,
|
static_cast<const MetalVertexFormat*>(vtxFmt), targetSamples,
|
||||||
srcFac, dstFac, prim, depthTest, depthWrite, culling);
|
srcFac, dstFac, prim, depthTest, depthWrite,
|
||||||
MetalDataFactoryImpl::m_deferredData->m_SPs.emplace_back(retval);
|
colorWrite, alphaWrite, culling);
|
||||||
|
d->m_SPs.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1241,14 +1370,17 @@ MetalDataFactory::Context::newShaderDataBinding(IShaderPipeline* pipeline,
|
||||||
IGraphicsBuffer* vbuf, IGraphicsBuffer* instVbo, IGraphicsBuffer* ibuf,
|
IGraphicsBuffer* vbuf, IGraphicsBuffer* instVbo, IGraphicsBuffer* ibuf,
|
||||||
size_t ubufCount, IGraphicsBuffer** ubufs, const PipelineStage* ubufStages,
|
size_t ubufCount, IGraphicsBuffer** ubufs, const PipelineStage* ubufStages,
|
||||||
const size_t* ubufOffs, const size_t* ubufSizes,
|
const size_t* ubufOffs, const size_t* ubufSizes,
|
||||||
size_t texCount, ITexture** texs, size_t baseVert, size_t baseInst)
|
size_t texCount, ITexture** texs,
|
||||||
|
const int* texBindIdxs, const bool* depthBind,
|
||||||
|
size_t baseVert, size_t baseInst)
|
||||||
{
|
{
|
||||||
MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent);
|
MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent);
|
||||||
MetalShaderDataBinding* retval =
|
MetalShaderDataBinding* retval =
|
||||||
new MetalShaderDataBinding(MetalDataFactoryImpl::m_deferredData.get(),
|
new MetalShaderDataBinding(MetalDataFactoryImpl::m_deferredData.get(),
|
||||||
factory.m_ctx, pipeline, vbuf, instVbo, ibuf,
|
factory.m_ctx, pipeline, vbuf, instVbo, ibuf,
|
||||||
ubufCount, ubufs, ubufStages, ubufOffs,
|
ubufCount, ubufs, ubufStages, ubufOffs,
|
||||||
ubufSizes, texCount, texs, baseVert, baseInst);
|
ubufSizes, texCount, texs, texBindIdxs,
|
||||||
|
depthBind, baseVert, baseInst);
|
||||||
MetalDataFactoryImpl::m_deferredData->m_SBinds.emplace_back(retval);
|
MetalDataFactoryImpl::m_deferredData->m_SBinds.emplace_back(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -1295,8 +1427,8 @@ void MetalDataFactoryImpl::destroyAllData()
|
||||||
std::unique_lock<std::mutex> lk(m_committedMutex);
|
std::unique_lock<std::mutex> lk(m_committedMutex);
|
||||||
for (MetalData* data : m_committedData)
|
for (MetalData* data : m_committedData)
|
||||||
data->decrement();
|
data->decrement();
|
||||||
for (IGraphicsBufferPool* pool : m_committedPools)
|
for (MetalPool* pool : m_committedPools)
|
||||||
delete static_cast<MetalPool*>(pool);
|
delete pool;
|
||||||
m_committedData.clear();
|
m_committedData.clear();
|
||||||
m_committedPools.clear();
|
m_committedPools.clear();
|
||||||
}
|
}
|
||||||
|
@ -1314,15 +1446,22 @@ IGraphicsBufferD* MetalDataFactoryImpl::newPoolBuffer(IGraphicsBufferPool* p, Bu
|
||||||
{
|
{
|
||||||
MetalPool* pool = static_cast<MetalPool*>(p);
|
MetalPool* pool = static_cast<MetalPool*>(p);
|
||||||
MetalCommandQueue* q = static_cast<MetalCommandQueue*>(m_parent->getCommandQueue());
|
MetalCommandQueue* q = static_cast<MetalCommandQueue*>(m_parent->getCommandQueue());
|
||||||
MetalGraphicsBufferD* retval = new MetalGraphicsBufferD(q, use, m_ctx, stride, count);
|
MetalPoolItem* item = new MetalPoolItem;
|
||||||
pool->m_DBufs.emplace(std::make_pair(retval, std::unique_ptr<MetalGraphicsBufferD>(retval)));
|
MetalGraphicsBufferD* retval = new MetalGraphicsBufferD(item, q, use, m_ctx, stride, count);
|
||||||
|
item->m_buf.reset(retval);
|
||||||
|
pool->m_items.emplace(item);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetalDataFactoryImpl::deletePoolBuffer(IGraphicsBufferPool* p, IGraphicsBufferD* buf)
|
void MetalDataFactoryImpl::deletePoolBuffer(IGraphicsBufferPool* p, IGraphicsBufferD* buf)
|
||||||
{
|
{
|
||||||
MetalPool* pool = static_cast<MetalPool*>(p);
|
MetalPool* pool = static_cast<MetalPool*>(p);
|
||||||
pool->m_DBufs.erase(static_cast<MetalGraphicsBufferD*>(buf));
|
auto search = pool->m_items.find(static_cast<MetalPoolItem*>(buf->m_parentData));
|
||||||
|
if (search != pool->m_items.end())
|
||||||
|
{
|
||||||
|
(*search)->decrement();
|
||||||
|
pool->m_items.erase(search);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IGraphicsCommandQueue* _NewMetalCommandQueue(MetalContext* ctx, IWindow* parentWindow,
|
IGraphicsCommandQueue* _NewMetalCommandQueue(MetalContext* ctx, IWindow* parentWindow,
|
||||||
|
|
|
@ -1841,7 +1841,7 @@ class VulkanShaderPipeline : public IShaderPipeline
|
||||||
VkPipelineCache pipelineCache,
|
VkPipelineCache pipelineCache,
|
||||||
const VulkanVertexFormat* vtxFmt,
|
const VulkanVertexFormat* vtxFmt,
|
||||||
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
||||||
bool depthTest, bool depthWrite, CullMode culling)
|
ZTest depthTest, bool depthWrite, CullMode culling)
|
||||||
: m_ctx(ctx), m_pipelineCache(pipelineCache), m_vtxFmt(vtxFmt),
|
: m_ctx(ctx), m_pipelineCache(pipelineCache), m_vtxFmt(vtxFmt),
|
||||||
m_vert(std::move(vert)), m_frag(std::move(frag))
|
m_vert(std::move(vert)), m_frag(std::move(frag))
|
||||||
{
|
{
|
||||||
|
@ -2509,7 +2509,7 @@ struct VulkanCommandQueue : IGraphicsCommandQueue
|
||||||
func();
|
func();
|
||||||
}
|
}
|
||||||
|
|
||||||
float m_clearColor[4] = {0.0,0.0,0.0,1.0};
|
float m_clearColor[4] = {0.0,0.0,0.0,0.0};
|
||||||
void setClearColor(const float rgba[4])
|
void setClearColor(const float rgba[4])
|
||||||
{
|
{
|
||||||
m_clearColor[0] = rgba[0];
|
m_clearColor[0] = rgba[0];
|
||||||
|
@ -3081,7 +3081,7 @@ IShaderPipeline* VulkanDataFactory::Context::newShaderPipeline
|
||||||
std::vector<unsigned int>* vertBlobOut, std::vector<unsigned int>* fragBlobOut,
|
std::vector<unsigned int>* vertBlobOut, std::vector<unsigned int>* fragBlobOut,
|
||||||
std::vector<unsigned char>* pipelineBlob, IVertexFormat* vtxFmt,
|
std::vector<unsigned char>* pipelineBlob, IVertexFormat* vtxFmt,
|
||||||
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
||||||
bool depthTest, bool depthWrite, CullMode culling)
|
ZTest depthTest, bool depthWrite, CullMode culling)
|
||||||
{
|
{
|
||||||
VulkanDataFactoryImpl& factory = static_cast<VulkanDataFactoryImpl&>(m_parent);
|
VulkanDataFactoryImpl& factory = static_cast<VulkanDataFactoryImpl&>(m_parent);
|
||||||
|
|
||||||
|
|
|
@ -214,8 +214,10 @@ public:
|
||||||
|
|
||||||
~GraphicsContextCocoaGL()
|
~GraphicsContextCocoaGL()
|
||||||
{
|
{
|
||||||
delete m_dataFactory;
|
m_commandQueue->stopRenderer();
|
||||||
|
m_dataFactory->destroyAllData();
|
||||||
delete m_commandQueue;
|
delete m_commandQueue;
|
||||||
|
delete m_dataFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _setCallback(IWindowCallback* cb)
|
void _setCallback(IWindowCallback* cb)
|
||||||
|
@ -370,8 +372,10 @@ public:
|
||||||
|
|
||||||
~GraphicsContextCocoaMetal()
|
~GraphicsContextCocoaMetal()
|
||||||
{
|
{
|
||||||
delete m_dataFactory;
|
m_commandQueue->stopRenderer();
|
||||||
|
m_dataFactory->destroyAllData();
|
||||||
delete m_commandQueue;
|
delete m_commandQueue;
|
||||||
|
delete m_dataFactory;
|
||||||
m_metalCtx->m_windows.erase(m_parentWindow);
|
m_metalCtx->m_windows.erase(m_parentWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -308,7 +308,7 @@ struct TestApplicationCallback : IApplicationCallback
|
||||||
|
|
||||||
pipeline = glF.newShaderPipeline(VS, FS, 1, &texName, 0, nullptr,
|
pipeline = glF.newShaderPipeline(VS, FS, 1, &texName, 0, nullptr,
|
||||||
BlendFactor::One, BlendFactor::Zero,
|
BlendFactor::One, BlendFactor::Zero,
|
||||||
Primitive::TriStrips, true, true, CullMode::None);
|
Primitive::TriStrips, boo::ZTest::LEqual, true, true, false, CullMode::None);
|
||||||
}
|
}
|
||||||
#if BOO_HAS_VULKAN
|
#if BOO_HAS_VULKAN
|
||||||
else if (plat == IGraphicsDataFactory::Platform::Vulkan)
|
else if (plat == IGraphicsDataFactory::Platform::Vulkan)
|
||||||
|
@ -403,13 +403,14 @@ struct TestApplicationCallback : IApplicationCallback
|
||||||
|
|
||||||
pipeline = metalF.newShaderPipeline(VS, FS, vfmt, 1,
|
pipeline = metalF.newShaderPipeline(VS, FS, vfmt, 1,
|
||||||
BlendFactor::One, BlendFactor::Zero, Primitive::TriStrips,
|
BlendFactor::One, BlendFactor::Zero, Primitive::TriStrips,
|
||||||
true, true, boo::CullMode::None);
|
boo::ZTest::LEqual, true, true, true, boo::CullMode::None);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Make shader data binding */
|
/* Make shader data binding */
|
||||||
self->m_binding =
|
self->m_binding =
|
||||||
ctx.newShaderDataBinding(pipeline, vfmt, vbo, nullptr, nullptr, 0, nullptr, nullptr, 1, &texture);
|
ctx.newShaderDataBinding(pipeline, vfmt, vbo, nullptr, nullptr, 0, nullptr, nullptr,
|
||||||
|
1, &texture, nullptr, nullptr);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue