mirror of https://github.com/AxioDL/boo.git
Addresses some resource lifetime issues in OpenGL and Vulkan
This commit is contained in:
parent
10364557b9
commit
0f96af94f6
|
@ -192,7 +192,7 @@ else(NOT GEKKO)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
include_directories(${DBUS_INCLUDE_DIR} ${DBUS_ARCH_INCLUDE_DIR})
|
include_directories(${DBUS_INCLUDE_DIR} ${DBUS_ARCH_INCLUDE_DIR})
|
||||||
list(APPEND _BOO_SYS_LIBS X11 Xi GL asound ${DBUS_LIBRARY} pthread)
|
list(APPEND _BOO_SYS_LIBS X11 Xi Xrandr GL asound ${DBUS_LIBRARY} pthread)
|
||||||
|
|
||||||
if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
||||||
message(STATUS "Enabling Vulkan support")
|
message(STATUS "Enabling Vulkan support")
|
||||||
|
|
|
@ -95,6 +95,7 @@ public:
|
||||||
{ m_parent = other.m_parent; other.m_parent = nullptr; return *this; }
|
{ m_parent = other.m_parent; other.m_parent = nullptr; return *this; }
|
||||||
Token(Token&& other)
|
Token(Token&& other)
|
||||||
{ m_parent = other.m_parent; other.m_parent = nullptr; }
|
{ m_parent = other.m_parent; other.m_parent = nullptr; }
|
||||||
|
void reset() { if (m_parent) m_parent->decrement(); m_parent = nullptr; }
|
||||||
~Token() { if (m_parent) m_parent->decrement(); }
|
~Token() { if (m_parent) m_parent->decrement(); }
|
||||||
operator bool() const { return m_parent != nullptr; }
|
operator bool() const { return m_parent != nullptr; }
|
||||||
ShaderImpl& get() const { return static_cast<ShaderImpl&>(*m_parent); }
|
ShaderImpl& get() const { return static_cast<ShaderImpl&>(*m_parent); }
|
||||||
|
|
|
@ -67,6 +67,7 @@ public:
|
||||||
ThreadLocalPtr<struct GLData> GLDataFactoryImpl::m_deferredData;
|
ThreadLocalPtr<struct GLData> GLDataFactoryImpl::m_deferredData;
|
||||||
struct GLData : IGraphicsDataPriv
|
struct GLData : IGraphicsDataPriv
|
||||||
{
|
{
|
||||||
|
int m_deadCounter = 0;
|
||||||
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;
|
||||||
std::vector<std::unique_ptr<class GLGraphicsBufferS>> m_SBufs;
|
std::vector<std::unique_ptr<class GLGraphicsBufferS>> m_SBufs;
|
||||||
|
@ -85,6 +86,7 @@ struct GLPoolItem : IGraphicsDataPriv
|
||||||
|
|
||||||
struct GLPool : IGraphicsBufferPool
|
struct GLPool : IGraphicsBufferPool
|
||||||
{
|
{
|
||||||
|
int m_deadCounter = 0;
|
||||||
std::unordered_set<GLPoolItem*> m_items;
|
std::unordered_set<GLPoolItem*> m_items;
|
||||||
~GLPool()
|
~GLPool()
|
||||||
{
|
{
|
||||||
|
@ -450,9 +452,9 @@ class GLShaderPipeline : public IShaderPipeline
|
||||||
friend class GLDataFactory;
|
friend class GLDataFactory;
|
||||||
friend struct GLCommandQueue;
|
friend struct GLCommandQueue;
|
||||||
friend struct GLShaderDataBinding;
|
friend struct GLShaderDataBinding;
|
||||||
GLShareableShader::Token m_vert;
|
mutable GLShareableShader::Token m_vert;
|
||||||
GLShareableShader::Token m_frag;
|
mutable GLShareableShader::Token m_frag;
|
||||||
GLuint m_prog = 0;
|
mutable GLuint m_prog = 0;
|
||||||
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;
|
||||||
|
@ -462,10 +464,11 @@ class GLShaderPipeline : public IShaderPipeline
|
||||||
bool m_alphaWrite = true;
|
bool m_alphaWrite = true;
|
||||||
bool m_subtractBlend = false;
|
bool m_subtractBlend = false;
|
||||||
CullMode m_culling;
|
CullMode m_culling;
|
||||||
std::vector<GLint> m_uniLocs;
|
mutable std::vector<GLint> m_uniLocs;
|
||||||
|
mutable std::vector<std::string> m_texNames;
|
||||||
|
mutable std::vector<std::string> m_blockNames;
|
||||||
GLShaderPipeline(GLData* parent) : IShaderPipeline(parent) {}
|
GLShaderPipeline(GLData* parent) : IShaderPipeline(parent) {}
|
||||||
public:
|
public:
|
||||||
operator bool() const {return m_prog != 0;}
|
|
||||||
~GLShaderPipeline() { if (m_prog) glDeleteProgram(m_prog); }
|
~GLShaderPipeline() { if (m_prog) glDeleteProgram(m_prog); }
|
||||||
GLShaderPipeline& operator=(const GLShaderPipeline&) = delete;
|
GLShaderPipeline& operator=(const GLShaderPipeline&) = delete;
|
||||||
GLShaderPipeline(const GLShaderPipeline&) = delete;
|
GLShaderPipeline(const GLShaderPipeline&) = delete;
|
||||||
|
@ -485,6 +488,8 @@ public:
|
||||||
m_subtractBlend = other.m_subtractBlend;
|
m_subtractBlend = other.m_subtractBlend;
|
||||||
m_culling = other.m_culling;
|
m_culling = other.m_culling;
|
||||||
m_uniLocs = std::move(other.m_uniLocs);
|
m_uniLocs = std::move(other.m_uniLocs);
|
||||||
|
m_texNames = std::move(other.m_texNames);
|
||||||
|
m_blockNames = std::move(other.m_blockNames);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
GLShaderPipeline(GLShaderPipeline&& other)
|
GLShaderPipeline(GLShaderPipeline&& other)
|
||||||
|
@ -492,7 +497,71 @@ public:
|
||||||
|
|
||||||
GLuint bind() const
|
GLuint bind() const
|
||||||
{
|
{
|
||||||
glUseProgram(m_prog);
|
if (!m_prog)
|
||||||
|
{
|
||||||
|
m_prog = glCreateProgram();
|
||||||
|
if (!m_prog)
|
||||||
|
{
|
||||||
|
Log.report(logvisor::Error, "unable to create shader program");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
glAttachShader(m_prog, m_vert.get().m_shader);
|
||||||
|
glAttachShader(m_prog, m_frag.get().m_shader);
|
||||||
|
|
||||||
|
glLinkProgram(m_prog);
|
||||||
|
|
||||||
|
glDetachShader(m_prog, m_vert.get().m_shader);
|
||||||
|
glDetachShader(m_prog, m_frag.get().m_shader);
|
||||||
|
|
||||||
|
m_vert.reset();
|
||||||
|
m_frag.reset();
|
||||||
|
|
||||||
|
GLint status;
|
||||||
|
glGetProgramiv(m_prog, GL_LINK_STATUS, &status);
|
||||||
|
if (status != GL_TRUE)
|
||||||
|
{
|
||||||
|
GLint logLen;
|
||||||
|
glGetProgramiv(m_prog, GL_INFO_LOG_LENGTH, &logLen);
|
||||||
|
char* log = (char*)malloc(logLen);
|
||||||
|
glGetProgramInfoLog(m_prog, logLen, nullptr, log);
|
||||||
|
Log.report(logvisor::Error, "unable to link shader program\n%s\n", log);
|
||||||
|
free(log);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
glUseProgram(m_prog);
|
||||||
|
|
||||||
|
if (m_blockNames.size())
|
||||||
|
{
|
||||||
|
m_uniLocs.reserve(m_blockNames.size());
|
||||||
|
for (size_t i=0 ; i<m_blockNames.size() ; ++i)
|
||||||
|
{
|
||||||
|
GLint uniLoc = glGetUniformBlockIndex(m_prog, m_blockNames[i].c_str());
|
||||||
|
//if (uniLoc < 0)
|
||||||
|
// Log.report(logvisor::Warning, "unable to find uniform block '%s'", uniformBlockNames[i]);
|
||||||
|
m_uniLocs.push_back(uniLoc);
|
||||||
|
}
|
||||||
|
m_blockNames = std::vector<std::string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_texNames.size())
|
||||||
|
{
|
||||||
|
for (int i=0 ; i<m_texNames.size() ; ++i)
|
||||||
|
{
|
||||||
|
GLint texLoc = glGetUniformLocation(m_prog, m_texNames[i].c_str());
|
||||||
|
if (texLoc < 0)
|
||||||
|
{ /* Log.report(logvisor::Warning, "unable to find sampler variable '%s'", texNames[i]); */ }
|
||||||
|
else
|
||||||
|
glUniform1i(texLoc, i);
|
||||||
|
}
|
||||||
|
m_texNames = std::vector<std::string>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glUseProgram(m_prog);
|
||||||
|
}
|
||||||
|
|
||||||
if (m_dfactor != GL_ZERO)
|
if (m_dfactor != GL_ZERO)
|
||||||
{
|
{
|
||||||
|
@ -654,54 +723,13 @@ IShaderPipeline* GLDataFactory::Context::newShaderPipeline
|
||||||
shader.m_frag = it->second->lock();
|
shader.m_frag = it->second->lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
shader.m_prog = glCreateProgram();
|
shader.m_texNames.reserve(texCount);
|
||||||
if (!shader.m_prog)
|
for (int i=0 ; i<texCount ; ++i)
|
||||||
{
|
shader.m_texNames.emplace_back(texNames[i]);
|
||||||
Log.report(logvisor::Error, "unable to create shader program");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
glAttachShader(shader.m_prog, shader.m_vert.get().m_shader);
|
shader.m_blockNames.reserve(uniformBlockCount);
|
||||||
glAttachShader(shader.m_prog, shader.m_frag.get().m_shader);
|
for (int i=0 ; i<uniformBlockCount ; ++i)
|
||||||
|
shader.m_blockNames.emplace_back(uniformBlockNames[i]);
|
||||||
glLinkProgram(shader.m_prog);
|
|
||||||
glGetProgramiv(shader.m_prog, GL_LINK_STATUS, &status);
|
|
||||||
if (status != GL_TRUE)
|
|
||||||
{
|
|
||||||
GLint logLen;
|
|
||||||
glGetProgramiv(shader.m_prog, GL_INFO_LOG_LENGTH, &logLen);
|
|
||||||
char* log = (char*)malloc(logLen);
|
|
||||||
glGetProgramInfoLog(shader.m_prog, logLen, nullptr, log);
|
|
||||||
Log.report(logvisor::Error, "unable to link shader program\n%s\n", log);
|
|
||||||
free(log);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
glUseProgram(shader.m_prog);
|
|
||||||
|
|
||||||
if (uniformBlockCount)
|
|
||||||
{
|
|
||||||
shader.m_uniLocs.reserve(uniformBlockCount);
|
|
||||||
for (size_t i=0 ; i<uniformBlockCount ; ++i)
|
|
||||||
{
|
|
||||||
GLint uniLoc = glGetUniformBlockIndex(shader.m_prog, uniformBlockNames[i]);
|
|
||||||
//if (uniLoc < 0)
|
|
||||||
// Log.report(logvisor::Warning, "unable to find uniform block '%s'", uniformBlockNames[i]);
|
|
||||||
shader.m_uniLocs.push_back(uniLoc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (texCount && texNames)
|
|
||||||
{
|
|
||||||
for (int i=0 ; i<texCount ; ++i)
|
|
||||||
{
|
|
||||||
GLint texLoc = glGetUniformLocation(shader.m_prog, texNames[i]);
|
|
||||||
if (texLoc < 0)
|
|
||||||
{ /* Log.report(logvisor::Warning, "unable to find sampler variable '%s'", texNames[i]); */ }
|
|
||||||
else
|
|
||||||
glUniform1i(texLoc, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (srcFac == BlendFactor::Subtract || dstFac == BlendFactor::Subtract)
|
if (srcFac == BlendFactor::Subtract || dstFac == BlendFactor::Subtract)
|
||||||
{
|
{
|
||||||
|
@ -926,8 +954,9 @@ void GLDataFactoryImpl::destroyData(IGraphicsData* d)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lk(m_committedMutex);
|
std::unique_lock<std::mutex> lk(m_committedMutex);
|
||||||
GLData* data = static_cast<GLData*>(d);
|
GLData* data = static_cast<GLData*>(d);
|
||||||
m_committedData.erase(data);
|
data->m_deadCounter = 3;
|
||||||
data->decrement();
|
//m_committedData.erase(data);
|
||||||
|
//data->decrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLDataFactoryImpl::destroyAllData()
|
void GLDataFactoryImpl::destroyAllData()
|
||||||
|
@ -945,8 +974,9 @@ void GLDataFactoryImpl::destroyPool(IGraphicsBufferPool* p)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lk(m_committedMutex);
|
std::unique_lock<std::mutex> lk(m_committedMutex);
|
||||||
GLPool* pool = static_cast<GLPool*>(p);
|
GLPool* pool = static_cast<GLPool*>(p);
|
||||||
m_committedPools.erase(pool);
|
pool->m_deadCounter = 3;
|
||||||
delete pool;
|
//m_committedPools.erase(pool);
|
||||||
|
//delete pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
IGraphicsBufferD* GLDataFactoryImpl::newPoolBuffer(IGraphicsBufferPool* p, BufferUse use,
|
IGraphicsBufferD* GLDataFactoryImpl::newPoolBuffer(IGraphicsBufferPool* p, BufferUse use,
|
||||||
|
@ -1094,9 +1124,9 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||||
std::vector<std::function<void(void)>> m_pendingPosts1;
|
std::vector<std::function<void(void)>> m_pendingPosts1;
|
||||||
std::vector<std::function<void(void)>> m_pendingPosts2;
|
std::vector<std::function<void(void)>> m_pendingPosts2;
|
||||||
std::vector<GLVertexFormat*> m_pendingFmtAdds;
|
std::vector<GLVertexFormat*> m_pendingFmtAdds;
|
||||||
std::vector<std::array<GLuint, 3>> m_pendingFmtDels;
|
//std::vector<std::array<GLuint, 3>> m_pendingFmtDels;
|
||||||
std::vector<GLTextureR*> m_pendingFboAdds;
|
std::vector<GLTextureR*> m_pendingFboAdds;
|
||||||
std::vector<GLuint> m_pendingFboDels;
|
//std::vector<GLuint> m_pendingFboDels;
|
||||||
|
|
||||||
static void ConfigureVertexFormat(GLVertexFormat* fmt)
|
static void ConfigureVertexFormat(GLVertexFormat* fmt)
|
||||||
{
|
{
|
||||||
|
@ -1213,6 +1243,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||||
self->m_pendingFmtAdds.clear();
|
self->m_pendingFmtAdds.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (self->m_pendingFmtDels.size())
|
if (self->m_pendingFmtDels.size())
|
||||||
{
|
{
|
||||||
for (const auto& fmt : self->m_pendingFmtDels)
|
for (const auto& fmt : self->m_pendingFmtDels)
|
||||||
|
@ -1226,12 +1257,14 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||||
glDeleteFramebuffers(1, &fbo);
|
glDeleteFramebuffers(1, &fbo);
|
||||||
self->m_pendingFboDels.clear();
|
self->m_pendingFboDels.clear();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (self->m_pendingPosts2.size())
|
if (self->m_pendingPosts2.size())
|
||||||
posts.swap(self->m_pendingPosts2);
|
posts.swap(self->m_pendingPosts2);
|
||||||
}
|
}
|
||||||
std::vector<Command>& cmds = self->m_cmdBufs[self->m_drawBuf];
|
std::vector<Command>& cmds = self->m_cmdBufs[self->m_drawBuf];
|
||||||
GLenum currentPrim = GL_TRIANGLES;
|
GLenum currentPrim = GL_TRIANGLES;
|
||||||
|
const GLShaderDataBinding* curBinding = nullptr;
|
||||||
for (const Command& cmd : cmds)
|
for (const Command& cmd : cmds)
|
||||||
{
|
{
|
||||||
switch (cmd.m_op)
|
switch (cmd.m_op)
|
||||||
|
@ -1240,6 +1273,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||||
{
|
{
|
||||||
const GLShaderDataBinding* binding = static_cast<const GLShaderDataBinding*>(cmd.binding);
|
const GLShaderDataBinding* binding = static_cast<const GLShaderDataBinding*>(cmd.binding);
|
||||||
binding->bind(self->m_drawBuf);
|
binding->bind(self->m_drawBuf);
|
||||||
|
curBinding = binding;
|
||||||
currentPrim = binding->m_pipeline->m_drawPrim;
|
currentPrim = binding->m_pipeline->m_drawPrim;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1332,6 +1366,31 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||||
cmds.clear();
|
cmds.clear();
|
||||||
for (auto& p : posts)
|
for (auto& p : posts)
|
||||||
p();
|
p();
|
||||||
|
|
||||||
|
GLDataFactoryImpl* gfxF = static_cast<GLDataFactoryImpl*>(self->m_parent->getDataFactory());
|
||||||
|
std::unique_lock<std::mutex> datalk(gfxF->m_committedMutex);
|
||||||
|
for (auto it = gfxF->m_committedData.begin() ; it != gfxF->m_committedData.end() ;)
|
||||||
|
{
|
||||||
|
GLData* d = *it;
|
||||||
|
if (d->m_deadCounter && --d->m_deadCounter == 0)
|
||||||
|
{
|
||||||
|
d->decrement();
|
||||||
|
it = gfxF->m_committedData.erase(it);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
for (auto it = gfxF->m_committedPools.begin() ; it != gfxF->m_committedPools.end() ;)
|
||||||
|
{
|
||||||
|
GLPool* p = *it;
|
||||||
|
if (p->m_deadCounter && --p->m_deadCounter == 0)
|
||||||
|
{
|
||||||
|
delete p;
|
||||||
|
it = gfxF->m_committedPools.erase(it);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1496,6 +1555,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||||
|
|
||||||
void delVertexFormat(GLVertexFormat* fmt)
|
void delVertexFormat(GLVertexFormat* fmt)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
std::unique_lock<std::mutex> lk(m_mt);
|
std::unique_lock<std::mutex> lk(m_mt);
|
||||||
bool foundAdd = false;
|
bool foundAdd = false;
|
||||||
for (GLVertexFormat*& afmt : m_pendingFmtAdds)
|
for (GLVertexFormat*& afmt : m_pendingFmtAdds)
|
||||||
|
@ -1507,6 +1567,8 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||||
}
|
}
|
||||||
if (!foundAdd)
|
if (!foundAdd)
|
||||||
m_pendingFmtDels.push_back({fmt->m_vao[0], fmt->m_vao[1], fmt->m_vao[2]});
|
m_pendingFmtDels.push_back({fmt->m_vao[0], fmt->m_vao[1], fmt->m_vao[2]});
|
||||||
|
#endif
|
||||||
|
glDeleteVertexArrays(3, fmt->m_vao);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addFBO(GLTextureR* tex)
|
void addFBO(GLTextureR* tex)
|
||||||
|
@ -1517,8 +1579,11 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||||
|
|
||||||
void delFBO(GLTextureR* tex)
|
void delFBO(GLTextureR* tex)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
std::unique_lock<std::mutex> lk(m_mt);
|
std::unique_lock<std::mutex> lk(m_mt);
|
||||||
m_pendingFboDels.push_back(tex->m_fbo);
|
m_pendingFboDels.push_back(tex->m_fbo);
|
||||||
|
#endif
|
||||||
|
glDeleteFramebuffers(1, &tex->m_fbo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void execute()
|
void execute()
|
||||||
|
|
|
@ -26,11 +26,10 @@ class VulkanDataFactoryImpl;
|
||||||
struct VulkanShareableShader : IShareableShader<VulkanDataFactoryImpl, VulkanShareableShader>
|
struct VulkanShareableShader : IShareableShader<VulkanDataFactoryImpl, VulkanShareableShader>
|
||||||
{
|
{
|
||||||
VkDevice m_dev;
|
VkDevice m_dev;
|
||||||
VkShaderModule m_shader;
|
std::vector<unsigned int> m_shader;
|
||||||
VulkanShareableShader(VulkanDataFactoryImpl& fac, uint64_t srcKey, uint64_t binKey,
|
VulkanShareableShader(VulkanDataFactoryImpl& fac, uint64_t srcKey, uint64_t binKey,
|
||||||
VkDevice dev, VkShaderModule s)
|
VkDevice dev, const std::vector<unsigned int>& s)
|
||||||
: IShareableShader(fac, srcKey, binKey), m_dev(dev), m_shader(s) {}
|
: IShareableShader(fac, srcKey, binKey), m_dev(dev), m_shader(s) {}
|
||||||
~VulkanShareableShader() { vk::DestroyShaderModule(m_dev, m_shader, nullptr); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class VulkanDataFactoryImpl : public VulkanDataFactory
|
class VulkanDataFactoryImpl : public VulkanDataFactory
|
||||||
|
@ -338,8 +337,8 @@ void VulkanContext::initVulkan(const char* appName)
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
m_layerNames.push_back("VK_LAYER_LUNARG_core_validation");
|
m_layerNames.push_back("VK_LAYER_LUNARG_core_validation");
|
||||||
m_layerNames.push_back("VK_LAYER_LUNARG_object_tracker");
|
m_layerNames.push_back("VK_LAYER_LUNARG_object_tracker");
|
||||||
m_layerNames.push_back("VK_LAYER_LUNARG_parameter_validation");
|
//m_layerNames.push_back("VK_LAYER_LUNARG_parameter_validation");
|
||||||
m_layerNames.push_back("VK_LAYER_GOOGLE_threading");
|
//m_layerNames.push_back("VK_LAYER_GOOGLE_threading");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
demo_check_layers(m_instanceLayerProperties, m_layerNames);
|
demo_check_layers(m_instanceLayerProperties, m_layerNames);
|
||||||
|
@ -753,7 +752,7 @@ struct VulkanData : IGraphicsDataPriv
|
||||||
std::vector<std::unique_ptr<class VulkanTextureD>> m_DTexs;
|
std::vector<std::unique_ptr<class VulkanTextureD>> m_DTexs;
|
||||||
std::vector<std::unique_ptr<class VulkanTextureR>> m_RTexs;
|
std::vector<std::unique_ptr<class VulkanTextureR>> m_RTexs;
|
||||||
std::vector<std::unique_ptr<struct VulkanVertexFormat>> m_VFmts;
|
std::vector<std::unique_ptr<struct VulkanVertexFormat>> m_VFmts;
|
||||||
bool m_dead = false;
|
int m_deadCounter = 0;
|
||||||
VulkanData(VulkanContext* ctx) : m_ctx(ctx) {}
|
VulkanData(VulkanContext* ctx) : m_ctx(ctx) {}
|
||||||
~VulkanData()
|
~VulkanData()
|
||||||
{
|
{
|
||||||
|
@ -769,7 +768,7 @@ struct VulkanPoolItem : IGraphicsDataPriv
|
||||||
VulkanContext* m_ctx;
|
VulkanContext* m_ctx;
|
||||||
VkDeviceMemory m_bufMem = VK_NULL_HANDLE;
|
VkDeviceMemory m_bufMem = VK_NULL_HANDLE;
|
||||||
std::unique_ptr<class VulkanGraphicsBufferD> m_buf;
|
std::unique_ptr<class VulkanGraphicsBufferD> m_buf;
|
||||||
bool m_dead = false;
|
int m_deadCounter = 0;
|
||||||
VulkanPoolItem(VulkanContext* ctx) : m_ctx(ctx) {}
|
VulkanPoolItem(VulkanContext* ctx) : m_ctx(ctx) {}
|
||||||
~VulkanPoolItem()
|
~VulkanPoolItem()
|
||||||
{
|
{
|
||||||
|
@ -781,7 +780,7 @@ struct VulkanPoolItem : IGraphicsDataPriv
|
||||||
struct VulkanPool : IGraphicsBufferPool
|
struct VulkanPool : IGraphicsBufferPool
|
||||||
{
|
{
|
||||||
std::unordered_set<VulkanPoolItem*> m_items;
|
std::unordered_set<VulkanPoolItem*> m_items;
|
||||||
bool m_dead = false;
|
int m_deadCounter = 0;
|
||||||
~VulkanPool()
|
~VulkanPool()
|
||||||
{
|
{
|
||||||
for (auto& item : m_items)
|
for (auto& item : m_items)
|
||||||
|
@ -792,7 +791,7 @@ struct VulkanPool : IGraphicsBufferPool
|
||||||
{
|
{
|
||||||
for (auto it = m_items.begin() ; it != m_items.end() ;)
|
for (auto it = m_items.begin() ; it != m_items.end() ;)
|
||||||
{
|
{
|
||||||
if ((*it)->m_dead)
|
if ((*it)->m_deadCounter && --(*it)->m_deadCounter == 0)
|
||||||
{
|
{
|
||||||
(*it)->decrement();
|
(*it)->decrement();
|
||||||
it = m_items.erase(it);
|
it = m_items.erase(it);
|
||||||
|
@ -1881,8 +1880,18 @@ class VulkanShaderPipeline : public IShaderPipeline
|
||||||
VulkanContext* m_ctx;
|
VulkanContext* m_ctx;
|
||||||
VkPipelineCache m_pipelineCache;
|
VkPipelineCache m_pipelineCache;
|
||||||
const VulkanVertexFormat* m_vtxFmt;
|
const VulkanVertexFormat* m_vtxFmt;
|
||||||
VulkanShareableShader::Token m_vert;
|
mutable VulkanShareableShader::Token m_vert;
|
||||||
VulkanShareableShader::Token m_frag;
|
mutable VulkanShareableShader::Token m_frag;
|
||||||
|
BlendFactor m_srcFac;
|
||||||
|
BlendFactor m_dstFac;
|
||||||
|
Primitive m_prim;
|
||||||
|
ZTest m_depthTest;
|
||||||
|
bool m_depthWrite;
|
||||||
|
bool m_colorWrite;
|
||||||
|
bool m_alphaWrite;
|
||||||
|
CullMode m_culling;
|
||||||
|
mutable VkPipeline m_pipeline = VK_NULL_HANDLE;
|
||||||
|
|
||||||
VulkanShaderPipeline(IGraphicsData* parent,
|
VulkanShaderPipeline(IGraphicsData* parent,
|
||||||
VulkanContext* ctx,
|
VulkanContext* ctx,
|
||||||
VulkanShareableShader::Token&& vert,
|
VulkanShareableShader::Token&& vert,
|
||||||
|
@ -1893,171 +1902,197 @@ class VulkanShaderPipeline : public IShaderPipeline
|
||||||
ZTest depthTest, bool depthWrite, bool colorWrite,
|
ZTest depthTest, bool depthWrite, bool colorWrite,
|
||||||
bool alphaWrite, CullMode culling)
|
bool alphaWrite, CullMode culling)
|
||||||
: IShaderPipeline(parent), m_ctx(ctx), m_pipelineCache(pipelineCache), m_vtxFmt(vtxFmt),
|
: IShaderPipeline(parent), 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)), m_srcFac(srcFac), m_dstFac(dstFac),
|
||||||
{
|
m_prim(prim), m_depthTest(depthTest), m_depthWrite(depthWrite), m_colorWrite(colorWrite),
|
||||||
VkCullModeFlagBits cullMode;
|
m_alphaWrite(alphaWrite), m_culling(culling)
|
||||||
switch (culling)
|
{}
|
||||||
{
|
|
||||||
case CullMode::None:
|
|
||||||
default:
|
|
||||||
cullMode = VK_CULL_MODE_NONE;
|
|
||||||
break;
|
|
||||||
case CullMode::Backface:
|
|
||||||
cullMode = VK_CULL_MODE_BACK_BIT;
|
|
||||||
break;
|
|
||||||
case CullMode::Frontface:
|
|
||||||
cullMode = VK_CULL_MODE_FRONT_BIT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkDynamicState dynamicStateEnables[VK_DYNAMIC_STATE_RANGE_SIZE] = {};
|
|
||||||
VkPipelineDynamicStateCreateInfo dynamicState = {};
|
|
||||||
dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
|
|
||||||
dynamicState.pNext = nullptr;
|
|
||||||
dynamicState.pDynamicStates = dynamicStateEnables;
|
|
||||||
dynamicState.dynamicStateCount = 0;
|
|
||||||
|
|
||||||
VkPipelineShaderStageCreateInfo stages[2] = {};
|
|
||||||
|
|
||||||
stages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
|
||||||
stages[0].pNext = nullptr;
|
|
||||||
stages[0].flags = 0;
|
|
||||||
stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
|
|
||||||
stages[0].module = m_vert.get().m_shader;
|
|
||||||
stages[0].pName = "main";
|
|
||||||
stages[0].pSpecializationInfo = nullptr;
|
|
||||||
|
|
||||||
stages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
|
||||||
stages[1].pNext = nullptr;
|
|
||||||
stages[1].flags = 0;
|
|
||||||
stages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
|
||||||
stages[1].module = m_frag.get().m_shader;
|
|
||||||
stages[1].pName = "main";
|
|
||||||
stages[1].pSpecializationInfo = nullptr;
|
|
||||||
|
|
||||||
VkPipelineInputAssemblyStateCreateInfo assemblyInfo = {};
|
|
||||||
assemblyInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
|
||||||
assemblyInfo.pNext = nullptr;
|
|
||||||
assemblyInfo.flags = 0;
|
|
||||||
assemblyInfo.topology = PRIMITIVE_TABLE[int(prim)];
|
|
||||||
assemblyInfo.primitiveRestartEnable = VK_FALSE;
|
|
||||||
|
|
||||||
VkPipelineViewportStateCreateInfo viewportInfo = {};
|
|
||||||
viewportInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
|
||||||
viewportInfo.pNext = nullptr;
|
|
||||||
viewportInfo.flags = 0;
|
|
||||||
viewportInfo.viewportCount = 1;
|
|
||||||
viewportInfo.pViewports = nullptr;
|
|
||||||
viewportInfo.scissorCount = 1;
|
|
||||||
viewportInfo.pScissors = nullptr;
|
|
||||||
dynamicStateEnables[dynamicState.dynamicStateCount++] = VK_DYNAMIC_STATE_VIEWPORT;
|
|
||||||
dynamicStateEnables[dynamicState.dynamicStateCount++] = VK_DYNAMIC_STATE_SCISSOR;
|
|
||||||
|
|
||||||
VkPipelineRasterizationStateCreateInfo rasterizationInfo = {};
|
|
||||||
rasterizationInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
|
||||||
rasterizationInfo.pNext = nullptr;
|
|
||||||
rasterizationInfo.flags = 0;
|
|
||||||
rasterizationInfo.depthClampEnable = VK_FALSE;
|
|
||||||
rasterizationInfo.rasterizerDiscardEnable = VK_FALSE;
|
|
||||||
rasterizationInfo.polygonMode = VK_POLYGON_MODE_FILL;
|
|
||||||
rasterizationInfo.cullMode = cullMode;
|
|
||||||
rasterizationInfo.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
|
|
||||||
rasterizationInfo.depthBiasEnable = VK_FALSE;
|
|
||||||
rasterizationInfo.lineWidth = 1.f;
|
|
||||||
|
|
||||||
VkPipelineMultisampleStateCreateInfo multisampleInfo = {};
|
|
||||||
multisampleInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
|
||||||
multisampleInfo.pNext = nullptr;
|
|
||||||
multisampleInfo.flags = 0;
|
|
||||||
multisampleInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
|
||||||
|
|
||||||
VkPipelineDepthStencilStateCreateInfo depthStencilInfo = {};
|
|
||||||
depthStencilInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
|
||||||
depthStencilInfo.pNext = nullptr;
|
|
||||||
depthStencilInfo.flags = 0;
|
|
||||||
depthStencilInfo.depthTestEnable = depthTest != ZTest::None;
|
|
||||||
depthStencilInfo.depthWriteEnable = depthWrite;
|
|
||||||
depthStencilInfo.front.compareOp = VK_COMPARE_OP_ALWAYS;
|
|
||||||
depthStencilInfo.back.compareOp = VK_COMPARE_OP_ALWAYS;
|
|
||||||
|
|
||||||
switch (depthTest)
|
|
||||||
{
|
|
||||||
case ZTest::None:
|
|
||||||
default:
|
|
||||||
depthStencilInfo.depthCompareOp = VK_COMPARE_OP_ALWAYS;
|
|
||||||
break;
|
|
||||||
case ZTest::LEqual:
|
|
||||||
depthStencilInfo.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
|
|
||||||
break;
|
|
||||||
case ZTest::Greater:
|
|
||||||
depthStencilInfo.depthCompareOp = VK_COMPARE_OP_GREATER;
|
|
||||||
break;
|
|
||||||
case ZTest::Equal:
|
|
||||||
depthStencilInfo.depthCompareOp = VK_COMPARE_OP_EQUAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkPipelineColorBlendAttachmentState colorAttachment = {};
|
|
||||||
colorAttachment.blendEnable = dstFac != BlendFactor::Zero;
|
|
||||||
if (srcFac == BlendFactor::Subtract || dstFac == BlendFactor::Subtract)
|
|
||||||
{
|
|
||||||
colorAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_DST_COLOR;
|
|
||||||
colorAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_SRC_COLOR;
|
|
||||||
colorAttachment.colorBlendOp = VK_BLEND_OP_SUBTRACT;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
colorAttachment.srcColorBlendFactor = BLEND_FACTOR_TABLE[int(srcFac)];
|
|
||||||
colorAttachment.dstColorBlendFactor = BLEND_FACTOR_TABLE[int(dstFac)];
|
|
||||||
colorAttachment.colorBlendOp = VK_BLEND_OP_ADD;
|
|
||||||
}
|
|
||||||
colorAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
|
|
||||||
colorAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
|
|
||||||
colorAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
|
|
||||||
colorAttachment.colorWriteMask =
|
|
||||||
(colorWrite ? (VK_COLOR_COMPONENT_R_BIT |
|
|
||||||
VK_COLOR_COMPONENT_G_BIT |
|
|
||||||
VK_COLOR_COMPONENT_B_BIT) : 0) |
|
|
||||||
(alphaWrite ? VK_COLOR_COMPONENT_A_BIT : 0);
|
|
||||||
|
|
||||||
VkPipelineColorBlendStateCreateInfo colorBlendInfo = {};
|
|
||||||
colorBlendInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
|
||||||
colorBlendInfo.pNext = nullptr;
|
|
||||||
colorBlendInfo.flags = 0;
|
|
||||||
colorBlendInfo.logicOpEnable = VK_FALSE;
|
|
||||||
colorBlendInfo.attachmentCount = 1;
|
|
||||||
colorBlendInfo.pAttachments = &colorAttachment;
|
|
||||||
|
|
||||||
VkGraphicsPipelineCreateInfo pipelineCreateInfo = {};
|
|
||||||
pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
|
||||||
pipelineCreateInfo.pNext = nullptr;
|
|
||||||
pipelineCreateInfo.flags = 0;
|
|
||||||
pipelineCreateInfo.stageCount = 2;
|
|
||||||
pipelineCreateInfo.pStages = stages;
|
|
||||||
pipelineCreateInfo.pVertexInputState = &vtxFmt->m_info;
|
|
||||||
pipelineCreateInfo.pInputAssemblyState = &assemblyInfo;
|
|
||||||
pipelineCreateInfo.pViewportState = &viewportInfo;
|
|
||||||
pipelineCreateInfo.pRasterizationState = &rasterizationInfo;
|
|
||||||
pipelineCreateInfo.pMultisampleState = &multisampleInfo;
|
|
||||||
pipelineCreateInfo.pDepthStencilState = &depthStencilInfo;
|
|
||||||
pipelineCreateInfo.pColorBlendState = &colorBlendInfo;
|
|
||||||
pipelineCreateInfo.pDynamicState = &dynamicState;
|
|
||||||
pipelineCreateInfo.layout = ctx->m_pipelinelayout;
|
|
||||||
pipelineCreateInfo.renderPass = ctx->m_pass;
|
|
||||||
|
|
||||||
ThrowIfFailed(vk::CreateGraphicsPipelines(ctx->m_dev, pipelineCache, 1, &pipelineCreateInfo,
|
|
||||||
nullptr, &m_pipeline));
|
|
||||||
}
|
|
||||||
public:
|
public:
|
||||||
VkPipeline m_pipeline;
|
|
||||||
~VulkanShaderPipeline()
|
~VulkanShaderPipeline()
|
||||||
{
|
{
|
||||||
vk::DestroyPipeline(m_ctx->m_dev, m_pipeline, nullptr);
|
if (m_pipeline)
|
||||||
|
vk::DestroyPipeline(m_ctx->m_dev, m_pipeline, nullptr);
|
||||||
if (m_pipelineCache)
|
if (m_pipelineCache)
|
||||||
vk::DestroyPipelineCache(m_ctx->m_dev, m_pipelineCache, nullptr);
|
vk::DestroyPipelineCache(m_ctx->m_dev, m_pipelineCache, nullptr);
|
||||||
}
|
}
|
||||||
VulkanShaderPipeline& operator=(const VulkanShaderPipeline&) = delete;
|
VulkanShaderPipeline& operator=(const VulkanShaderPipeline&) = delete;
|
||||||
VulkanShaderPipeline(const VulkanShaderPipeline&) = delete;
|
VulkanShaderPipeline(const VulkanShaderPipeline&) = delete;
|
||||||
|
VkPipeline bind() const
|
||||||
|
{
|
||||||
|
if (!m_pipeline)
|
||||||
|
{
|
||||||
|
VkCullModeFlagBits cullMode;
|
||||||
|
switch (m_culling)
|
||||||
|
{
|
||||||
|
case CullMode::None:
|
||||||
|
default:
|
||||||
|
cullMode = VK_CULL_MODE_NONE;
|
||||||
|
break;
|
||||||
|
case CullMode::Backface:
|
||||||
|
cullMode = VK_CULL_MODE_BACK_BIT;
|
||||||
|
break;
|
||||||
|
case CullMode::Frontface:
|
||||||
|
cullMode = VK_CULL_MODE_FRONT_BIT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkDynamicState dynamicStateEnables[VK_DYNAMIC_STATE_RANGE_SIZE] = {};
|
||||||
|
VkPipelineDynamicStateCreateInfo dynamicState = {};
|
||||||
|
dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
|
||||||
|
dynamicState.pNext = nullptr;
|
||||||
|
dynamicState.pDynamicStates = dynamicStateEnables;
|
||||||
|
dynamicState.dynamicStateCount = 0;
|
||||||
|
|
||||||
|
VkPipelineShaderStageCreateInfo stages[2] = {};
|
||||||
|
|
||||||
|
VkShaderModuleCreateInfo smCreateInfo = {};
|
||||||
|
smCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||||
|
VkShaderModule vertModule, fragModule;
|
||||||
|
const auto& vertShader = m_vert.get().m_shader;
|
||||||
|
smCreateInfo.codeSize = vertShader.size() * sizeof(unsigned int);
|
||||||
|
smCreateInfo.pCode = vertShader.data();
|
||||||
|
ThrowIfFailed(vk::CreateShaderModule(m_ctx->m_dev, &smCreateInfo, nullptr, &vertModule));
|
||||||
|
const auto& fragShader = m_frag.get().m_shader;
|
||||||
|
smCreateInfo.codeSize = fragShader.size() * sizeof(unsigned int);
|
||||||
|
smCreateInfo.pCode = fragShader.data();
|
||||||
|
ThrowIfFailed(vk::CreateShaderModule(m_ctx->m_dev, &smCreateInfo, nullptr, &fragModule));
|
||||||
|
|
||||||
|
stages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||||
|
stages[0].pNext = nullptr;
|
||||||
|
stages[0].flags = 0;
|
||||||
|
stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
|
||||||
|
stages[0].module = vertModule;
|
||||||
|
stages[0].pName = "main";
|
||||||
|
stages[0].pSpecializationInfo = nullptr;
|
||||||
|
|
||||||
|
stages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||||
|
stages[1].pNext = nullptr;
|
||||||
|
stages[1].flags = 0;
|
||||||
|
stages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||||
|
stages[1].module = fragModule;
|
||||||
|
stages[1].pName = "main";
|
||||||
|
stages[1].pSpecializationInfo = nullptr;
|
||||||
|
|
||||||
|
VkPipelineInputAssemblyStateCreateInfo assemblyInfo = {};
|
||||||
|
assemblyInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
||||||
|
assemblyInfo.pNext = nullptr;
|
||||||
|
assemblyInfo.flags = 0;
|
||||||
|
assemblyInfo.topology = PRIMITIVE_TABLE[int(m_prim)];
|
||||||
|
assemblyInfo.primitiveRestartEnable = VK_FALSE;
|
||||||
|
|
||||||
|
VkPipelineViewportStateCreateInfo viewportInfo = {};
|
||||||
|
viewportInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
||||||
|
viewportInfo.pNext = nullptr;
|
||||||
|
viewportInfo.flags = 0;
|
||||||
|
viewportInfo.viewportCount = 1;
|
||||||
|
viewportInfo.pViewports = nullptr;
|
||||||
|
viewportInfo.scissorCount = 1;
|
||||||
|
viewportInfo.pScissors = nullptr;
|
||||||
|
dynamicStateEnables[dynamicState.dynamicStateCount++] = VK_DYNAMIC_STATE_VIEWPORT;
|
||||||
|
dynamicStateEnables[dynamicState.dynamicStateCount++] = VK_DYNAMIC_STATE_SCISSOR;
|
||||||
|
|
||||||
|
VkPipelineRasterizationStateCreateInfo rasterizationInfo = {};
|
||||||
|
rasterizationInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
||||||
|
rasterizationInfo.pNext = nullptr;
|
||||||
|
rasterizationInfo.flags = 0;
|
||||||
|
rasterizationInfo.depthClampEnable = VK_FALSE;
|
||||||
|
rasterizationInfo.rasterizerDiscardEnable = VK_FALSE;
|
||||||
|
rasterizationInfo.polygonMode = VK_POLYGON_MODE_FILL;
|
||||||
|
rasterizationInfo.cullMode = cullMode;
|
||||||
|
rasterizationInfo.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
|
||||||
|
rasterizationInfo.depthBiasEnable = VK_FALSE;
|
||||||
|
rasterizationInfo.lineWidth = 1.f;
|
||||||
|
|
||||||
|
VkPipelineMultisampleStateCreateInfo multisampleInfo = {};
|
||||||
|
multisampleInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
||||||
|
multisampleInfo.pNext = nullptr;
|
||||||
|
multisampleInfo.flags = 0;
|
||||||
|
multisampleInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
|
||||||
|
VkPipelineDepthStencilStateCreateInfo depthStencilInfo = {};
|
||||||
|
depthStencilInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
||||||
|
depthStencilInfo.pNext = nullptr;
|
||||||
|
depthStencilInfo.flags = 0;
|
||||||
|
depthStencilInfo.depthTestEnable = m_depthTest != ZTest::None;
|
||||||
|
depthStencilInfo.depthWriteEnable = m_depthWrite;
|
||||||
|
depthStencilInfo.front.compareOp = VK_COMPARE_OP_ALWAYS;
|
||||||
|
depthStencilInfo.back.compareOp = VK_COMPARE_OP_ALWAYS;
|
||||||
|
|
||||||
|
switch (m_depthTest)
|
||||||
|
{
|
||||||
|
case ZTest::None:
|
||||||
|
default:
|
||||||
|
depthStencilInfo.depthCompareOp = VK_COMPARE_OP_ALWAYS;
|
||||||
|
break;
|
||||||
|
case ZTest::LEqual:
|
||||||
|
depthStencilInfo.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
|
||||||
|
break;
|
||||||
|
case ZTest::Greater:
|
||||||
|
depthStencilInfo.depthCompareOp = VK_COMPARE_OP_GREATER;
|
||||||
|
break;
|
||||||
|
case ZTest::Equal:
|
||||||
|
depthStencilInfo.depthCompareOp = VK_COMPARE_OP_EQUAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkPipelineColorBlendAttachmentState colorAttachment = {};
|
||||||
|
colorAttachment.blendEnable = m_dstFac != BlendFactor::Zero;
|
||||||
|
if (m_srcFac == BlendFactor::Subtract || m_dstFac == BlendFactor::Subtract)
|
||||||
|
{
|
||||||
|
colorAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_DST_COLOR;
|
||||||
|
colorAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_SRC_COLOR;
|
||||||
|
colorAttachment.colorBlendOp = VK_BLEND_OP_SUBTRACT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
colorAttachment.srcColorBlendFactor = BLEND_FACTOR_TABLE[int(m_srcFac)];
|
||||||
|
colorAttachment.dstColorBlendFactor = BLEND_FACTOR_TABLE[int(m_dstFac)];
|
||||||
|
colorAttachment.colorBlendOp = VK_BLEND_OP_ADD;
|
||||||
|
}
|
||||||
|
colorAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
|
||||||
|
colorAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
|
||||||
|
colorAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
|
||||||
|
colorAttachment.colorWriteMask =
|
||||||
|
(m_colorWrite ? (VK_COLOR_COMPONENT_R_BIT |
|
||||||
|
VK_COLOR_COMPONENT_G_BIT |
|
||||||
|
VK_COLOR_COMPONENT_B_BIT) : 0) |
|
||||||
|
(m_alphaWrite ? VK_COLOR_COMPONENT_A_BIT : 0);
|
||||||
|
|
||||||
|
VkPipelineColorBlendStateCreateInfo colorBlendInfo = {};
|
||||||
|
colorBlendInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
||||||
|
colorBlendInfo.pNext = nullptr;
|
||||||
|
colorBlendInfo.flags = 0;
|
||||||
|
colorBlendInfo.logicOpEnable = VK_FALSE;
|
||||||
|
colorBlendInfo.attachmentCount = 1;
|
||||||
|
colorBlendInfo.pAttachments = &colorAttachment;
|
||||||
|
|
||||||
|
VkGraphicsPipelineCreateInfo pipelineCreateInfo = {};
|
||||||
|
pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||||
|
pipelineCreateInfo.pNext = nullptr;
|
||||||
|
pipelineCreateInfo.flags = 0;
|
||||||
|
pipelineCreateInfo.stageCount = 2;
|
||||||
|
pipelineCreateInfo.pStages = stages;
|
||||||
|
pipelineCreateInfo.pVertexInputState = &m_vtxFmt->m_info;
|
||||||
|
pipelineCreateInfo.pInputAssemblyState = &assemblyInfo;
|
||||||
|
pipelineCreateInfo.pViewportState = &viewportInfo;
|
||||||
|
pipelineCreateInfo.pRasterizationState = &rasterizationInfo;
|
||||||
|
pipelineCreateInfo.pMultisampleState = &multisampleInfo;
|
||||||
|
pipelineCreateInfo.pDepthStencilState = &depthStencilInfo;
|
||||||
|
pipelineCreateInfo.pColorBlendState = &colorBlendInfo;
|
||||||
|
pipelineCreateInfo.pDynamicState = &dynamicState;
|
||||||
|
pipelineCreateInfo.layout = m_ctx->m_pipelinelayout;
|
||||||
|
pipelineCreateInfo.renderPass = m_ctx->m_pass;
|
||||||
|
|
||||||
|
ThrowIfFailed(vk::CreateGraphicsPipelines(m_ctx->m_dev, m_pipelineCache, 1, &pipelineCreateInfo,
|
||||||
|
nullptr, &m_pipeline));
|
||||||
|
|
||||||
|
vk::DestroyShaderModule(m_ctx->m_dev, vertModule, nullptr);
|
||||||
|
vk::DestroyShaderModule(m_ctx->m_dev, fragModule, nullptr);
|
||||||
|
|
||||||
|
m_vert.reset();
|
||||||
|
m_frag.reset();
|
||||||
|
}
|
||||||
|
return m_pipeline;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static VkDeviceSize SizeBufferForGPU(IGraphicsBuffer* buf, VulkanContext* ctx,
|
static VkDeviceSize SizeBufferForGPU(IGraphicsBuffer* buf, VulkanContext* ctx,
|
||||||
|
@ -2156,7 +2191,7 @@ struct VulkanShaderDataBinding : IShaderDataBindingPriv
|
||||||
std::unique_ptr<IGraphicsBuffer*[]> m_ubufs;
|
std::unique_ptr<IGraphicsBuffer*[]> m_ubufs;
|
||||||
std::vector<std::array<VkDescriptorBufferInfo, 2>> m_ubufOffs;
|
std::vector<std::array<VkDescriptorBufferInfo, 2>> m_ubufOffs;
|
||||||
size_t m_texCount;
|
size_t m_texCount;
|
||||||
VkImageView m_knownViewHandles[2][8] = {};
|
VkImageView m_knownViewHandles[2][BOO_GLSL_MAX_TEXTURE_COUNT] = {};
|
||||||
struct BindTex
|
struct BindTex
|
||||||
{
|
{
|
||||||
ITexture* tex;
|
ITexture* tex;
|
||||||
|
@ -2402,7 +2437,7 @@ struct VulkanShaderDataBinding : IShaderDataBindingPriv
|
||||||
if (totalWrites)
|
if (totalWrites)
|
||||||
vk::UpdateDescriptorSets(m_ctx->m_dev, totalWrites, writes, 0, nullptr);
|
vk::UpdateDescriptorSets(m_ctx->m_dev, totalWrites, writes, 0, nullptr);
|
||||||
|
|
||||||
vk::CmdBindPipeline(cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline->m_pipeline);
|
vk::CmdBindPipeline(cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline->bind());
|
||||||
if (m_descSets[b])
|
if (m_descSets[b])
|
||||||
vk::CmdBindDescriptorSets(cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, m_ctx->m_pipelinelayout,
|
vk::CmdBindDescriptorSets(cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, m_ctx->m_pipelinelayout,
|
||||||
0, 1, &m_descSets[b], 0, nullptr);
|
0, 1, &m_descSets[b], 0, nullptr);
|
||||||
|
@ -3023,13 +3058,13 @@ void VulkanTextureD::unmap()
|
||||||
void VulkanDataFactoryImpl::destroyData(IGraphicsData* d)
|
void VulkanDataFactoryImpl::destroyData(IGraphicsData* d)
|
||||||
{
|
{
|
||||||
VulkanData* data = static_cast<VulkanData*>(d);
|
VulkanData* data = static_cast<VulkanData*>(d);
|
||||||
data->m_dead = true;
|
data->m_deadCounter = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanDataFactoryImpl::destroyPool(IGraphicsBufferPool* p)
|
void VulkanDataFactoryImpl::destroyPool(IGraphicsBufferPool* p)
|
||||||
{
|
{
|
||||||
VulkanPool* pool = static_cast<VulkanPool*>(p);
|
VulkanPool* pool = static_cast<VulkanPool*>(p);
|
||||||
pool->m_dead = true;
|
pool->m_deadCounter = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanDataFactoryImpl::destroyAllData()
|
void VulkanDataFactoryImpl::destroyAllData()
|
||||||
|
@ -3255,15 +3290,10 @@ IShaderPipeline* VulkanDataFactory::Context::newShaderPipeline
|
||||||
binHashes[0] = CompileVert(vertBlob, vertSource, srcHashes[0], factory);
|
binHashes[0] = CompileVert(vertBlob, vertSource, srcHashes[0], factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
smCreateInfo.codeSize = useVertBlob->size() * sizeof(unsigned int);
|
|
||||||
smCreateInfo.pCode = useVertBlob->data();
|
|
||||||
VkShaderModule vertModule;
|
|
||||||
ThrowIfFailed(vk::CreateShaderModule(factory.m_ctx->m_dev, &smCreateInfo, nullptr, &vertModule));
|
|
||||||
|
|
||||||
auto it =
|
auto it =
|
||||||
factory.m_sharedShaders.emplace(std::make_pair(binHashes[0],
|
factory.m_sharedShaders.emplace(std::make_pair(binHashes[0],
|
||||||
std::make_unique<VulkanShareableShader>(factory, srcHashes[0], binHashes[0],
|
std::make_unique<VulkanShareableShader>(factory, srcHashes[0], binHashes[0],
|
||||||
factory.m_ctx->m_dev, vertModule))).first;
|
factory.m_ctx->m_dev, *useVertBlob))).first;
|
||||||
vertShader = it->second->lock();
|
vertShader = it->second->lock();
|
||||||
}
|
}
|
||||||
auto fragFind = binHashes[1] ? factory.m_sharedShaders.find(binHashes[1]) :
|
auto fragFind = binHashes[1] ? factory.m_sharedShaders.find(binHashes[1]) :
|
||||||
|
@ -3286,19 +3316,13 @@ IShaderPipeline* VulkanDataFactory::Context::newShaderPipeline
|
||||||
binHashes[1] = CompileFrag(fragBlob, fragSource, srcHashes[1], factory);
|
binHashes[1] = CompileFrag(fragBlob, fragSource, srcHashes[1], factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
smCreateInfo.codeSize = useFragBlob->size() * sizeof(unsigned int);
|
|
||||||
smCreateInfo.pCode = useFragBlob->data();
|
|
||||||
VkShaderModule fragModule;
|
|
||||||
ThrowIfFailed(vk::CreateShaderModule(factory.m_ctx->m_dev, &smCreateInfo, nullptr, &fragModule));
|
|
||||||
|
|
||||||
auto it =
|
auto it =
|
||||||
factory.m_sharedShaders.emplace(std::make_pair(binHashes[1],
|
factory.m_sharedShaders.emplace(std::make_pair(binHashes[1],
|
||||||
std::make_unique<VulkanShareableShader>(factory, srcHashes[1], binHashes[1],
|
std::make_unique<VulkanShareableShader>(factory, srcHashes[1], binHashes[1],
|
||||||
factory.m_ctx->m_dev, fragModule))).first;
|
factory.m_ctx->m_dev, *useFragBlob))).first;
|
||||||
fragShader = it->second->lock();
|
fragShader = it->second->lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VkPipelineCache pipelineCache = VK_NULL_HANDLE;
|
VkPipelineCache pipelineCache = VK_NULL_HANDLE;
|
||||||
if (pipelineBlob)
|
if (pipelineBlob)
|
||||||
{
|
{
|
||||||
|
@ -3590,7 +3614,7 @@ void VulkanDataFactoryImpl::deletePoolBuffer(IGraphicsBufferPool* p, IGraphicsBu
|
||||||
VulkanPool* pool = static_cast<VulkanPool*>(p);
|
VulkanPool* pool = static_cast<VulkanPool*>(p);
|
||||||
auto search = pool->m_items.find(static_cast<VulkanPoolItem*>(buf->m_parentData));
|
auto search = pool->m_items.find(static_cast<VulkanPoolItem*>(buf->m_parentData));
|
||||||
if (search != pool->m_items.end())
|
if (search != pool->m_items.end())
|
||||||
(*search)->m_dead = true;
|
(*search)->m_deadCounter = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
GraphicsBufferPoolToken VulkanDataFactoryImpl::newBufferPool()
|
GraphicsBufferPoolToken VulkanDataFactoryImpl::newBufferPool()
|
||||||
|
@ -3666,9 +3690,10 @@ void VulkanCommandQueue::execute()
|
||||||
datalk.lock();
|
datalk.lock();
|
||||||
for (auto it = gfxF->m_committedData.begin() ; it != gfxF->m_committedData.end() ;)
|
for (auto it = gfxF->m_committedData.begin() ; it != gfxF->m_committedData.end() ;)
|
||||||
{
|
{
|
||||||
if ((*it)->m_dead)
|
VulkanData* data = *it;
|
||||||
|
if (data->m_deadCounter && --data->m_deadCounter == 0)
|
||||||
{
|
{
|
||||||
(*it)->decrement();
|
data->decrement();
|
||||||
it = gfxF->m_committedData.erase(it);
|
it = gfxF->m_committedData.erase(it);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -3676,16 +3701,16 @@ void VulkanCommandQueue::execute()
|
||||||
}
|
}
|
||||||
for (auto it = gfxF->m_committedPools.begin() ; it != gfxF->m_committedPools.end() ;)
|
for (auto it = gfxF->m_committedPools.begin() ; it != gfxF->m_committedPools.end() ;)
|
||||||
{
|
{
|
||||||
if ((*it)->m_dead)
|
VulkanPool* p = *it;
|
||||||
|
if (p->m_deadCounter && --p->m_deadCounter == 0)
|
||||||
{
|
{
|
||||||
VulkanPool* p = *it;
|
|
||||||
it = gfxF->m_committedPools.erase(it);
|
it = gfxF->m_committedPools.erase(it);
|
||||||
delete p;
|
delete p;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
(*it)->clearDeadBuffers();
|
p->clearDeadBuffers();
|
||||||
}
|
}
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <X11/XKBlib.h>
|
#include <X11/XKBlib.h>
|
||||||
#include <X11/extensions/XInput2.h>
|
#include <X11/extensions/XInput2.h>
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
|
#include <X11/extensions/Xrandr.h>
|
||||||
#include "logvisor/logvisor.hpp"
|
#include "logvisor/logvisor.hpp"
|
||||||
|
|
||||||
#include "XlibCommon.hpp"
|
#include "XlibCommon.hpp"
|
||||||
|
@ -282,6 +283,16 @@ static void genFrameDefault(Screen* screen, int& xOut, int& yOut, int& wOut, int
|
||||||
hOut = height;
|
hOut = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void genFrameDefault(XRRMonitorInfo* screen, int& xOut, int& yOut, int& wOut, int& hOut)
|
||||||
|
{
|
||||||
|
float width = screen->width * 2.0 / 3.0;
|
||||||
|
float height = screen->height * 2.0 / 3.0;
|
||||||
|
xOut = (screen->width - width) / 2.0 + screen->x;
|
||||||
|
yOut = (screen->height - height) / 2.0 + screen->y;
|
||||||
|
wOut = width;
|
||||||
|
hOut = height;
|
||||||
|
}
|
||||||
|
|
||||||
struct GraphicsContextXlib : IGraphicsContext
|
struct GraphicsContextXlib : IGraphicsContext
|
||||||
{
|
{
|
||||||
EGraphicsAPI m_api;
|
EGraphicsAPI m_api;
|
||||||
|
@ -976,7 +987,13 @@ public:
|
||||||
|
|
||||||
/* Create window */
|
/* Create window */
|
||||||
int x, y, w, h;
|
int x, y, w, h;
|
||||||
genFrameDefault(screen, x, y, w, h);
|
int nmonitors = 0;
|
||||||
|
XRRMonitorInfo* mInfo = XRRGetMonitors(m_xDisp, screen->root, true, &nmonitors);
|
||||||
|
if (nmonitors)
|
||||||
|
genFrameDefault(mInfo, x, y, w, h);
|
||||||
|
else
|
||||||
|
genFrameDefault(screen, x, y, w, h);
|
||||||
|
XRRFreeMonitors(mInfo);
|
||||||
XSetWindowAttributes swa;
|
XSetWindowAttributes swa;
|
||||||
swa.colormap = m_colormapId;
|
swa.colormap = m_colormapId;
|
||||||
swa.border_pixmap = 0;
|
swa.border_pixmap = 0;
|
||||||
|
@ -1042,6 +1059,7 @@ public:
|
||||||
XMapWindow(m_xDisp, m_windowId);
|
XMapWindow(m_xDisp, m_windowId);
|
||||||
setStyle(EWindowStyle::Default);
|
setStyle(EWindowStyle::Default);
|
||||||
setCursor(EMouseCursor::Pointer);
|
setCursor(EMouseCursor::Pointer);
|
||||||
|
setWindowFrameDefault();
|
||||||
XFlush(m_xDisp);
|
XFlush(m_xDisp);
|
||||||
|
|
||||||
if (!m_gfxCtx->initializeContext(vulkanHandle))
|
if (!m_gfxCtx->initializeContext(vulkanHandle))
|
||||||
|
@ -1150,9 +1168,14 @@ public:
|
||||||
|
|
||||||
void setWindowFrameDefault()
|
void setWindowFrameDefault()
|
||||||
{
|
{
|
||||||
int x, y, w, h;
|
int x, y, w, h, nmonitors;
|
||||||
Screen* screen = DefaultScreenOfDisplay(m_xDisp);
|
Screen* screen = DefaultScreenOfDisplay(m_xDisp);
|
||||||
genFrameDefault(screen, x, y, w, h);
|
XRRMonitorInfo* mInfo = XRRGetMonitors(m_xDisp, screen->root, true, &nmonitors);
|
||||||
|
if (nmonitors)
|
||||||
|
genFrameDefault(mInfo, x, y, w, h);
|
||||||
|
else
|
||||||
|
genFrameDefault(screen, x, y, w, h);
|
||||||
|
XRRFreeMonitors(mInfo);
|
||||||
XWindowChanges values = {(int)x, (int)y, (int)w, (int)h};
|
XWindowChanges values = {(int)x, (int)y, (int)w, (int)h};
|
||||||
XLockDisplay(m_xDisp);
|
XLockDisplay(m_xDisp);
|
||||||
XConfigureWindow(m_xDisp, m_windowId, CWX|CWY|CWWidth|CWHeight, &values);
|
XConfigureWindow(m_xDisp, m_windowId, CWX|CWY|CWWidth|CWHeight, &values);
|
||||||
|
|
2
logvisor
2
logvisor
|
@ -1 +1 @@
|
||||||
Subproject commit f8ab0e03bae0cad2541f551350dcafb91477b007
|
Subproject commit bfe0c1ccad9ee545a6ab9c0b295258c47b55da3c
|
Loading…
Reference in New Issue