mirror of https://github.com/AxioDL/boo.git
Object tracker bug fixes; optional metal binary shader compilation
This commit is contained in:
parent
021143fd89
commit
3a7987bb21
|
@ -25,13 +25,13 @@ class ObjToken
|
||||||
SubCls* m_obj = nullptr;
|
SubCls* m_obj = nullptr;
|
||||||
public:
|
public:
|
||||||
ObjToken() = default;
|
ObjToken() = default;
|
||||||
ObjToken(SubCls* obj) : m_obj(obj) { m_obj->increment(); }
|
ObjToken(SubCls* obj) : m_obj(obj) { if (m_obj) m_obj->increment(); }
|
||||||
ObjToken(const ObjToken& other) : m_obj(other.m_obj) { m_obj->increment(); }
|
ObjToken(const ObjToken& other) : m_obj(other.m_obj) { if (m_obj) m_obj->increment(); }
|
||||||
ObjToken(ObjToken&& other) : m_obj(other.m_obj) { other.m_obj = nullptr; }
|
ObjToken(ObjToken&& other) : m_obj(other.m_obj) { other.m_obj = nullptr; }
|
||||||
ObjToken& operator=(SubCls* obj)
|
ObjToken& operator=(SubCls* obj)
|
||||||
{ if (m_obj) m_obj->decrement(); m_obj = obj; m_obj->increment(); return *this; }
|
{ if (m_obj) m_obj->decrement(); m_obj = obj; if (m_obj) m_obj->increment(); return *this; }
|
||||||
ObjToken& operator=(const ObjToken& other)
|
ObjToken& operator=(const ObjToken& other)
|
||||||
{ if (m_obj) m_obj->decrement(); m_obj = other.m_obj; m_obj->increment(); return *this; }
|
{ if (m_obj) m_obj->decrement(); m_obj = other.m_obj; if (m_obj) m_obj->increment(); return *this; }
|
||||||
ObjToken& operator=(ObjToken&& other)
|
ObjToken& operator=(ObjToken&& other)
|
||||||
{ if (m_obj) m_obj->decrement(); m_obj = other.m_obj; other.m_obj = nullptr; return *this; }
|
{ if (m_obj) m_obj->decrement(); m_obj = other.m_obj; other.m_obj = nullptr; return *this; }
|
||||||
~ObjToken() { if (m_obj) m_obj->decrement(); }
|
~ObjToken() { if (m_obj) m_obj->decrement(); }
|
||||||
|
@ -40,6 +40,7 @@ public:
|
||||||
SubCls& operator*() const { return *m_obj; }
|
SubCls& operator*() const { return *m_obj; }
|
||||||
template<class T> T* cast() const { return static_cast<T*>(m_obj); }
|
template<class T> T* cast() const { return static_cast<T*>(m_obj); }
|
||||||
operator bool() const { return m_obj != nullptr; }
|
operator bool() const { return m_obj != nullptr; }
|
||||||
|
void reset() { if (m_obj) m_obj->decrement(); m_obj = nullptr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
namespace boo
|
namespace boo
|
||||||
{
|
{
|
||||||
class BaseGraphicsData;
|
struct BaseGraphicsData;
|
||||||
|
|
||||||
class GLDataFactory : public IGraphicsDataFactory
|
class GLDataFactory : public IGraphicsDataFactory
|
||||||
{
|
{
|
||||||
|
|
|
@ -139,12 +139,13 @@ ENABLE_BITWISE_ENUM(VertexSemantic)
|
||||||
/** Used to create IVertexFormat */
|
/** Used to create IVertexFormat */
|
||||||
struct VertexElementDescriptor
|
struct VertexElementDescriptor
|
||||||
{
|
{
|
||||||
IGraphicsBuffer* vertBuffer = nullptr;
|
ObjToken<IGraphicsBuffer> vertBuffer;
|
||||||
IGraphicsBuffer* indexBuffer = nullptr;
|
ObjToken<IGraphicsBuffer> indexBuffer;
|
||||||
VertexSemantic semantic;
|
VertexSemantic semantic;
|
||||||
int semanticIdx = 0;
|
int semanticIdx = 0;
|
||||||
VertexElementDescriptor() = default;
|
VertexElementDescriptor() = default;
|
||||||
VertexElementDescriptor(IGraphicsBuffer* v, IGraphicsBuffer* i, VertexSemantic s, int idx=0)
|
VertexElementDescriptor(const ObjToken<IGraphicsBuffer>& v, const ObjToken<IGraphicsBuffer>& i,
|
||||||
|
VertexSemantic s, int idx=0)
|
||||||
: vertBuffer(v), indexBuffer(i), semantic(s), semanticIdx(idx) {}
|
: vertBuffer(v), indexBuffer(i), semantic(s), semanticIdx(idx) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
namespace boo
|
namespace boo
|
||||||
{
|
{
|
||||||
|
struct BaseGraphicsData;
|
||||||
|
|
||||||
class MetalDataFactory : public IGraphicsDataFactory
|
class MetalDataFactory : public IGraphicsDataFactory
|
||||||
{
|
{
|
||||||
|
@ -17,7 +18,9 @@ public:
|
||||||
{
|
{
|
||||||
friend class MetalDataFactoryImpl;
|
friend class MetalDataFactoryImpl;
|
||||||
MetalDataFactory& m_parent;
|
MetalDataFactory& m_parent;
|
||||||
Context(MetalDataFactory& parent) : m_parent(parent) {}
|
ObjToken<BaseGraphicsData> m_data;
|
||||||
|
Context(MetalDataFactory& parent);
|
||||||
|
~Context();
|
||||||
public:
|
public:
|
||||||
Platform platform() const { return Platform::Metal; }
|
Platform platform() const { return Platform::Metal; }
|
||||||
const SystemChar* platformName() const { return _S("Metal"); }
|
const SystemChar* platformName() const { return _S("Metal"); }
|
||||||
|
@ -40,7 +43,9 @@ public:
|
||||||
size_t baseVert = 0, size_t baseInst = 0);
|
size_t baseVert = 0, size_t baseInst = 0);
|
||||||
|
|
||||||
ObjToken<IShaderPipeline> newShaderPipeline(const char* vertSource, const char* fragSource,
|
ObjToken<IShaderPipeline> newShaderPipeline(const char* vertSource, const char* fragSource,
|
||||||
IVertexFormat* vtxFmt, unsigned targetSamples,
|
std::vector<uint8_t>* vertBlobOut,
|
||||||
|
std::vector<uint8_t>* fragBlobOut,
|
||||||
|
const ObjToken<IVertexFormat>& vtxFmt, unsigned targetSamples,
|
||||||
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
||||||
ZTest depthTest, bool depthWrite, bool colorWrite,
|
ZTest depthTest, bool depthWrite, bool colorWrite,
|
||||||
bool alphaWrite, CullMode culling);
|
bool alphaWrite, CullMode culling);
|
||||||
|
|
|
@ -26,6 +26,24 @@ struct GraphicsDataFactoryHead
|
||||||
BaseGraphicsPool* m_poolHead = nullptr;
|
BaseGraphicsPool* m_poolHead = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Linked-list iterator shareable by data container types */
|
||||||
|
template<class T>
|
||||||
|
class DataIterator
|
||||||
|
{
|
||||||
|
T* m_node;
|
||||||
|
public:
|
||||||
|
using value_type = T;
|
||||||
|
using pointer = T*;
|
||||||
|
using reference = T&;
|
||||||
|
using iterator_category = std::bidirectional_iterator_tag;
|
||||||
|
|
||||||
|
explicit DataIterator(T* node) : m_node(node) {}
|
||||||
|
T& operator*() const { return *m_node; }
|
||||||
|
bool operator!=(const DataIterator& other) const { return m_node != other.m_node; }
|
||||||
|
DataIterator& operator++() { m_node = m_node->m_next; return *this; }
|
||||||
|
DataIterator& operator--() { m_node = m_node->m_prev; return *this; }
|
||||||
|
};
|
||||||
|
|
||||||
/** Private generalized data container class.
|
/** Private generalized data container class.
|
||||||
* Keeps head pointers to all graphics objects by type
|
* Keeps head pointers to all graphics objects by type
|
||||||
*/
|
*/
|
||||||
|
@ -50,6 +68,8 @@ struct BaseGraphicsData : IObj
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lk(m_head.m_dataMutex);
|
std::lock_guard<std::mutex> lk(m_head.m_dataMutex);
|
||||||
m_next = head.m_dataHead;
|
m_next = head.m_dataHead;
|
||||||
|
if (m_next)
|
||||||
|
m_next->m_prev = this;
|
||||||
head.m_dataHead = this;
|
head.m_dataHead = this;
|
||||||
}
|
}
|
||||||
~BaseGraphicsData()
|
~BaseGraphicsData()
|
||||||
|
@ -64,52 +84,37 @@ struct BaseGraphicsData : IObj
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (m_next)
|
if (m_next)
|
||||||
m_next->m_prev = m_head.m_dataHead;
|
m_next->m_prev = nullptr;
|
||||||
m_head.m_dataHead = m_next;
|
m_head.m_dataHead = m_next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class iterator
|
using iterator = DataIterator<BaseGraphicsData>;
|
||||||
{
|
|
||||||
BaseGraphicsData* m_node;
|
|
||||||
public:
|
|
||||||
using value_type = BaseGraphicsData;
|
|
||||||
using pointer = BaseGraphicsData*;
|
|
||||||
using reference = BaseGraphicsData&;
|
|
||||||
using iterator_category = std::bidirectional_iterator_tag;
|
|
||||||
|
|
||||||
explicit iterator(BaseGraphicsData* node) : m_node(node) {}
|
|
||||||
BaseGraphicsData& operator*() const { return *m_node; }
|
|
||||||
bool operator!=(const iterator& other) const { return m_node != other.m_node; }
|
|
||||||
iterator& operator++() { m_node = m_node->m_next; return *this; }
|
|
||||||
iterator& operator--() { m_node = m_node->m_prev; return *this; }
|
|
||||||
};
|
|
||||||
|
|
||||||
iterator begin() { return iterator(this); }
|
iterator begin() { return iterator(this); }
|
||||||
iterator end() { return iterator(nullptr); }
|
iterator end() { return iterator(nullptr); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> GraphicsDataNode<IShaderPipeline, BaseGraphicsData>*&
|
template <> inline GraphicsDataNode<IShaderPipeline, BaseGraphicsData>*&
|
||||||
BaseGraphicsData::getHead<IShaderPipeline>() { return m_SPs; }
|
BaseGraphicsData::getHead<IShaderPipeline>() { return m_SPs; }
|
||||||
template <> GraphicsDataNode<IShaderDataBinding, BaseGraphicsData>*&
|
template <> inline GraphicsDataNode<IShaderDataBinding, BaseGraphicsData>*&
|
||||||
BaseGraphicsData::getHead<IShaderDataBinding>() { return m_SBinds; }
|
BaseGraphicsData::getHead<IShaderDataBinding>() { return m_SBinds; }
|
||||||
template <> GraphicsDataNode<IGraphicsBufferS, BaseGraphicsData>*&
|
template <> inline GraphicsDataNode<IGraphicsBufferS, BaseGraphicsData>*&
|
||||||
BaseGraphicsData::getHead<IGraphicsBufferS>() { return m_SBufs; }
|
BaseGraphicsData::getHead<IGraphicsBufferS>() { return m_SBufs; }
|
||||||
template <> GraphicsDataNode<IGraphicsBufferD, BaseGraphicsData>*&
|
template <> inline GraphicsDataNode<IGraphicsBufferD, BaseGraphicsData>*&
|
||||||
BaseGraphicsData::getHead<IGraphicsBufferD>() { return m_DBufs; }
|
BaseGraphicsData::getHead<IGraphicsBufferD>() { return m_DBufs; }
|
||||||
template <> GraphicsDataNode<ITextureS, BaseGraphicsData>*&
|
template <> inline GraphicsDataNode<ITextureS, BaseGraphicsData>*&
|
||||||
BaseGraphicsData::getHead<ITextureS>() { return m_STexs; }
|
BaseGraphicsData::getHead<ITextureS>() { return m_STexs; }
|
||||||
template <> GraphicsDataNode<ITextureSA, BaseGraphicsData>*&
|
template <> inline GraphicsDataNode<ITextureSA, BaseGraphicsData>*&
|
||||||
BaseGraphicsData::getHead<ITextureSA>() { return m_SATexs; }
|
BaseGraphicsData::getHead<ITextureSA>() { return m_SATexs; }
|
||||||
template <> GraphicsDataNode<ITextureD, BaseGraphicsData>*&
|
template <> inline GraphicsDataNode<ITextureD, BaseGraphicsData>*&
|
||||||
BaseGraphicsData::getHead<ITextureD>() { return m_DTexs; }
|
BaseGraphicsData::getHead<ITextureD>() { return m_DTexs; }
|
||||||
template <> GraphicsDataNode<ITextureR, BaseGraphicsData>*&
|
template <> inline GraphicsDataNode<ITextureR, BaseGraphicsData>*&
|
||||||
BaseGraphicsData::getHead<ITextureR>() { return m_RTexs; }
|
BaseGraphicsData::getHead<ITextureR>() { return m_RTexs; }
|
||||||
template <> GraphicsDataNode<IVertexFormat, BaseGraphicsData>*&
|
template <> inline GraphicsDataNode<IVertexFormat, BaseGraphicsData>*&
|
||||||
BaseGraphicsData::getHead<IVertexFormat>() { return m_VFmts; }
|
BaseGraphicsData::getHead<IVertexFormat>() { return m_VFmts; }
|
||||||
|
|
||||||
/** Private generalized pool container class.
|
/** Private generalized pool container class.
|
||||||
* Keeps head pointer to exactly one dynamic buffer while otherwise conforming to IGraphicsData
|
* Keeps head pointer to exactly one dynamic buffer while otherwise conforming to BaseGraphicsData
|
||||||
*/
|
*/
|
||||||
struct BaseGraphicsPool : IObj
|
struct BaseGraphicsPool : IObj
|
||||||
{
|
{
|
||||||
|
@ -124,6 +129,8 @@ struct BaseGraphicsPool : IObj
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lk(m_head.m_dataMutex);
|
std::lock_guard<std::mutex> lk(m_head.m_dataMutex);
|
||||||
m_next = head.m_poolHead;
|
m_next = head.m_poolHead;
|
||||||
|
if (m_next)
|
||||||
|
m_next->m_prev = this;
|
||||||
head.m_poolHead = this;
|
head.m_poolHead = this;
|
||||||
}
|
}
|
||||||
~BaseGraphicsPool()
|
~BaseGraphicsPool()
|
||||||
|
@ -138,32 +145,17 @@ struct BaseGraphicsPool : IObj
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (m_next)
|
if (m_next)
|
||||||
m_next->m_prev = m_head.m_poolHead;
|
m_next->m_prev = nullptr;
|
||||||
m_head.m_poolHead = m_next;
|
m_head.m_poolHead = m_next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class iterator
|
using iterator = DataIterator<BaseGraphicsPool>;
|
||||||
{
|
|
||||||
BaseGraphicsPool* m_node;
|
|
||||||
public:
|
|
||||||
using value_type = BaseGraphicsPool;
|
|
||||||
using pointer = BaseGraphicsPool*;
|
|
||||||
using reference = BaseGraphicsPool&;
|
|
||||||
using iterator_category = std::bidirectional_iterator_tag;
|
|
||||||
|
|
||||||
explicit iterator(BaseGraphicsPool* node) : m_node(node) {}
|
|
||||||
BaseGraphicsPool& operator*() const { return *m_node; }
|
|
||||||
bool operator!=(const iterator& other) const { return m_node != other.m_node; }
|
|
||||||
iterator& operator++() { m_node = m_node->m_next; return *this; }
|
|
||||||
iterator& operator--() { m_node = m_node->m_prev; return *this; }
|
|
||||||
};
|
|
||||||
|
|
||||||
iterator begin() { return iterator(this); }
|
iterator begin() { return iterator(this); }
|
||||||
iterator end() { return iterator(nullptr); }
|
iterator end() { return iterator(nullptr); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> GraphicsDataNode<IGraphicsBufferD, BaseGraphicsPool>*&
|
template <> inline GraphicsDataNode<IGraphicsBufferD, BaseGraphicsPool>*&
|
||||||
BaseGraphicsPool::getHead<IGraphicsBufferD>() { return m_DBufs; }
|
BaseGraphicsPool::getHead<IGraphicsBufferD>() { return m_DBufs; }
|
||||||
|
|
||||||
/** Private generalised graphics object node.
|
/** Private generalised graphics object node.
|
||||||
|
@ -182,6 +174,8 @@ struct GraphicsDataNode : NodeCls
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lk(m_data->m_head.m_dataMutex);
|
std::lock_guard<std::mutex> lk(m_data->m_head.m_dataMutex);
|
||||||
m_next = data->template getHead<NodeCls>();
|
m_next = data->template getHead<NodeCls>();
|
||||||
|
if (m_next)
|
||||||
|
m_next->m_prev = this;
|
||||||
data->template getHead<NodeCls>() = this;
|
data->template getHead<NodeCls>() = this;
|
||||||
}
|
}
|
||||||
~GraphicsDataNode()
|
~GraphicsDataNode()
|
||||||
|
@ -196,7 +190,7 @@ struct GraphicsDataNode : NodeCls
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (m_next)
|
if (m_next)
|
||||||
m_next->m_prev = m_data->template getHead<NodeCls>();
|
m_next->m_prev = nullptr;
|
||||||
m_data->template getHead<NodeCls>() = m_next;
|
m_data->template getHead<NodeCls>() = m_next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -221,6 +215,7 @@ struct GraphicsDataNode : NodeCls
|
||||||
iterator end() { return iterator(nullptr); }
|
iterator end() { return iterator(nullptr); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Hash table entry for owning sharable shader objects */
|
||||||
template <class FactoryImpl, class ShaderImpl>
|
template <class FactoryImpl, class ShaderImpl>
|
||||||
class IShareableShader
|
class IShareableShader
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,7 +34,8 @@ class GLDataFactoryImpl : public GLDataFactory, public GraphicsDataFactoryHead
|
||||||
uint32_t m_drawSamples;
|
uint32_t m_drawSamples;
|
||||||
std::unordered_map<uint64_t, std::unique_ptr<GLShareableShader>> m_sharedShaders;
|
std::unordered_map<uint64_t, std::unique_ptr<GLShareableShader>> m_sharedShaders;
|
||||||
public:
|
public:
|
||||||
GLDataFactoryImpl(IGraphicsContext* parent, uint32_t drawSamples);
|
GLDataFactoryImpl(IGraphicsContext* parent, uint32_t drawSamples)
|
||||||
|
: m_parent(parent), m_drawSamples(drawSamples) {}
|
||||||
|
|
||||||
Platform platform() const { return Platform::OpenGL; }
|
Platform platform() const { return Platform::OpenGL; }
|
||||||
const SystemChar* platformName() const { return _S("OpenGL"); }
|
const SystemChar* platformName() const { return _S("OpenGL"); }
|
||||||
|
@ -60,14 +61,13 @@ class GLGraphicsBufferS : public GraphicsDataNode<IGraphicsBufferS>
|
||||||
GLGraphicsBufferS(const ObjToken<BaseGraphicsData>& parent, BufferUse use, const void* data, size_t sz)
|
GLGraphicsBufferS(const ObjToken<BaseGraphicsData>& parent, BufferUse use, const void* data, size_t sz)
|
||||||
: GraphicsDataNode<IGraphicsBufferS>(parent)
|
: GraphicsDataNode<IGraphicsBufferS>(parent)
|
||||||
{
|
{
|
||||||
Log.report(logvisor::Info, "Create static buffer %p\n", this);
|
|
||||||
m_target = USE_TABLE[int(use)];
|
m_target = USE_TABLE[int(use)];
|
||||||
glGenBuffers(1, &m_buf);
|
glGenBuffers(1, &m_buf);
|
||||||
glBindBuffer(m_target, m_buf);
|
glBindBuffer(m_target, m_buf);
|
||||||
glBufferData(m_target, sz, data, GL_STATIC_DRAW);
|
glBufferData(m_target, sz, data, GL_STATIC_DRAW);
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
~GLGraphicsBufferS() {glDeleteBuffers(1, &m_buf); Log.report(logvisor::Info, "Delete static buffer %p\n", this); }
|
~GLGraphicsBufferS() { glDeleteBuffers(1, &m_buf); }
|
||||||
|
|
||||||
void bindVertex() const
|
void bindVertex() const
|
||||||
{glBindBuffer(GL_ARRAY_BUFFER, m_buf);}
|
{glBindBuffer(GL_ARRAY_BUFFER, m_buf);}
|
||||||
|
@ -94,7 +94,6 @@ class GLGraphicsBufferD : public GraphicsDataNode<IGraphicsBufferD, DataCls>
|
||||||
: GraphicsDataNode<IGraphicsBufferD, DataCls>(parent),
|
: GraphicsDataNode<IGraphicsBufferD, DataCls>(parent),
|
||||||
m_target(USE_TABLE[int(use)]), m_cpuBuf(new uint8_t[sz]), m_cpuSz(sz)
|
m_target(USE_TABLE[int(use)]), m_cpuBuf(new uint8_t[sz]), m_cpuSz(sz)
|
||||||
{
|
{
|
||||||
Log.report(logvisor::Info, "Create dynamic buffer %p\n", this);
|
|
||||||
glGenBuffers(3, m_bufs);
|
glGenBuffers(3, m_bufs);
|
||||||
for (int i=0 ; i<3 ; ++i)
|
for (int i=0 ; i<3 ; ++i)
|
||||||
{
|
{
|
||||||
|
@ -102,18 +101,44 @@ class GLGraphicsBufferD : public GraphicsDataNode<IGraphicsBufferD, DataCls>
|
||||||
glBufferData(m_target, m_cpuSz, nullptr, GL_STREAM_DRAW);
|
glBufferData(m_target, m_cpuSz, nullptr, GL_STREAM_DRAW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void update(int b);
|
|
||||||
public:
|
public:
|
||||||
~GLGraphicsBufferD() {glDeleteBuffers(3, m_bufs); Log.report(logvisor::Info, "Delete dynamic buffer %p\n", this);}
|
~GLGraphicsBufferD() { glDeleteBuffers(3, m_bufs); }
|
||||||
|
|
||||||
void load(const void* data, size_t sz);
|
void update(int b)
|
||||||
void* map(size_t sz);
|
{
|
||||||
void unmap();
|
int slot = 1 << b;
|
||||||
|
if ((slot & m_validMask) == 0)
|
||||||
|
{
|
||||||
|
glBindBuffer(m_target, m_bufs[b]);
|
||||||
|
glBufferSubData(m_target, 0, m_cpuSz, m_cpuBuf.get());
|
||||||
|
m_validMask |= slot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void bindVertex(int b);
|
void load(const void* data, size_t sz)
|
||||||
void bindIndex(int b);
|
{
|
||||||
void bindUniform(size_t idx, int b);
|
size_t bufSz = std::min(sz, m_cpuSz);
|
||||||
void bindUniformRange(size_t idx, GLintptr off, GLsizeiptr size, int b);
|
memcpy(m_cpuBuf.get(), data, bufSz);
|
||||||
|
m_validMask = 0;
|
||||||
|
}
|
||||||
|
void* map(size_t sz)
|
||||||
|
{
|
||||||
|
if (sz < m_cpuSz)
|
||||||
|
return nullptr;
|
||||||
|
return m_cpuBuf.get();
|
||||||
|
}
|
||||||
|
void unmap()
|
||||||
|
{
|
||||||
|
m_validMask = 0;
|
||||||
|
}
|
||||||
|
void bindVertex(int b)
|
||||||
|
{glBindBuffer(GL_ARRAY_BUFFER, m_bufs[b]);}
|
||||||
|
void bindIndex(int b)
|
||||||
|
{glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_bufs[b]);}
|
||||||
|
void bindUniform(size_t idx, int b)
|
||||||
|
{glBindBufferBase(GL_UNIFORM_BUFFER, idx, m_bufs[b]);}
|
||||||
|
void bindUniformRange(size_t idx, GLintptr off, GLsizeiptr size, int b)
|
||||||
|
{glBindBufferRange(GL_UNIFORM_BUFFER, idx, m_bufs[b], off, size);}
|
||||||
};
|
};
|
||||||
|
|
||||||
ObjToken<IGraphicsBufferS>
|
ObjToken<IGraphicsBufferS>
|
||||||
|
@ -294,16 +319,76 @@ class GLTextureD : public GraphicsDataNode<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(const ObjToken<BaseGraphicsData>& parent, size_t width, size_t height, TextureFormat fmt, TextureClampMode clampMode);
|
GLTextureD(const ObjToken<BaseGraphicsData>& parent, size_t width, size_t height,
|
||||||
void update(int b);
|
TextureFormat fmt, TextureClampMode clampMode)
|
||||||
|
: GraphicsDataNode<ITextureD>(parent), m_width(width), m_height(height)
|
||||||
|
{
|
||||||
|
int pxPitch = 4;
|
||||||
|
switch (fmt)
|
||||||
|
{
|
||||||
|
case TextureFormat::RGBA8:
|
||||||
|
m_intFormat = GL_RGBA8;
|
||||||
|
m_format = GL_RGBA;
|
||||||
|
pxPitch = 4;
|
||||||
|
break;
|
||||||
|
case TextureFormat::I8:
|
||||||
|
m_intFormat = GL_R8;
|
||||||
|
m_format = GL_RED;
|
||||||
|
pxPitch = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Log.report(logvisor::Fatal, "unsupported tex format");
|
||||||
|
}
|
||||||
|
m_cpuSz = width * height * pxPitch;
|
||||||
|
m_cpuBuf.reset(new uint8_t[m_cpuSz]);
|
||||||
|
|
||||||
|
glGenTextures(3, m_texs);
|
||||||
|
for (int i=0 ; i<3 ; ++i)
|
||||||
|
{
|
||||||
|
glBindTexture(GL_TEXTURE_2D, m_texs[i]);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, m_intFormat, width, height, 0, m_format, GL_UNSIGNED_BYTE, nullptr);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
SetClampMode(GL_TEXTURE_2D, clampMode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~GLTextureD();
|
~GLTextureD() { glDeleteTextures(3, m_texs); }
|
||||||
|
|
||||||
void load(const void* data, size_t sz);
|
void update(int b)
|
||||||
void* map(size_t sz);
|
{
|
||||||
void unmap();
|
int slot = 1 << b;
|
||||||
|
if ((slot & m_validMask) == 0)
|
||||||
|
{
|
||||||
|
glBindTexture(GL_TEXTURE_2D, m_texs[b]);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, m_intFormat, m_width, m_height, 0, m_format, GL_UNSIGNED_BYTE, m_cpuBuf.get());
|
||||||
|
m_validMask |= slot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void bind(size_t idx, int b);
|
void load(const void* data, size_t sz)
|
||||||
|
{
|
||||||
|
size_t bufSz = std::min(sz, m_cpuSz);
|
||||||
|
memcpy(m_cpuBuf.get(), data, bufSz);
|
||||||
|
m_validMask = 0;
|
||||||
|
}
|
||||||
|
void* map(size_t sz)
|
||||||
|
{
|
||||||
|
if (sz > m_cpuSz)
|
||||||
|
return nullptr;
|
||||||
|
return m_cpuBuf.get();
|
||||||
|
}
|
||||||
|
void unmap()
|
||||||
|
{
|
||||||
|
m_validMask = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bind(size_t idx, int b)
|
||||||
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE0 + idx);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, m_texs[b]);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_BIND_TEXS 4
|
#define MAX_BIND_TEXS 4
|
||||||
|
@ -323,7 +408,12 @@ class GLTextureR : public GraphicsDataNode<ITextureR>
|
||||||
GLTextureR(const ObjToken<BaseGraphicsData>& parent, GLCommandQueue* q, size_t width, size_t height, size_t samples,
|
GLTextureR(const ObjToken<BaseGraphicsData>& parent, GLCommandQueue* q, size_t width, size_t height, size_t samples,
|
||||||
TextureClampMode clampMode, size_t colorBindCount, size_t depthBindCount);
|
TextureClampMode clampMode, size_t colorBindCount, size_t depthBindCount);
|
||||||
public:
|
public:
|
||||||
~GLTextureR();
|
~GLTextureR()
|
||||||
|
{
|
||||||
|
glDeleteTextures(2, m_texs);
|
||||||
|
glDeleteTextures(MAX_BIND_TEXS * 2, m_bindTexs[0]);
|
||||||
|
glDeleteFramebuffers(1, &m_fbo);
|
||||||
|
}
|
||||||
|
|
||||||
void bind(size_t idx, int bindIdx, bool depth) const
|
void bind(size_t idx, int bindIdx, bool depth) const
|
||||||
{
|
{
|
||||||
|
@ -673,15 +763,13 @@ ObjToken<IShaderPipeline> GLDataFactory::Context::newShaderPipeline
|
||||||
|
|
||||||
struct GLVertexFormat : GraphicsDataNode<IVertexFormat>
|
struct GLVertexFormat : GraphicsDataNode<IVertexFormat>
|
||||||
{
|
{
|
||||||
GLCommandQueue* m_q;
|
|
||||||
GLuint m_vao[3] = {};
|
GLuint m_vao[3] = {};
|
||||||
size_t m_elementCount;
|
|
||||||
GLuint m_baseVert, m_baseInst;
|
GLuint m_baseVert, m_baseInst;
|
||||||
std::unique_ptr<VertexElementDescriptor[]> m_elements;
|
std::vector<VertexElementDescriptor> m_elements;
|
||||||
GLVertexFormat(const ObjToken<BaseGraphicsData>& parent, GLCommandQueue* q, size_t elementCount,
|
GLVertexFormat(const ObjToken<BaseGraphicsData>& parent, GLCommandQueue* q,
|
||||||
const VertexElementDescriptor* elements,
|
size_t elementCount, const VertexElementDescriptor* elements,
|
||||||
size_t baseVert, size_t baseInst);
|
size_t baseVert, size_t baseInst);
|
||||||
~GLVertexFormat();
|
~GLVertexFormat() { glDeleteVertexArrays(3, m_vao); }
|
||||||
void bind(int idx) const { glBindVertexArray(m_vao[idx]); }
|
void bind(int idx) const { glBindVertexArray(m_vao[idx]); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -735,7 +823,7 @@ struct GLShaderDataBinding : GraphicsDataNode<IShaderDataBinding>
|
||||||
m_texs.reserve(texCount);
|
m_texs.reserve(texCount);
|
||||||
for (size_t i=0 ; i<texCount ; ++i)
|
for (size_t i=0 ; i<texCount ; ++i)
|
||||||
{
|
{
|
||||||
m_texs[i] = {texs[i], bindTexIdx ? bindTexIdx[i] : 0, depthBind ? depthBind[i] : false};
|
m_texs.push_back({texs[i], bindTexIdx ? bindTexIdx[i] : 0, depthBind ? depthBind[i] : false});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void bind(int b) const
|
void bind(int b) const
|
||||||
|
@ -817,9 +905,6 @@ GLDataFactory::Context::newShaderDataBinding(const ObjToken<IShaderPipeline>& pi
|
||||||
ubufOffs, ubufSizes, texCount, texs, texBindIdx, depthBind)};
|
ubufOffs, ubufSizes, texCount, texs, texBindIdx, depthBind)};
|
||||||
}
|
}
|
||||||
|
|
||||||
GLDataFactoryImpl::GLDataFactoryImpl(IGraphicsContext* parent, uint32_t drawSamples)
|
|
||||||
: m_parent(parent), m_drawSamples(drawSamples) {}
|
|
||||||
|
|
||||||
GLDataFactory::Context::Context(GLDataFactory& parent)
|
GLDataFactory::Context::Context(GLDataFactory& parent)
|
||||||
: m_parent(parent), m_data(new BaseGraphicsData(static_cast<GLDataFactoryImpl&>(parent)))
|
: m_parent(parent), m_data(new BaseGraphicsData(static_cast<GLDataFactoryImpl&>(parent)))
|
||||||
{}
|
{}
|
||||||
|
@ -974,13 +1059,13 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||||
|
|
||||||
size_t stride = 0;
|
size_t stride = 0;
|
||||||
size_t instStride = 0;
|
size_t instStride = 0;
|
||||||
for (size_t i=0 ; i<fmt->m_elementCount ; ++i)
|
for (size_t i=0 ; i<fmt->m_elements.size() ; ++i)
|
||||||
{
|
{
|
||||||
const VertexElementDescriptor* desc = &fmt->m_elements[i];
|
const VertexElementDescriptor& desc = fmt->m_elements[i];
|
||||||
if ((desc->semantic & VertexSemantic::Instanced) != VertexSemantic::None)
|
if ((desc.semantic & VertexSemantic::Instanced) != VertexSemantic::None)
|
||||||
instStride += SEMANTIC_SIZE_TABLE[int(desc->semantic & VertexSemantic::SemanticMask)];
|
instStride += SEMANTIC_SIZE_TABLE[int(desc.semantic & VertexSemantic::SemanticMask)];
|
||||||
else
|
else
|
||||||
stride += SEMANTIC_SIZE_TABLE[int(desc->semantic & VertexSemantic::SemanticMask)];
|
stride += SEMANTIC_SIZE_TABLE[int(desc.semantic & VertexSemantic::SemanticMask)];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int b=0 ; b<3 ; ++b)
|
for (int b=0 ; b<3 ; ++b)
|
||||||
|
@ -990,28 +1075,28 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||||
glBindVertexArray(fmt->m_vao[b]);
|
glBindVertexArray(fmt->m_vao[b]);
|
||||||
IGraphicsBuffer* lastVBO = nullptr;
|
IGraphicsBuffer* lastVBO = nullptr;
|
||||||
IGraphicsBuffer* lastEBO = nullptr;
|
IGraphicsBuffer* lastEBO = nullptr;
|
||||||
for (size_t i=0 ; i<fmt->m_elementCount ; ++i)
|
for (size_t i=0 ; i<fmt->m_elements.size() ; ++i)
|
||||||
{
|
{
|
||||||
const VertexElementDescriptor* desc = &fmt->m_elements[i];
|
const VertexElementDescriptor& desc = fmt->m_elements[i];
|
||||||
if (desc->vertBuffer != lastVBO)
|
if (desc.vertBuffer.get() != lastVBO)
|
||||||
{
|
{
|
||||||
lastVBO = desc->vertBuffer;
|
lastVBO = desc.vertBuffer.get();
|
||||||
if (lastVBO->dynamic())
|
if (lastVBO->dynamic())
|
||||||
static_cast<GLGraphicsBufferD<BaseGraphicsData>*>(lastVBO)->bindVertex(b);
|
static_cast<GLGraphicsBufferD<BaseGraphicsData>*>(lastVBO)->bindVertex(b);
|
||||||
else
|
else
|
||||||
static_cast<GLGraphicsBufferS*>(lastVBO)->bindVertex();
|
static_cast<GLGraphicsBufferS*>(lastVBO)->bindVertex();
|
||||||
}
|
}
|
||||||
if (desc->indexBuffer != lastEBO)
|
if (desc.indexBuffer.get() != lastEBO)
|
||||||
{
|
{
|
||||||
lastEBO = desc->indexBuffer;
|
lastEBO = desc.indexBuffer.get();
|
||||||
if (lastEBO->dynamic())
|
if (lastEBO->dynamic())
|
||||||
static_cast<GLGraphicsBufferD<BaseGraphicsData>*>(lastEBO)->bindIndex(b);
|
static_cast<GLGraphicsBufferD<BaseGraphicsData>*>(lastEBO)->bindIndex(b);
|
||||||
else
|
else
|
||||||
static_cast<GLGraphicsBufferS*>(lastEBO)->bindIndex();
|
static_cast<GLGraphicsBufferS*>(lastEBO)->bindIndex();
|
||||||
}
|
}
|
||||||
glEnableVertexAttribArray(i);
|
glEnableVertexAttribArray(i);
|
||||||
int maskedSem = int(desc->semantic & VertexSemantic::SemanticMask);
|
int maskedSem = int(desc.semantic & VertexSemantic::SemanticMask);
|
||||||
if ((desc->semantic & VertexSemantic::Instanced) != VertexSemantic::None)
|
if ((desc.semantic & VertexSemantic::Instanced) != VertexSemantic::None)
|
||||||
{
|
{
|
||||||
glVertexAttribPointer(i, SEMANTIC_COUNT_TABLE[maskedSem],
|
glVertexAttribPointer(i, SEMANTIC_COUNT_TABLE[maskedSem],
|
||||||
SEMANTIC_TYPE_TABLE[maskedSem], GL_TRUE, instStride, (void*)instOffset);
|
SEMANTIC_TYPE_TABLE[maskedSem], GL_TRUE, instStride, (void*)instOffset);
|
||||||
|
@ -1350,39 +1435,12 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||||
m_pendingFmtAdds.push_back(fmt);
|
m_pendingFmtAdds.push_back(fmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void delVertexFormat(const ObjToken<GLVertexFormat>& fmt)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
std::unique_lock<std::mutex> lk(m_mt);
|
|
||||||
bool foundAdd = false;
|
|
||||||
for (GLVertexFormat*& afmt : m_pendingFmtAdds)
|
|
||||||
if (afmt == fmt)
|
|
||||||
{
|
|
||||||
foundAdd = true;
|
|
||||||
afmt = nullptr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!foundAdd)
|
|
||||||
m_pendingFmtDels.push_back({fmt->m_vao[0], fmt->m_vao[1], fmt->m_vao[2]});
|
|
||||||
#endif
|
|
||||||
glDeleteVertexArrays(3, fmt->m_vao);
|
|
||||||
}
|
|
||||||
|
|
||||||
void addFBO(const ObjToken<ITextureR>& tex)
|
void addFBO(const ObjToken<ITextureR>& tex)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lk(m_mt);
|
std::unique_lock<std::mutex> lk(m_mt);
|
||||||
m_pendingFboAdds.push_back(tex);
|
m_pendingFboAdds.push_back(tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void delFBO(const ObjToken<ITextureR>& tex)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
std::unique_lock<std::mutex> lk(m_mt);
|
|
||||||
m_pendingFboDels.push_back(tex->m_fbo);
|
|
||||||
#endif
|
|
||||||
glDeleteFramebuffers(1, &tex.cast<GLTextureR>()->m_fbo);
|
|
||||||
}
|
|
||||||
|
|
||||||
void execute()
|
void execute()
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lk(m_mt);
|
std::unique_lock<std::mutex> lk(m_mt);
|
||||||
|
@ -1432,125 +1490,12 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class DataCls>
|
|
||||||
void GLGraphicsBufferD<DataCls>::update(int b)
|
|
||||||
{
|
|
||||||
int slot = 1 << b;
|
|
||||||
if ((slot & m_validMask) == 0)
|
|
||||||
{
|
|
||||||
glBindBuffer(m_target, m_bufs[b]);
|
|
||||||
glBufferSubData(m_target, 0, m_cpuSz, m_cpuBuf.get());
|
|
||||||
m_validMask |= slot;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class DataCls>
|
|
||||||
void GLGraphicsBufferD<DataCls>::load(const void* data, size_t sz)
|
|
||||||
{
|
|
||||||
size_t bufSz = std::min(sz, m_cpuSz);
|
|
||||||
memcpy(m_cpuBuf.get(), data, bufSz);
|
|
||||||
m_validMask = 0;
|
|
||||||
}
|
|
||||||
template<class DataCls>
|
|
||||||
void* GLGraphicsBufferD<DataCls>::map(size_t sz)
|
|
||||||
{
|
|
||||||
if (sz < m_cpuSz)
|
|
||||||
return nullptr;
|
|
||||||
return m_cpuBuf.get();
|
|
||||||
}
|
|
||||||
template<class DataCls>
|
|
||||||
void GLGraphicsBufferD<DataCls>::unmap()
|
|
||||||
{
|
|
||||||
m_validMask = 0;
|
|
||||||
}
|
|
||||||
template<class DataCls>
|
|
||||||
void GLGraphicsBufferD<DataCls>::bindVertex(int b)
|
|
||||||
{glBindBuffer(GL_ARRAY_BUFFER, m_bufs[b]);}
|
|
||||||
template<class DataCls>
|
|
||||||
void GLGraphicsBufferD<DataCls>::bindIndex(int b)
|
|
||||||
{glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_bufs[b]);}
|
|
||||||
template<class DataCls>
|
|
||||||
void GLGraphicsBufferD<DataCls>::bindUniform(size_t idx, int b)
|
|
||||||
{glBindBufferBase(GL_UNIFORM_BUFFER, idx, m_bufs[b]);}
|
|
||||||
template<class DataCls>
|
|
||||||
void GLGraphicsBufferD<DataCls>::bindUniformRange(size_t idx, GLintptr off, GLsizeiptr size, int b)
|
|
||||||
{glBindBufferRange(GL_UNIFORM_BUFFER, idx, m_bufs[b], off, size);}
|
|
||||||
|
|
||||||
ObjToken<IGraphicsBufferD>
|
ObjToken<IGraphicsBufferD>
|
||||||
GLDataFactory::Context::newDynamicBuffer(BufferUse use, size_t stride, size_t count)
|
GLDataFactory::Context::newDynamicBuffer(BufferUse use, size_t stride, size_t count)
|
||||||
{
|
{
|
||||||
return {new GLGraphicsBufferD<BaseGraphicsData>(m_data, use, stride * count)};
|
return {new GLGraphicsBufferD<BaseGraphicsData>(m_data, use, stride * count)};
|
||||||
}
|
}
|
||||||
|
|
||||||
GLTextureD::GLTextureD(const ObjToken<BaseGraphicsData>& parent, size_t width, size_t height, TextureFormat fmt,
|
|
||||||
TextureClampMode clampMode)
|
|
||||||
: GraphicsDataNode<ITextureD>(parent), m_width(width), m_height(height)
|
|
||||||
{
|
|
||||||
int pxPitch = 4;
|
|
||||||
switch (fmt)
|
|
||||||
{
|
|
||||||
case TextureFormat::RGBA8:
|
|
||||||
m_intFormat = GL_RGBA8;
|
|
||||||
m_format = GL_RGBA;
|
|
||||||
pxPitch = 4;
|
|
||||||
break;
|
|
||||||
case TextureFormat::I8:
|
|
||||||
m_intFormat = GL_R8;
|
|
||||||
m_format = GL_RED;
|
|
||||||
pxPitch = 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Log.report(logvisor::Fatal, "unsupported tex format");
|
|
||||||
}
|
|
||||||
m_cpuSz = width * height * pxPitch;
|
|
||||||
m_cpuBuf.reset(new uint8_t[m_cpuSz]);
|
|
||||||
|
|
||||||
glGenTextures(3, m_texs);
|
|
||||||
for (int i=0 ; i<3 ; ++i)
|
|
||||||
{
|
|
||||||
glBindTexture(GL_TEXTURE_2D, m_texs[i]);
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, m_intFormat, width, height, 0, m_format, GL_UNSIGNED_BYTE, nullptr);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
SetClampMode(GL_TEXTURE_2D, clampMode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
GLTextureD::~GLTextureD() { glDeleteTextures(3, m_texs); }
|
|
||||||
|
|
||||||
void GLTextureD::update(int b)
|
|
||||||
{
|
|
||||||
int slot = 1 << b;
|
|
||||||
if ((slot & m_validMask) == 0)
|
|
||||||
{
|
|
||||||
glBindTexture(GL_TEXTURE_2D, m_texs[b]);
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, m_intFormat, m_width, m_height, 0, m_format, GL_UNSIGNED_BYTE, m_cpuBuf.get());
|
|
||||||
m_validMask |= slot;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLTextureD::load(const void* data, size_t sz)
|
|
||||||
{
|
|
||||||
size_t bufSz = std::min(sz, m_cpuSz);
|
|
||||||
memcpy(m_cpuBuf.get(), data, bufSz);
|
|
||||||
m_validMask = 0;
|
|
||||||
}
|
|
||||||
void* GLTextureD::map(size_t sz)
|
|
||||||
{
|
|
||||||
if (sz > m_cpuSz)
|
|
||||||
return nullptr;
|
|
||||||
return m_cpuBuf.get();
|
|
||||||
}
|
|
||||||
void GLTextureD::unmap()
|
|
||||||
{
|
|
||||||
m_validMask = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLTextureD::bind(size_t idx, int b)
|
|
||||||
{
|
|
||||||
glActiveTexture(GL_TEXTURE0 + idx);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, m_texs[b]);
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjToken<ITextureD>
|
ObjToken<ITextureD>
|
||||||
GLDataFactory::Context::newDynamicTexture(size_t width, size_t height, TextureFormat fmt, TextureClampMode clampMode)
|
GLDataFactory::Context::newDynamicTexture(size_t width, size_t height, TextureFormat fmt, TextureClampMode clampMode)
|
||||||
{
|
{
|
||||||
|
@ -1612,13 +1557,6 @@ GLTextureR::GLTextureR(const ObjToken<BaseGraphicsData>& parent, GLCommandQueue*
|
||||||
m_q->addFBO(this);
|
m_q->addFBO(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLTextureR::~GLTextureR()
|
|
||||||
{
|
|
||||||
glDeleteTextures(2, m_texs);
|
|
||||||
glDeleteTextures(MAX_BIND_TEXS * 2, m_bindTexs[0]);
|
|
||||||
m_q->delFBO(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjToken<ITextureR>
|
ObjToken<ITextureR>
|
||||||
GLDataFactory::Context::newRenderTexture(size_t width, size_t height, TextureClampMode clampMode,
|
GLDataFactory::Context::newRenderTexture(size_t width, size_t height, TextureClampMode clampMode,
|
||||||
size_t colorBindingCount, size_t depthBindingCount)
|
size_t colorBindingCount, size_t depthBindingCount)
|
||||||
|
@ -1631,20 +1569,17 @@ GLDataFactory::Context::newRenderTexture(size_t width, size_t height, TextureCla
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLVertexFormat::GLVertexFormat(const ObjToken<BaseGraphicsData>& parent, GLCommandQueue* q, size_t elementCount,
|
GLVertexFormat::GLVertexFormat(const ObjToken<BaseGraphicsData>& parent, GLCommandQueue* q,
|
||||||
const VertexElementDescriptor* elements,
|
size_t elementCount, const VertexElementDescriptor* elements,
|
||||||
size_t baseVert, size_t baseInst)
|
size_t baseVert, size_t baseInst)
|
||||||
: GraphicsDataNode<IVertexFormat>(parent),
|
: GraphicsDataNode<IVertexFormat>(parent),
|
||||||
m_q(q),
|
|
||||||
m_elementCount(elementCount),
|
|
||||||
m_elements(new VertexElementDescriptor[elementCount]),
|
|
||||||
m_baseVert(baseVert), m_baseInst(baseInst)
|
m_baseVert(baseVert), m_baseInst(baseInst)
|
||||||
{
|
{
|
||||||
|
m_elements.reserve(elementCount);
|
||||||
for (size_t i=0 ; i<elementCount ; ++i)
|
for (size_t i=0 ; i<elementCount ; ++i)
|
||||||
m_elements[i] = elements[i];
|
m_elements.push_back(elements[i]);
|
||||||
m_q->addVertexFormat(this);
|
q->addVertexFormat(this);
|
||||||
}
|
}
|
||||||
GLVertexFormat::~GLVertexFormat() { m_q->delVertexFormat(this); }
|
|
||||||
|
|
||||||
ObjToken<IVertexFormat> GLDataFactory::Context::newVertexFormat
|
ObjToken<IVertexFormat> GLDataFactory::Context::newVertexFormat
|
||||||
(size_t elementCount, const VertexElementDescriptor* elements,
|
(size_t elementCount, const VertexElementDescriptor* elements,
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -215,7 +215,6 @@ public:
|
||||||
~GraphicsContextCocoaGL()
|
~GraphicsContextCocoaGL()
|
||||||
{
|
{
|
||||||
m_commandQueue->stopRenderer();
|
m_commandQueue->stopRenderer();
|
||||||
m_dataFactory->destroyAllData();
|
|
||||||
delete m_commandQueue;
|
delete m_commandQueue;
|
||||||
delete m_dataFactory;
|
delete m_dataFactory;
|
||||||
printf("CONTEXT DESTROYED\n");
|
printf("CONTEXT DESTROYED\n");
|
||||||
|
@ -374,7 +373,6 @@ public:
|
||||||
~GraphicsContextCocoaMetal()
|
~GraphicsContextCocoaMetal()
|
||||||
{
|
{
|
||||||
m_commandQueue->stopRenderer();
|
m_commandQueue->stopRenderer();
|
||||||
m_dataFactory->destroyAllData();
|
|
||||||
delete m_commandQueue;
|
delete m_commandQueue;
|
||||||
delete m_dataFactory;
|
delete m_dataFactory;
|
||||||
m_metalCtx->m_windows.erase(m_parentWindow);
|
m_metalCtx->m_windows.erase(m_parentWindow);
|
||||||
|
|
|
@ -157,7 +157,7 @@ struct CTestWindowCallback : IWindowCallback
|
||||||
bool m_rectDirty = false;
|
bool m_rectDirty = false;
|
||||||
bool m_windowInvalid = false;
|
bool m_windowInvalid = false;
|
||||||
|
|
||||||
void resized(const SWindowRect& rect)
|
void resized(const SWindowRect& rect, bool sync)
|
||||||
{
|
{
|
||||||
m_lastRect = rect;
|
m_lastRect = rect;
|
||||||
m_rectDirty = true;
|
m_rectDirty = true;
|
||||||
|
@ -247,8 +247,8 @@ struct TestApplicationCallback : IApplicationCallback
|
||||||
CTestWindowCallback windowCallback;
|
CTestWindowCallback windowCallback;
|
||||||
bool running = true;
|
bool running = true;
|
||||||
|
|
||||||
IShaderDataBinding* m_binding = nullptr;
|
boo::ObjToken<IShaderDataBinding> m_binding;
|
||||||
ITextureR* m_renderTarget = nullptr;
|
boo::ObjToken<ITextureR> m_renderTarget;
|
||||||
|
|
||||||
std::mutex m_mt;
|
std::mutex m_mt;
|
||||||
std::condition_variable m_cv;
|
std::condition_variable m_cv;
|
||||||
|
@ -256,13 +256,13 @@ struct TestApplicationCallback : IApplicationCallback
|
||||||
std::mutex m_initmt;
|
std::mutex m_initmt;
|
||||||
std::condition_variable m_initcv;
|
std::condition_variable m_initcv;
|
||||||
|
|
||||||
static GraphicsDataToken LoaderProc(TestApplicationCallback* self)
|
static void LoaderProc(TestApplicationCallback* self)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lk(self->m_initmt);
|
std::unique_lock<std::mutex> lk(self->m_initmt);
|
||||||
|
|
||||||
IGraphicsDataFactory* factory = self->mainWindow->getLoadContextDataFactory();
|
IGraphicsDataFactory* factory = self->mainWindow->getLoadContextDataFactory();
|
||||||
|
|
||||||
GraphicsDataToken data = factory->commitTransaction([&](IGraphicsDataFactory::Context& ctx) -> bool
|
factory->commitTransaction([&](IGraphicsDataFactory::Context& ctx) -> bool
|
||||||
{
|
{
|
||||||
/* Create render target */
|
/* Create render target */
|
||||||
int x, y, w, h;
|
int x, y, w, h;
|
||||||
|
@ -282,16 +282,15 @@ struct TestApplicationCallback : IApplicationCallback
|
||||||
{{0.5,-0.5},{1.0,0.0}},
|
{{0.5,-0.5},{1.0,0.0}},
|
||||||
{{-0.5,-0.5},{0.0,0.0}}
|
{{-0.5,-0.5},{0.0,0.0}}
|
||||||
};
|
};
|
||||||
IGraphicsBuffer* vbo =
|
auto vbo = ctx.newStaticBuffer(BufferUse::Vertex, quad, sizeof(Vert), 4);
|
||||||
ctx.newStaticBuffer(BufferUse::Vertex, quad, sizeof(Vert), 4);
|
|
||||||
|
|
||||||
/* Make vertex format */
|
/* Make vertex format */
|
||||||
VertexElementDescriptor descs[2] =
|
VertexElementDescriptor descs[2] =
|
||||||
{
|
{
|
||||||
{vbo, nullptr, VertexSemantic::Position3},
|
{vbo.get(), nullptr, VertexSemantic::Position3},
|
||||||
{vbo, nullptr, VertexSemantic::UV2}
|
{vbo.get(), nullptr, VertexSemantic::UV2}
|
||||||
};
|
};
|
||||||
IVertexFormat* vfmt = ctx.newVertexFormat(2, descs);
|
auto vfmt = ctx.newVertexFormat(2, descs);
|
||||||
|
|
||||||
/* Make ramp texture */
|
/* Make ramp texture */
|
||||||
using Pixel = uint8_t[4];
|
using Pixel = uint8_t[4];
|
||||||
|
@ -304,11 +303,11 @@ struct TestApplicationCallback : IApplicationCallback
|
||||||
tex[i][j][2] = 0;
|
tex[i][j][2] = 0;
|
||||||
tex[i][j][3] = 0xff;
|
tex[i][j][3] = 0xff;
|
||||||
}
|
}
|
||||||
ITexture* texture =
|
boo::ObjToken<ITexture> texture = ctx.newStaticTexture(256, 256, 1, TextureFormat::RGBA8,
|
||||||
ctx.newStaticTexture(256, 256, 1, TextureFormat::RGBA8, boo::TextureClampMode::Repeat, tex, 256*256*4);
|
boo::TextureClampMode::Repeat, tex, 256*256*4).get();
|
||||||
|
|
||||||
/* Make shader pipeline */
|
/* Make shader pipeline */
|
||||||
IShaderPipeline* pipeline = nullptr;
|
boo::ObjToken<IShaderPipeline> pipeline;
|
||||||
auto plat = ctx.platform();
|
auto plat = ctx.platform();
|
||||||
if (plat == IGraphicsDataFactory::Platform::OpenGL)
|
if (plat == IGraphicsDataFactory::Platform::OpenGL)
|
||||||
{
|
{
|
||||||
|
@ -437,7 +436,7 @@ struct TestApplicationCallback : IApplicationCallback
|
||||||
" return tex.sample(samp, d.out_uv);\n"
|
" return tex.sample(samp, d.out_uv);\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
pipeline = metalF.newShaderPipeline(VS, FS, vfmt, 1,
|
pipeline = metalF.newShaderPipeline(VS, FS, nullptr, nullptr, vfmt, 1,
|
||||||
BlendFactor::One, BlendFactor::Zero, Primitive::TriStrips,
|
BlendFactor::One, BlendFactor::Zero, Primitive::TriStrips,
|
||||||
boo::ZTest::LEqual, true, true, true, boo::CullMode::None);
|
boo::ZTest::LEqual, true, true, true, boo::CullMode::None);
|
||||||
}
|
}
|
||||||
|
@ -445,7 +444,7 @@ struct TestApplicationCallback : IApplicationCallback
|
||||||
|
|
||||||
/* Make shader data binding */
|
/* Make shader data binding */
|
||||||
self->m_binding =
|
self->m_binding =
|
||||||
ctx.newShaderDataBinding(pipeline, vfmt, vbo, nullptr, nullptr, 0, nullptr, nullptr,
|
ctx.newShaderDataBinding(pipeline, vfmt, vbo.get(), nullptr, nullptr, 0, nullptr, nullptr,
|
||||||
1, &texture, nullptr, nullptr);
|
1, &texture, nullptr, nullptr);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -463,7 +462,6 @@ struct TestApplicationCallback : IApplicationCallback
|
||||||
if (!self->running)
|
if (!self->running)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int appMain(IApplication* app)
|
int appMain(IApplication* app)
|
||||||
|
|
Loading…
Reference in New Issue