Xlib deep color support

This commit is contained in:
Jack Andersen 2018-01-21 21:33:47 -10:00
parent b9d200c61d
commit 25dc238c44
6 changed files with 70 additions and 18 deletions

View File

@ -47,6 +47,7 @@ struct VulkanContext
VkCommandPool m_loadPool; VkCommandPool m_loadPool;
VkCommandBuffer m_loadCmdBuf; VkCommandBuffer m_loadCmdBuf;
VkFormat m_displayFormat; VkFormat m_displayFormat;
VkFormat m_internalFormat;
struct Window struct Window
{ {

View File

@ -607,7 +607,9 @@ void VulkanContext::Window::SwapChain::Buffer::setImage
void VulkanContext::initSwapChain(VulkanContext::Window& windowCtx, VkSurfaceKHR surface, void VulkanContext::initSwapChain(VulkanContext::Window& windowCtx, VkSurfaceKHR surface,
VkFormat format, VkColorSpaceKHR colorspace) VkFormat format, VkColorSpaceKHR colorspace)
{ {
m_displayFormat = format; m_internalFormat = m_displayFormat = format;
if (m_deepColor)
m_internalFormat = VK_FORMAT_R16G16B16A16_UNORM;
VkSurfaceCapabilitiesKHR surfCapabilities; VkSurfaceCapabilitiesKHR surfCapabilities;
ThrowIfFailed(vk::GetPhysicalDeviceSurfaceCapabilitiesKHR(m_gpus[0], surface, &surfCapabilities)); ThrowIfFailed(vk::GetPhysicalDeviceSurfaceCapabilitiesKHR(m_gpus[0], surface, &surfCapabilities));
@ -770,7 +772,7 @@ void VulkanContext::initSwapChain(VulkanContext::Window& windowCtx, VkSurfaceKHR
VkAttachmentDescription attachments[2] = {}; VkAttachmentDescription attachments[2] = {};
/* color attachment */ /* color attachment */
attachments[0].format = m_displayFormat; attachments[0].format = m_internalFormat;
attachments[0].samples = VkSampleCountFlagBits(m_sampleCountColor); attachments[0].samples = VkSampleCountFlagBits(m_sampleCountColor);
attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; 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)); ThrowIfFailed(vk::CreateRenderPass(m_dev, &renderPass, nullptr, &m_pass));
/* render pass color only */ /* render pass color only */
attachments[0].format = m_displayFormat;
renderPass.attachmentCount = 1; renderPass.attachmentCount = 1;
subpass.pDepthStencilAttachment = nullptr; subpass.pDepthStencilAttachment = nullptr;
ThrowIfFailed(vk::CreateRenderPass(m_dev, &renderPass, nullptr, &m_passColorOnly)); ThrowIfFailed(vk::CreateRenderPass(m_dev, &renderPass, nullptr, &m_passColorOnly));
@ -1797,7 +1800,7 @@ class VulkanTextureR : public GraphicsDataNode<ITextureR>
texCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; texCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
texCreateInfo.pNext = nullptr; texCreateInfo.pNext = nullptr;
texCreateInfo.imageType = VK_IMAGE_TYPE_2D; texCreateInfo.imageType = VK_IMAGE_TYPE_2D;
texCreateInfo.format = ctx->m_displayFormat; texCreateInfo.format = ctx->m_internalFormat;
texCreateInfo.extent.width = m_width; texCreateInfo.extent.width = m_width;
texCreateInfo.extent.height = m_height; texCreateInfo.extent.height = m_height;
texCreateInfo.extent.depth = 1; texCreateInfo.extent.depth = 1;
@ -1848,7 +1851,7 @@ class VulkanTextureR : public GraphicsDataNode<ITextureR>
for (size_t i=0 ; i<m_colorBindCount ; ++i) for (size_t i=0 ; i<m_colorBindCount ; ++i)
{ {
m_colorBindLayout[i] = VK_IMAGE_LAYOUT_UNDEFINED; m_colorBindLayout[i] = VK_IMAGE_LAYOUT_UNDEFINED;
texCreateInfo.format = ctx->m_displayFormat; texCreateInfo.format = ctx->m_internalFormat;
texCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; texCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
ThrowIfFailed(vk::CreateImage(ctx->m_dev, &texCreateInfo, nullptr, &m_colorBindTex[i])); ThrowIfFailed(vk::CreateImage(ctx->m_dev, &texCreateInfo, nullptr, &m_colorBindTex[i]));
@ -1899,7 +1902,7 @@ class VulkanTextureR : public GraphicsDataNode<ITextureR>
viewCreateInfo.pNext = nullptr; viewCreateInfo.pNext = nullptr;
viewCreateInfo.image = m_colorTex; viewCreateInfo.image = m_colorTex;
viewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; 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.r = VK_COMPONENT_SWIZZLE_R;
viewCreateInfo.components.g = VK_COMPONENT_SWIZZLE_G; viewCreateInfo.components.g = VK_COMPONENT_SWIZZLE_G;
viewCreateInfo.components.b = VK_COMPONENT_SWIZZLE_B; viewCreateInfo.components.b = VK_COMPONENT_SWIZZLE_B;
@ -1920,7 +1923,7 @@ class VulkanTextureR : public GraphicsDataNode<ITextureR>
{ {
ThrowIfFailed(vk::BindImageMemory(ctx->m_dev, m_colorBindTex[i], m_gpuMem, colorOffsets[i])); ThrowIfFailed(vk::BindImageMemory(ctx->m_dev, m_colorBindTex[i], m_gpuMem, colorOffsets[i]));
viewCreateInfo.image = m_colorBindTex[i]; viewCreateInfo.image = m_colorBindTex[i];
viewCreateInfo.format = ctx->m_displayFormat; viewCreateInfo.format = ctx->m_internalFormat;
viewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; viewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
ThrowIfFailed(vk::CreateImageView(ctx->m_dev, &viewCreateInfo, nullptr, &m_colorBindView[i])); ThrowIfFailed(vk::CreateImageView(ctx->m_dev, &viewCreateInfo, nullptr, &m_colorBindView[i]));
m_colorBindDescInfo[i].imageView = 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]; VulkanContext::Window::SwapChain::Buffer& dest = sc.m_bufs[sc.m_backBuf];
VulkanDataFactoryImpl* dataFactory = static_cast<VulkanDataFactoryImpl*>(m_parent->getDataFactory()); VulkanDataFactoryImpl* dataFactory = static_cast<VulkanDataFactoryImpl*>(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); SWindowRect rect(0, 0, csource->m_width, csource->m_height);
_resolveBindTexture(cmdBuf, csource, rect, true, 0, true, false); _resolveBindTexture(cmdBuf, csource, rect, true, 0, true, false);

View File

@ -69,10 +69,10 @@ int ApplicationRun(IApplication::EPlatformType platform,
if (APP) if (APP)
return 1; return 1;
if (platform == IApplication::EPlatformType::Wayland) 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 || else if (platform == IApplication::EPlatformType::Xlib ||
platform == IApplication::EPlatformType::Auto) 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 else
return 1; return 1;
return APP->run(); return APP->run();

View File

@ -35,6 +35,7 @@ public:
std::string_view gfxApi, std::string_view gfxApi,
uint32_t samples, uint32_t samples,
uint32_t anisotropy, uint32_t anisotropy,
bool deepColor,
bool singleInstance) bool singleInstance)
: m_callback(callback), : m_callback(callback),
m_uniqueName(uniqueName), m_uniqueName(uniqueName),

View File

@ -30,6 +30,7 @@ DBusConnection* RegisterDBus(const char* appName, bool& isFirst);
#include <X11/Xlib-xcb.h> #include <X11/Xlib-xcb.h>
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
#include <dlfcn.h> #include <dlfcn.h>
#include "boo/graphicsdev/Vulkan.hpp"
#endif #endif
namespace boo namespace boo
@ -228,6 +229,7 @@ public:
std::string_view gfxApi, std::string_view gfxApi,
uint32_t samples, uint32_t samples,
uint32_t anisotropy, uint32_t anisotropy,
bool deepColor,
bool singleInstance) bool singleInstance)
: m_callback(callback), : m_callback(callback),
m_uniqueName(uniqueName), m_uniqueName(uniqueName),
@ -238,7 +240,13 @@ public:
{ {
m_glContext.m_sampleCount = samples; m_glContext.m_sampleCount = samples;
m_glContext.m_anisotropy = anisotropy; m_glContext.m_anisotropy = anisotropy;
m_glContext.m_deepColor = deepColor;
#if BOO_HAS_VULKAN #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 */ /* Check for Vulkan presence and preference */
bool tryVulkan = true; bool tryVulkan = true;
if (!gfxApi.compare("OpenGL")) if (!gfxApi.compare("OpenGL"))

View File

@ -3,6 +3,7 @@
#include "boo/IApplication.hpp" #include "boo/IApplication.hpp"
#include "boo/graphicsdev/GL.hpp" #include "boo/graphicsdev/GL.hpp"
#include "boo/audiodev/IAudioVoiceEngine.hpp" #include "boo/audiodev/IAudioVoiceEngine.hpp"
#include "boo/graphicsdev/glew.h"
#if BOO_HAS_VULKAN #if BOO_HAS_VULKAN
#include "boo/graphicsdev/Vulkan.hpp" #include "boo/graphicsdev/Vulkan.hpp"
@ -334,8 +335,8 @@ public:
GraphicsContextXlibGLX(EGraphicsAPI api, IWindow* parentWindow, GraphicsContextXlibGLX(EGraphicsAPI api, IWindow* parentWindow,
Display* display, int defaultScreen, Display* display, int defaultScreen,
GLXContext lastCtx, uint32_t& visualIdOut, GLContext* glCtx) GLXContext lastCtx, uint32_t& visualIdOut, GLContext* glCtx)
: GraphicsContextXlib(api, EPixelFormat::RGBA8, parentWindow, display, glCtx), : GraphicsContextXlib(api, glCtx->m_deepColor ? EPixelFormat::RGBA16 : EPixelFormat::RGBA8,
m_lastCtx(lastCtx) parentWindow, display, glCtx), m_lastCtx(lastCtx)
{ {
m_dataFactory = _NewGLDataFactory(this, m_glCtx); m_dataFactory = _NewGLDataFactory(this, m_glCtx);
@ -368,6 +369,20 @@ public:
m_visualid = visualId; m_visualid = visualId;
break; 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) else if (m_pf == EPixelFormat::RGBA8_Z24 && colorSize >= 32 && depthSize >= 24)
{ {
m_fbconfig = config; m_fbconfig = config;
@ -483,6 +498,12 @@ public:
Log.report(logvisor::Fatal, "unable to make new GLX window"); Log.report(logvisor::Fatal, "unable to make new GLX window");
_XlibUpdateLastGlxCtx(m_glxCtx); _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 */ /* Spawn vsync thread */
m_vsyncRunning = true; m_vsyncRunning = true;
std::mutex initmt; std::mutex initmt;
@ -532,6 +553,7 @@ public:
XUnlockDisplay(m_xDisp); XUnlockDisplay(m_xDisp);
m_commandQueue = _NewGLCommandQueue(this, m_glCtx); m_commandQueue = _NewGLCommandQueue(this, m_glCtx);
m_commandQueue->startRenderer();
XLockDisplay(m_xDisp); XLockDisplay(m_xDisp);
return true; return true;
@ -634,7 +656,8 @@ public:
GraphicsContextXlibVulkan(IWindow* parentWindow, GraphicsContextXlibVulkan(IWindow* parentWindow,
Display* display, xcb_connection_t* xcbConn, int defaultScreen, Display* display, xcb_connection_t* xcbConn, int defaultScreen,
VulkanContext* ctx, uint32_t& visualIdOut, GLContext* glCtx) 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) m_xcbConn(xcbConn), m_ctx(ctx)
{ {
Screen* screen = ScreenOfDisplay(display, defaultScreen); Screen* screen = ScreenOfDisplay(display, defaultScreen);
@ -773,14 +796,29 @@ public:
* supported format will be returned. */ * supported format will be returned. */
if (formatCount >= 1) if (formatCount >= 1)
{ {
for (int i=0 ; i<formatCount ; ++i) if (m_ctx->m_deepColor)
{ {
if (surfFormats[i].format == VK_FORMAT_B8G8R8A8_UNORM || for (int i=0 ; i<formatCount ; ++i)
surfFormats[i].format == VK_FORMAT_R8G8B8A8_UNORM)
{ {
m_format = surfFormats[i].format; if (surfFormats[i].format == VK_FORMAT_R16G16B16A16_UNORM)
m_colorspace = surfFormats[i].colorSpace; {
break; m_format = surfFormats[i].format;
m_colorspace = surfFormats[i].colorSpace;
break;
}
}
}
if (m_format == VK_FORMAT_UNDEFINED)
{
for (int i=0 ; i<formatCount ; ++i)
{
if (surfFormats[i].format == VK_FORMAT_B8G8R8A8_UNORM ||
surfFormats[i].format == VK_FORMAT_R8G8B8A8_UNORM)
{
m_format = surfFormats[i].format;
m_colorspace = surfFormats[i].colorSpace;
break;
}
} }
} }
} }
@ -839,6 +877,7 @@ public:
m_dataFactory = _NewVulkanDataFactory(this, m_ctx); m_dataFactory = _NewVulkanDataFactory(this, m_ctx);
m_commandQueue = _NewVulkanCommandQueue(m_ctx, m_ctx->m_windows[m_parentWindow].get(), this); m_commandQueue = _NewVulkanCommandQueue(m_ctx, m_ctx->m_windows[m_parentWindow].get(), this);
m_commandQueue->startRenderer();
return true; return true;
} }