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()
|
||||
|
||||
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")
|
||||
message(STATUS "Enabling Vulkan support")
|
||||
|
|
|
@ -95,6 +95,7 @@ public:
|
|||
{ m_parent = other.m_parent; other.m_parent = nullptr; return *this; }
|
||||
Token(Token&& other)
|
||||
{ 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(); }
|
||||
operator bool() const { return m_parent != nullptr; }
|
||||
ShaderImpl& get() const { return static_cast<ShaderImpl&>(*m_parent); }
|
||||
|
|
|
@ -67,6 +67,7 @@ public:
|
|||
ThreadLocalPtr<struct GLData> GLDataFactoryImpl::m_deferredData;
|
||||
struct GLData : IGraphicsDataPriv
|
||||
{
|
||||
int m_deadCounter = 0;
|
||||
std::vector<std::unique_ptr<class GLShaderPipeline>> m_SPs;
|
||||
std::vector<std::unique_ptr<struct GLShaderDataBinding>> m_SBinds;
|
||||
std::vector<std::unique_ptr<class GLGraphicsBufferS>> m_SBufs;
|
||||
|
@ -85,6 +86,7 @@ struct GLPoolItem : IGraphicsDataPriv
|
|||
|
||||
struct GLPool : IGraphicsBufferPool
|
||||
{
|
||||
int m_deadCounter = 0;
|
||||
std::unordered_set<GLPoolItem*> m_items;
|
||||
~GLPool()
|
||||
{
|
||||
|
@ -450,9 +452,9 @@ class GLShaderPipeline : public IShaderPipeline
|
|||
friend class GLDataFactory;
|
||||
friend struct GLCommandQueue;
|
||||
friend struct GLShaderDataBinding;
|
||||
GLShareableShader::Token m_vert;
|
||||
GLShareableShader::Token m_frag;
|
||||
GLuint m_prog = 0;
|
||||
mutable GLShareableShader::Token m_vert;
|
||||
mutable GLShareableShader::Token m_frag;
|
||||
mutable GLuint m_prog = 0;
|
||||
GLenum m_sfactor = GL_ONE;
|
||||
GLenum m_dfactor = GL_ZERO;
|
||||
GLenum m_drawPrim = GL_TRIANGLES;
|
||||
|
@ -462,10 +464,11 @@ class GLShaderPipeline : public IShaderPipeline
|
|||
bool m_alphaWrite = true;
|
||||
bool m_subtractBlend = false;
|
||||
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) {}
|
||||
public:
|
||||
operator bool() const {return m_prog != 0;}
|
||||
~GLShaderPipeline() { if (m_prog) glDeleteProgram(m_prog); }
|
||||
GLShaderPipeline& operator=(const GLShaderPipeline&) = delete;
|
||||
GLShaderPipeline(const GLShaderPipeline&) = delete;
|
||||
|
@ -485,6 +488,8 @@ public:
|
|||
m_subtractBlend = other.m_subtractBlend;
|
||||
m_culling = other.m_culling;
|
||||
m_uniLocs = std::move(other.m_uniLocs);
|
||||
m_texNames = std::move(other.m_texNames);
|
||||
m_blockNames = std::move(other.m_blockNames);
|
||||
return *this;
|
||||
}
|
||||
GLShaderPipeline(GLShaderPipeline&& other)
|
||||
|
@ -492,7 +497,71 @@ public:
|
|||
|
||||
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)
|
||||
{
|
||||
|
@ -654,54 +723,13 @@ IShaderPipeline* GLDataFactory::Context::newShaderPipeline
|
|||
shader.m_frag = it->second->lock();
|
||||
}
|
||||
|
||||
shader.m_prog = glCreateProgram();
|
||||
if (!shader.m_prog)
|
||||
{
|
||||
Log.report(logvisor::Error, "unable to create shader program");
|
||||
return nullptr;
|
||||
}
|
||||
shader.m_texNames.reserve(texCount);
|
||||
for (int i=0 ; i<texCount ; ++i)
|
||||
shader.m_texNames.emplace_back(texNames[i]);
|
||||
|
||||
glAttachShader(shader.m_prog, shader.m_vert.get().m_shader);
|
||||
glAttachShader(shader.m_prog, shader.m_frag.get().m_shader);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
shader.m_blockNames.reserve(uniformBlockCount);
|
||||
for (int i=0 ; i<uniformBlockCount ; ++i)
|
||||
shader.m_blockNames.emplace_back(uniformBlockNames[i]);
|
||||
|
||||
if (srcFac == BlendFactor::Subtract || dstFac == BlendFactor::Subtract)
|
||||
{
|
||||
|
@ -926,8 +954,9 @@ void GLDataFactoryImpl::destroyData(IGraphicsData* d)
|
|||
{
|
||||
std::unique_lock<std::mutex> lk(m_committedMutex);
|
||||
GLData* data = static_cast<GLData*>(d);
|
||||
m_committedData.erase(data);
|
||||
data->decrement();
|
||||
data->m_deadCounter = 3;
|
||||
//m_committedData.erase(data);
|
||||
//data->decrement();
|
||||
}
|
||||
|
||||
void GLDataFactoryImpl::destroyAllData()
|
||||
|
@ -945,8 +974,9 @@ void GLDataFactoryImpl::destroyPool(IGraphicsBufferPool* p)
|
|||
{
|
||||
std::unique_lock<std::mutex> lk(m_committedMutex);
|
||||
GLPool* pool = static_cast<GLPool*>(p);
|
||||
m_committedPools.erase(pool);
|
||||
delete pool;
|
||||
pool->m_deadCounter = 3;
|
||||
//m_committedPools.erase(pool);
|
||||
//delete pool;
|
||||
}
|
||||
|
||||
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_pendingPosts2;
|
||||
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<GLuint> m_pendingFboDels;
|
||||
//std::vector<GLuint> m_pendingFboDels;
|
||||
|
||||
static void ConfigureVertexFormat(GLVertexFormat* fmt)
|
||||
{
|
||||
|
@ -1213,6 +1243,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
|||
self->m_pendingFmtAdds.clear();
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (self->m_pendingFmtDels.size())
|
||||
{
|
||||
for (const auto& fmt : self->m_pendingFmtDels)
|
||||
|
@ -1226,12 +1257,14 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
|||
glDeleteFramebuffers(1, &fbo);
|
||||
self->m_pendingFboDels.clear();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (self->m_pendingPosts2.size())
|
||||
posts.swap(self->m_pendingPosts2);
|
||||
}
|
||||
std::vector<Command>& cmds = self->m_cmdBufs[self->m_drawBuf];
|
||||
GLenum currentPrim = GL_TRIANGLES;
|
||||
const GLShaderDataBinding* curBinding = nullptr;
|
||||
for (const Command& cmd : cmds)
|
||||
{
|
||||
switch (cmd.m_op)
|
||||
|
@ -1240,6 +1273,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
|||
{
|
||||
const GLShaderDataBinding* binding = static_cast<const GLShaderDataBinding*>(cmd.binding);
|
||||
binding->bind(self->m_drawBuf);
|
||||
curBinding = binding;
|
||||
currentPrim = binding->m_pipeline->m_drawPrim;
|
||||
break;
|
||||
}
|
||||
|
@ -1332,6 +1366,31 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
|||
cmds.clear();
|
||||
for (auto& p : posts)
|
||||
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)
|
||||
{
|
||||
#if 0
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
bool foundAdd = false;
|
||||
for (GLVertexFormat*& afmt : m_pendingFmtAdds)
|
||||
|
@ -1507,6 +1567,8 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
|||
}
|
||||
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(GLTextureR* tex)
|
||||
|
@ -1517,8 +1579,11 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
|||
|
||||
void delFBO(GLTextureR* tex)
|
||||
{
|
||||
#if 0
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_pendingFboDels.push_back(tex->m_fbo);
|
||||
#endif
|
||||
glDeleteFramebuffers(1, &tex->m_fbo);
|
||||
}
|
||||
|
||||
void execute()
|
||||
|
|
|
@ -26,11 +26,10 @@ class VulkanDataFactoryImpl;
|
|||
struct VulkanShareableShader : IShareableShader<VulkanDataFactoryImpl, VulkanShareableShader>
|
||||
{
|
||||
VkDevice m_dev;
|
||||
VkShaderModule m_shader;
|
||||
std::vector<unsigned int> m_shader;
|
||||
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) {}
|
||||
~VulkanShareableShader() { vk::DestroyShaderModule(m_dev, m_shader, nullptr); }
|
||||
};
|
||||
|
||||
class VulkanDataFactoryImpl : public VulkanDataFactory
|
||||
|
@ -338,8 +337,8 @@ void VulkanContext::initVulkan(const char* appName)
|
|||
#ifndef NDEBUG
|
||||
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_parameter_validation");
|
||||
m_layerNames.push_back("VK_LAYER_GOOGLE_threading");
|
||||
//m_layerNames.push_back("VK_LAYER_LUNARG_parameter_validation");
|
||||
//m_layerNames.push_back("VK_LAYER_GOOGLE_threading");
|
||||
#endif
|
||||
|
||||
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 VulkanTextureR>> m_RTexs;
|
||||
std::vector<std::unique_ptr<struct VulkanVertexFormat>> m_VFmts;
|
||||
bool m_dead = false;
|
||||
int m_deadCounter = 0;
|
||||
VulkanData(VulkanContext* ctx) : m_ctx(ctx) {}
|
||||
~VulkanData()
|
||||
{
|
||||
|
@ -769,7 +768,7 @@ struct VulkanPoolItem : IGraphicsDataPriv
|
|||
VulkanContext* m_ctx;
|
||||
VkDeviceMemory m_bufMem = VK_NULL_HANDLE;
|
||||
std::unique_ptr<class VulkanGraphicsBufferD> m_buf;
|
||||
bool m_dead = false;
|
||||
int m_deadCounter = 0;
|
||||
VulkanPoolItem(VulkanContext* ctx) : m_ctx(ctx) {}
|
||||
~VulkanPoolItem()
|
||||
{
|
||||
|
@ -781,7 +780,7 @@ struct VulkanPoolItem : IGraphicsDataPriv
|
|||
struct VulkanPool : IGraphicsBufferPool
|
||||
{
|
||||
std::unordered_set<VulkanPoolItem*> m_items;
|
||||
bool m_dead = false;
|
||||
int m_deadCounter = 0;
|
||||
~VulkanPool()
|
||||
{
|
||||
for (auto& item : m_items)
|
||||
|
@ -792,7 +791,7 @@ struct VulkanPool : IGraphicsBufferPool
|
|||
{
|
||||
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 = m_items.erase(it);
|
||||
|
@ -1881,8 +1880,18 @@ class VulkanShaderPipeline : public IShaderPipeline
|
|||
VulkanContext* m_ctx;
|
||||
VkPipelineCache m_pipelineCache;
|
||||
const VulkanVertexFormat* m_vtxFmt;
|
||||
VulkanShareableShader::Token m_vert;
|
||||
VulkanShareableShader::Token m_frag;
|
||||
mutable VulkanShareableShader::Token m_vert;
|
||||
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,
|
||||
VulkanContext* ctx,
|
||||
VulkanShareableShader::Token&& vert,
|
||||
|
@ -1893,171 +1902,197 @@ class VulkanShaderPipeline : public IShaderPipeline
|
|||
ZTest depthTest, bool depthWrite, bool colorWrite,
|
||||
bool alphaWrite, CullMode culling)
|
||||
: IShaderPipeline(parent), m_ctx(ctx), m_pipelineCache(pipelineCache), m_vtxFmt(vtxFmt),
|
||||
m_vert(std::move(vert)), m_frag(std::move(frag))
|
||||
{
|
||||
VkCullModeFlagBits cullMode;
|
||||
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));
|
||||
}
|
||||
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),
|
||||
m_alphaWrite(alphaWrite), m_culling(culling)
|
||||
{}
|
||||
public:
|
||||
VkPipeline m_pipeline;
|
||||
~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)
|
||||
vk::DestroyPipelineCache(m_ctx->m_dev, m_pipelineCache, nullptr);
|
||||
}
|
||||
VulkanShaderPipeline& operator=(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,
|
||||
|
@ -2156,7 +2191,7 @@ struct VulkanShaderDataBinding : IShaderDataBindingPriv
|
|||
std::unique_ptr<IGraphicsBuffer*[]> m_ubufs;
|
||||
std::vector<std::array<VkDescriptorBufferInfo, 2>> m_ubufOffs;
|
||||
size_t m_texCount;
|
||||
VkImageView m_knownViewHandles[2][8] = {};
|
||||
VkImageView m_knownViewHandles[2][BOO_GLSL_MAX_TEXTURE_COUNT] = {};
|
||||
struct BindTex
|
||||
{
|
||||
ITexture* tex;
|
||||
|
@ -2402,7 +2437,7 @@ struct VulkanShaderDataBinding : IShaderDataBindingPriv
|
|||
if (totalWrites)
|
||||
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])
|
||||
vk::CmdBindDescriptorSets(cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, m_ctx->m_pipelinelayout,
|
||||
0, 1, &m_descSets[b], 0, nullptr);
|
||||
|
@ -3023,13 +3058,13 @@ void VulkanTextureD::unmap()
|
|||
void VulkanDataFactoryImpl::destroyData(IGraphicsData* d)
|
||||
{
|
||||
VulkanData* data = static_cast<VulkanData*>(d);
|
||||
data->m_dead = true;
|
||||
data->m_deadCounter = 3;
|
||||
}
|
||||
|
||||
void VulkanDataFactoryImpl::destroyPool(IGraphicsBufferPool* p)
|
||||
{
|
||||
VulkanPool* pool = static_cast<VulkanPool*>(p);
|
||||
pool->m_dead = true;
|
||||
pool->m_deadCounter = 3;
|
||||
}
|
||||
|
||||
void VulkanDataFactoryImpl::destroyAllData()
|
||||
|
@ -3255,15 +3290,10 @@ IShaderPipeline* VulkanDataFactory::Context::newShaderPipeline
|
|||
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 =
|
||||
factory.m_sharedShaders.emplace(std::make_pair(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();
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
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 =
|
||||
factory.m_sharedShaders.emplace(std::make_pair(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();
|
||||
}
|
||||
|
||||
|
||||
VkPipelineCache pipelineCache = VK_NULL_HANDLE;
|
||||
if (pipelineBlob)
|
||||
{
|
||||
|
@ -3590,7 +3614,7 @@ void VulkanDataFactoryImpl::deletePoolBuffer(IGraphicsBufferPool* p, IGraphicsBu
|
|||
VulkanPool* pool = static_cast<VulkanPool*>(p);
|
||||
auto search = pool->m_items.find(static_cast<VulkanPoolItem*>(buf->m_parentData));
|
||||
if (search != pool->m_items.end())
|
||||
(*search)->m_dead = true;
|
||||
(*search)->m_deadCounter = 3;
|
||||
}
|
||||
|
||||
GraphicsBufferPoolToken VulkanDataFactoryImpl::newBufferPool()
|
||||
|
@ -3666,9 +3690,10 @@ void VulkanCommandQueue::execute()
|
|||
datalk.lock();
|
||||
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);
|
||||
continue;
|
||||
}
|
||||
|
@ -3676,16 +3701,16 @@ void VulkanCommandQueue::execute()
|
|||
}
|
||||
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);
|
||||
delete p;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
(*it)->clearDeadBuffers();
|
||||
p->clearDeadBuffers();
|
||||
}
|
||||
++it;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <X11/XKBlib.h>
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#include "logvisor/logvisor.hpp"
|
||||
|
||||
#include "XlibCommon.hpp"
|
||||
|
@ -282,6 +283,16 @@ static void genFrameDefault(Screen* screen, int& xOut, int& yOut, int& wOut, int
|
|||
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
|
||||
{
|
||||
EGraphicsAPI m_api;
|
||||
|
@ -976,7 +987,13 @@ public:
|
|||
|
||||
/* Create window */
|
||||
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;
|
||||
swa.colormap = m_colormapId;
|
||||
swa.border_pixmap = 0;
|
||||
|
@ -1042,6 +1059,7 @@ public:
|
|||
XMapWindow(m_xDisp, m_windowId);
|
||||
setStyle(EWindowStyle::Default);
|
||||
setCursor(EMouseCursor::Pointer);
|
||||
setWindowFrameDefault();
|
||||
XFlush(m_xDisp);
|
||||
|
||||
if (!m_gfxCtx->initializeContext(vulkanHandle))
|
||||
|
@ -1150,9 +1168,14 @@ public:
|
|||
|
||||
void setWindowFrameDefault()
|
||||
{
|
||||
int x, y, w, h;
|
||||
int x, y, w, h, nmonitors;
|
||||
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};
|
||||
XLockDisplay(m_xDisp);
|
||||
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