From 25dc238c447f93ad706cfaa7396b5cb96779168e Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Sun, 21 Jan 2018 21:33:47 -1000 Subject: [PATCH] Xlib deep color support --- include/boo/graphicsdev/Vulkan.hpp | 1 + lib/graphicsdev/Vulkan.cpp | 17 +++++---- lib/x11/ApplicationUnix.cpp | 4 +-- lib/x11/ApplicationWayland.hpp | 1 + lib/x11/ApplicationXlib.hpp | 8 +++++ lib/x11/WindowXlib.cpp | 57 +++++++++++++++++++++++++----- 6 files changed, 70 insertions(+), 18 deletions(-) diff --git a/include/boo/graphicsdev/Vulkan.hpp b/include/boo/graphicsdev/Vulkan.hpp index 5c3483e..f02c343 100644 --- a/include/boo/graphicsdev/Vulkan.hpp +++ b/include/boo/graphicsdev/Vulkan.hpp @@ -47,6 +47,7 @@ struct VulkanContext VkCommandPool m_loadPool; VkCommandBuffer m_loadCmdBuf; VkFormat m_displayFormat; + VkFormat m_internalFormat; struct Window { diff --git a/lib/graphicsdev/Vulkan.cpp b/lib/graphicsdev/Vulkan.cpp index e50590f..3944b0a 100644 --- a/lib/graphicsdev/Vulkan.cpp +++ b/lib/graphicsdev/Vulkan.cpp @@ -607,7 +607,9 @@ void VulkanContext::Window::SwapChain::Buffer::setImage void VulkanContext::initSwapChain(VulkanContext::Window& windowCtx, VkSurfaceKHR surface, VkFormat format, VkColorSpaceKHR colorspace) { - m_displayFormat = format; + m_internalFormat = m_displayFormat = format; + if (m_deepColor) + m_internalFormat = VK_FORMAT_R16G16B16A16_UNORM; VkSurfaceCapabilitiesKHR surfCapabilities; ThrowIfFailed(vk::GetPhysicalDeviceSurfaceCapabilitiesKHR(m_gpus[0], surface, &surfCapabilities)); @@ -770,7 +772,7 @@ void VulkanContext::initSwapChain(VulkanContext::Window& windowCtx, VkSurfaceKHR VkAttachmentDescription attachments[2] = {}; /* color attachment */ - attachments[0].format = m_displayFormat; + attachments[0].format = m_internalFormat; attachments[0].samples = VkSampleCountFlagBits(m_sampleCountColor); attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; @@ -808,6 +810,7 @@ void VulkanContext::initSwapChain(VulkanContext::Window& windowCtx, VkSurfaceKHR ThrowIfFailed(vk::CreateRenderPass(m_dev, &renderPass, nullptr, &m_pass)); /* render pass color only */ + attachments[0].format = m_displayFormat; renderPass.attachmentCount = 1; subpass.pDepthStencilAttachment = nullptr; ThrowIfFailed(vk::CreateRenderPass(m_dev, &renderPass, nullptr, &m_passColorOnly)); @@ -1797,7 +1800,7 @@ class VulkanTextureR : public GraphicsDataNode texCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; texCreateInfo.pNext = nullptr; texCreateInfo.imageType = VK_IMAGE_TYPE_2D; - texCreateInfo.format = ctx->m_displayFormat; + texCreateInfo.format = ctx->m_internalFormat; texCreateInfo.extent.width = m_width; texCreateInfo.extent.height = m_height; texCreateInfo.extent.depth = 1; @@ -1848,7 +1851,7 @@ class VulkanTextureR : public GraphicsDataNode for (size_t i=0 ; im_displayFormat; + texCreateInfo.format = ctx->m_internalFormat; texCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; ThrowIfFailed(vk::CreateImage(ctx->m_dev, &texCreateInfo, nullptr, &m_colorBindTex[i])); @@ -1899,7 +1902,7 @@ class VulkanTextureR : public GraphicsDataNode viewCreateInfo.pNext = nullptr; viewCreateInfo.image = m_colorTex; viewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; - viewCreateInfo.format = ctx->m_displayFormat; + viewCreateInfo.format = ctx->m_internalFormat; viewCreateInfo.components.r = VK_COMPONENT_SWIZZLE_R; viewCreateInfo.components.g = VK_COMPONENT_SWIZZLE_G; viewCreateInfo.components.b = VK_COMPONENT_SWIZZLE_B; @@ -1920,7 +1923,7 @@ class VulkanTextureR : public GraphicsDataNode { ThrowIfFailed(vk::BindImageMemory(ctx->m_dev, m_colorBindTex[i], m_gpuMem, colorOffsets[i])); viewCreateInfo.image = m_colorBindTex[i]; - viewCreateInfo.format = ctx->m_displayFormat; + viewCreateInfo.format = ctx->m_internalFormat; viewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; ThrowIfFailed(vk::CreateImageView(ctx->m_dev, &viewCreateInfo, nullptr, &m_colorBindView[i])); m_colorBindDescInfo[i].imageView = m_colorBindView[i]; @@ -3006,7 +3009,7 @@ struct VulkanCommandQueue : IGraphicsCommandQueue VulkanContext::Window::SwapChain::Buffer& dest = sc.m_bufs[sc.m_backBuf]; VulkanDataFactoryImpl* dataFactory = static_cast(m_parent->getDataFactory()); - if (dataFactory->m_gamma != 1.f) + if (dataFactory->m_gamma != 1.f || m_ctx->m_internalFormat != m_ctx->m_displayFormat) { SWindowRect rect(0, 0, csource->m_width, csource->m_height); _resolveBindTexture(cmdBuf, csource, rect, true, 0, true, false); diff --git a/lib/x11/ApplicationUnix.cpp b/lib/x11/ApplicationUnix.cpp index 1b30312..cea3118 100644 --- a/lib/x11/ApplicationUnix.cpp +++ b/lib/x11/ApplicationUnix.cpp @@ -69,10 +69,10 @@ int ApplicationRun(IApplication::EPlatformType platform, if (APP) return 1; if (platform == IApplication::EPlatformType::Wayland) - APP = new ApplicationWayland(cb, uniqueName, friendlyName, pname, args, gfxApi, samples, anisotropy, singleInstance); + APP = new ApplicationWayland(cb, uniqueName, friendlyName, pname, args, gfxApi, samples, anisotropy, deepColor, singleInstance); else if (platform == IApplication::EPlatformType::Xlib || platform == IApplication::EPlatformType::Auto) - APP = new ApplicationXlib(cb, uniqueName, friendlyName, pname, args, gfxApi, samples, anisotropy, singleInstance); + APP = new ApplicationXlib(cb, uniqueName, friendlyName, pname, args, gfxApi, samples, anisotropy, deepColor, singleInstance); else return 1; return APP->run(); diff --git a/lib/x11/ApplicationWayland.hpp b/lib/x11/ApplicationWayland.hpp index 9470801..e7f2762 100644 --- a/lib/x11/ApplicationWayland.hpp +++ b/lib/x11/ApplicationWayland.hpp @@ -35,6 +35,7 @@ public: std::string_view gfxApi, uint32_t samples, uint32_t anisotropy, + bool deepColor, bool singleInstance) : m_callback(callback), m_uniqueName(uniqueName), diff --git a/lib/x11/ApplicationXlib.hpp b/lib/x11/ApplicationXlib.hpp index 9f1ec23..ae1875e 100644 --- a/lib/x11/ApplicationXlib.hpp +++ b/lib/x11/ApplicationXlib.hpp @@ -30,6 +30,7 @@ DBusConnection* RegisterDBus(const char* appName, bool& isFirst); #include #include #include +#include "boo/graphicsdev/Vulkan.hpp" #endif namespace boo @@ -228,6 +229,7 @@ public: std::string_view gfxApi, uint32_t samples, uint32_t anisotropy, + bool deepColor, bool singleInstance) : m_callback(callback), m_uniqueName(uniqueName), @@ -238,7 +240,13 @@ public: { m_glContext.m_sampleCount = samples; m_glContext.m_anisotropy = anisotropy; + m_glContext.m_deepColor = deepColor; #if BOO_HAS_VULKAN + g_VulkanContext.m_sampleCountColor = samples; + g_VulkanContext.m_sampleCountDepth = samples; + g_VulkanContext.m_anisotropy = anisotropy; + g_VulkanContext.m_deepColor = deepColor; + /* Check for Vulkan presence and preference */ bool tryVulkan = true; if (!gfxApi.compare("OpenGL")) diff --git a/lib/x11/WindowXlib.cpp b/lib/x11/WindowXlib.cpp index da41022..8d63ab4 100644 --- a/lib/x11/WindowXlib.cpp +++ b/lib/x11/WindowXlib.cpp @@ -3,6 +3,7 @@ #include "boo/IApplication.hpp" #include "boo/graphicsdev/GL.hpp" #include "boo/audiodev/IAudioVoiceEngine.hpp" +#include "boo/graphicsdev/glew.h" #if BOO_HAS_VULKAN #include "boo/graphicsdev/Vulkan.hpp" @@ -334,8 +335,8 @@ public: GraphicsContextXlibGLX(EGraphicsAPI api, IWindow* parentWindow, Display* display, int defaultScreen, GLXContext lastCtx, uint32_t& visualIdOut, GLContext* glCtx) - : GraphicsContextXlib(api, EPixelFormat::RGBA8, parentWindow, display, glCtx), - m_lastCtx(lastCtx) + : GraphicsContextXlib(api, glCtx->m_deepColor ? EPixelFormat::RGBA16 : EPixelFormat::RGBA8, + parentWindow, display, glCtx), m_lastCtx(lastCtx) { m_dataFactory = _NewGLDataFactory(this, m_glCtx); @@ -368,6 +369,20 @@ public: m_visualid = visualId; break; } + else if (m_pf == EPixelFormat::RGBA16) + { + if (colorSize >= 64) + { + m_fbconfig = config; + m_visualid = visualId; + break; + } + else if (!m_visualid && colorSize >= 32) + { + m_fbconfig = config; + m_visualid = visualId; + } + } else if (m_pf == EPixelFormat::RGBA8_Z24 && colorSize >= 32 && depthSize >= 24) { m_fbconfig = config; @@ -483,6 +498,12 @@ public: Log.report(logvisor::Fatal, "unable to make new GLX window"); _XlibUpdateLastGlxCtx(m_glxCtx); + if (!glXMakeCurrent(m_xDisp, DefaultRootWindow(m_xDisp), m_glxCtx)) + Log.report(logvisor::Fatal, "unable to make GLX context current"); + if (glewInit() != GLEW_OK) + Log.report(logvisor::Fatal, "glewInit failed"); + glXMakeCurrent(m_xDisp, 0, 0); + /* Spawn vsync thread */ m_vsyncRunning = true; std::mutex initmt; @@ -532,6 +553,7 @@ public: XUnlockDisplay(m_xDisp); m_commandQueue = _NewGLCommandQueue(this, m_glCtx); + m_commandQueue->startRenderer(); XLockDisplay(m_xDisp); return true; @@ -634,7 +656,8 @@ public: GraphicsContextXlibVulkan(IWindow* parentWindow, Display* display, xcb_connection_t* xcbConn, int defaultScreen, VulkanContext* ctx, uint32_t& visualIdOut, GLContext* glCtx) - : GraphicsContextXlib(EGraphicsAPI::Vulkan, EPixelFormat::RGBA8, parentWindow, display, glCtx), + : GraphicsContextXlib(EGraphicsAPI::Vulkan, ctx->m_deepColor ? EPixelFormat::RGBA16 : EPixelFormat::RGBA8, + parentWindow, display, glCtx), m_xcbConn(xcbConn), m_ctx(ctx) { Screen* screen = ScreenOfDisplay(display, defaultScreen); @@ -773,14 +796,29 @@ public: * supported format will be returned. */ if (formatCount >= 1) { - for (int i=0 ; im_deepColor) { - if (surfFormats[i].format == VK_FORMAT_B8G8R8A8_UNORM || - surfFormats[i].format == VK_FORMAT_R8G8B8A8_UNORM) + for (int i=0 ; im_windows[m_parentWindow].get(), this); + m_commandQueue->startRenderer(); return true; }