mirror of https://github.com/AxioDL/boo.git
Vulkan platform conformances
This commit is contained in:
parent
295d100ca3
commit
0c99623aa9
|
@ -9,8 +9,10 @@
|
|||
"#define gl_VertexID gl_VertexIndex\n" \
|
||||
"#extension GL_ARB_separate_shader_objects: enable\n" \
|
||||
"#define SBINDING(idx) layout(location=idx)\n" \
|
||||
"#define FLIPFROMGL(vec) vec4((vec).x, -(vec).y, (vec).z, (vec).w)\n" \
|
||||
"#else\n" \
|
||||
"#define SBINDING(idx)\n" \
|
||||
"#define FLIPFROMGL(vec) (vec)\n" \
|
||||
"#endif\n" \
|
||||
"#extension GL_ARB_shading_language_420pack: enable\n" \
|
||||
"#ifdef GL_ARB_shading_language_420pack\n" \
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#define GDEV_VULKAN_HPP
|
||||
#if BOO_HAS_VULKAN
|
||||
|
||||
#define SRGB_HACK 0
|
||||
|
||||
#include "IGraphicsDataFactory.hpp"
|
||||
#include "IGraphicsCommandQueue.hpp"
|
||||
#include "boo/IGraphicsContext.hpp"
|
||||
|
@ -43,6 +45,27 @@ struct VulkanContext
|
|||
VkCommandPool m_loadPool;
|
||||
VkCommandBuffer m_loadCmdBuf;
|
||||
VkSampler m_linearSampler;
|
||||
|
||||
#if SRGB_HACK
|
||||
/* Dedicated objects for performing shader-based sRGB conversion */
|
||||
VkDescriptorSetLayout m_srgbDescSetLayout;
|
||||
VkDescriptorPool m_srgbDescPool;
|
||||
VkDescriptorSet m_srgbDescSet;
|
||||
VkPipelineLayout m_srgbPipelinelayout;
|
||||
VkRenderPass m_srgbPass;
|
||||
VkPipelineCache m_srgbPipelineCache;
|
||||
VkBuffer m_srgbVertBuf;
|
||||
VkDeviceMemory m_srgbVertBufMem;
|
||||
VkShaderModule m_srgbVert;
|
||||
VkShaderModule m_srgbFrag;
|
||||
VkPipeline m_srgbPipeline;
|
||||
VkPipeline m_srgbPipelinePreResize = VK_NULL_HANDLE;
|
||||
VkBuffer m_srgbRampTextureBuf;
|
||||
VkDeviceMemory m_srgbRampTextureMem;
|
||||
VkImage m_srgbRampTexture;
|
||||
VkImageView m_srgbRampTextureView;
|
||||
#endif
|
||||
|
||||
struct Window
|
||||
{
|
||||
struct SwapChain
|
||||
|
@ -52,6 +75,10 @@ struct VulkanContext
|
|||
struct Buffer
|
||||
{
|
||||
VkImage m_image = VK_NULL_HANDLE;
|
||||
#if SRGB_HACK
|
||||
VkImageView m_view;
|
||||
VkFramebuffer m_framebuffer;
|
||||
#endif
|
||||
VkImageLayout m_layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
};
|
||||
std::vector<Buffer> m_bufs;
|
||||
|
@ -61,6 +88,13 @@ struct VulkanContext
|
|||
m_bufs.clear();
|
||||
if (m_swapChain)
|
||||
{
|
||||
#if SRGB_HACK
|
||||
for (Buffer& buf : m_bufs)
|
||||
{
|
||||
vk::DestroyFramebuffer(dev, buf.m_framebuffer, nullptr);
|
||||
vk::DestroyImageView(dev, buf.m_view, nullptr);
|
||||
}
|
||||
#endif
|
||||
vk::DestroySwapchainKHR(dev, m_swapChain, nullptr);
|
||||
m_swapChain = VK_NULL_HANDLE;
|
||||
}
|
||||
|
@ -74,8 +108,8 @@ struct VulkanContext
|
|||
void initVulkan(const char* appName);
|
||||
void enumerateDevices();
|
||||
void initDevice();
|
||||
void initSwapChain(Window& windowCtx, VkSurfaceKHR surface, VkFormat format);
|
||||
void resizeSwapChain(Window& windowCtx, VkSurfaceKHR surface, VkFormat format);
|
||||
void initSwapChain(Window& windowCtx, VkSurfaceKHR surface, VkFormat format, VkColorSpaceKHR colorspace);
|
||||
void resizeSwapChain(Window& windowCtx, VkSurfaceKHR surface, VkFormat format, VkColorSpaceKHR colorspace);
|
||||
};
|
||||
extern VulkanContext g_VulkanContext;
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "boo/graphicsdev/Vulkan.hpp"
|
||||
#include "boo/IGraphicsContext.hpp"
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
#include <glslang/Public/ShaderLang.h>
|
||||
#include <StandAlone/ResourceLimits.h>
|
||||
#include <SPIRV/GlslangToSpv.h>
|
||||
|
@ -18,6 +19,41 @@ namespace boo
|
|||
static logvisor::Module Log("boo::Vulkan");
|
||||
VulkanContext g_VulkanContext;
|
||||
|
||||
static const char* LinToSrgbVS =
|
||||
"#version 330\n"
|
||||
BOO_GLSL_BINDING_HEAD
|
||||
"layout(location=0) in vec3 inPos;\n"
|
||||
"layout(location=1) in vec2 inUv;\n"
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" vec4 uv;\n"
|
||||
"};\n"
|
||||
"SBINDING(0) out VertToFrag vtf;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_Position = vec4(inPos, 1.0);\n"
|
||||
" vtf.uv.xy = inUv;\n"
|
||||
"}\n";
|
||||
|
||||
static const char* LinToSrgbFS =
|
||||
"#version 330\n"
|
||||
BOO_GLSL_BINDING_HEAD
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" vec4 uv;\n"
|
||||
"};\n"
|
||||
"layout(binding=0) uniform sampler2D sceneTex;\n"
|
||||
"layout(binding=1) uniform sampler1D rampTex;\n"
|
||||
"SBINDING(0) in VertToFrag vtf;\n"
|
||||
"layout(location=0) out vec4 outColor;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" outColor = texture(sceneTex, vtf.uv.xy);\n"
|
||||
" outColor.r = texture(rampTex, outColor.r).r;\n"
|
||||
" outColor.g = texture(rampTex, outColor.g).r;\n"
|
||||
" outColor.b = texture(rampTex, outColor.b).r;\n"
|
||||
"}\n";
|
||||
|
||||
static inline void ThrowIfFailed(VkResult res)
|
||||
{
|
||||
if (res != VK_SUCCESS)
|
||||
|
@ -100,7 +136,7 @@ static void SetImageLayout(VkCommandBuffer cmd, VkImage image,
|
|||
|
||||
if (old_image_layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
|
||||
imageMemoryBarrier.srcAccessMask =
|
||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
|
||||
}
|
||||
|
||||
if (old_image_layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
|
||||
|
@ -123,6 +159,11 @@ static void SetImageLayout(VkCommandBuffer cmd, VkImage image,
|
|||
VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
}
|
||||
|
||||
if (old_image_layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
|
||||
imageMemoryBarrier.srcAccessMask =
|
||||
VK_ACCESS_SHADER_READ_BIT;
|
||||
}
|
||||
|
||||
if (new_image_layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
|
||||
/* Make sure anything that was copying from this image has completed */
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
|
@ -135,14 +176,12 @@ static void SetImageLayout(VkCommandBuffer cmd, VkImage image,
|
|||
|
||||
if (new_image_layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
|
||||
/* Make sure any Copy or CPU writes to image are flushed */
|
||||
imageMemoryBarrier.srcAccessMask =
|
||||
VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
}
|
||||
|
||||
if (new_image_layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
|
||||
imageMemoryBarrier.dstAccessMask =
|
||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
|
||||
}
|
||||
|
||||
if (new_image_layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
|
||||
|
@ -267,7 +306,7 @@ void VulkanContext::initVulkan(const char* appName)
|
|||
m_layerNames.push_back("VK_LAYER_LUNARG_device_limits");
|
||||
m_layerNames.push_back("VK_LAYER_LUNARG_image");
|
||||
m_layerNames.push_back("VK_LAYER_LUNARG_parameter_validation");
|
||||
m_layerNames.push_back("VK_LAYER_LUNARG_swapchain");
|
||||
//m_layerNames.push_back("VK_LAYER_LUNARG_swapchain");
|
||||
m_layerNames.push_back("VK_LAYER_GOOGLE_threading");
|
||||
#endif
|
||||
|
||||
|
@ -373,7 +412,7 @@ void VulkanContext::initDevice()
|
|||
ThrowIfFailed(vk::CreateDevice(m_gpus[0], &deviceInfo, nullptr, &m_dev));
|
||||
}
|
||||
|
||||
void VulkanContext::initSwapChain(VulkanContext::Window& windowCtx, VkSurfaceKHR surface, VkFormat format)
|
||||
void VulkanContext::initSwapChain(VulkanContext::Window& windowCtx, VkSurfaceKHR surface, VkFormat format, VkColorSpaceKHR colorspace)
|
||||
{
|
||||
VkSurfaceCapabilitiesKHR surfCapabilities;
|
||||
ThrowIfFailed(vk::GetPhysicalDeviceSurfaceCapabilitiesKHR(m_gpus[0], surface, &surfCapabilities));
|
||||
|
@ -440,7 +479,7 @@ void VulkanContext::initSwapChain(VulkanContext::Window& windowCtx, VkSurfaceKHR
|
|||
swapChainInfo.pNext = nullptr;
|
||||
swapChainInfo.surface = surface;
|
||||
swapChainInfo.minImageCount = desiredNumberOfSwapChainImages;
|
||||
swapChainInfo.imageFormat = format;
|
||||
swapChainInfo.imageFormat = VK_FORMAT_B8G8R8A8_UNORM;
|
||||
swapChainInfo.imageExtent.width = swapChainExtent.width;
|
||||
swapChainInfo.imageExtent.height = swapChainExtent.height;
|
||||
swapChainInfo.preTransform = preTransform;
|
||||
|
@ -449,8 +488,12 @@ void VulkanContext::initSwapChain(VulkanContext::Window& windowCtx, VkSurfaceKHR
|
|||
swapChainInfo.presentMode = swapchainPresentMode;
|
||||
swapChainInfo.oldSwapchain = nullptr;
|
||||
swapChainInfo.clipped = true;
|
||||
swapChainInfo.imageColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
|
||||
swapChainInfo.imageColorSpace = colorspace;
|
||||
#if SRGB_HACK
|
||||
swapChainInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
#else
|
||||
swapChainInfo.imageUsage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||
#endif
|
||||
swapChainInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
swapChainInfo.queueFamilyIndexCount = 0;
|
||||
swapChainInfo.pQueueFamilyIndices = nullptr;
|
||||
|
@ -465,11 +508,6 @@ void VulkanContext::initSwapChain(VulkanContext::Window& windowCtx, VkSurfaceKHR
|
|||
VkImage* swapchainImages = (VkImage*)malloc(swapchainImageCount * sizeof(VkImage));
|
||||
ThrowIfFailed(vk::GetSwapchainImagesKHR(m_dev, sc.m_swapChain, &swapchainImageCount, swapchainImages));
|
||||
|
||||
sc.m_bufs.resize(swapchainImageCount);
|
||||
for (uint32_t i=0 ; i<swapchainImageCount ; ++i)
|
||||
sc.m_bufs[i].m_image = swapchainImages[i];
|
||||
free(swapchainImages);
|
||||
|
||||
// Going to need a command buffer to send the memory barriers in
|
||||
// set_image_layout but we couldn't have created one before we knew
|
||||
// what our graphics_queue_family_index is, but now that we have it,
|
||||
|
@ -497,10 +535,479 @@ void VulkanContext::initSwapChain(VulkanContext::Window& windowCtx, VkSurfaceKHR
|
|||
cmdBufBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
cmdBufBeginInfo.flags = 0;
|
||||
ThrowIfFailed(vk::BeginCommandBuffer(m_loadCmdBuf, &cmdBufBeginInfo));
|
||||
|
||||
/* Create shared linear sampler */
|
||||
VkSamplerCreateInfo samplerInfo = {};
|
||||
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||
samplerInfo.pNext = nullptr;
|
||||
samplerInfo.magFilter = VK_FILTER_LINEAR;
|
||||
samplerInfo.minFilter = VK_FILTER_LINEAR;
|
||||
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
ThrowIfFailed(vk::CreateSampler(m_dev, &samplerInfo, nullptr, &m_linearSampler));
|
||||
|
||||
#if SRGB_HACK
|
||||
/* Construct sRGB conversion objects */
|
||||
struct Vert
|
||||
{
|
||||
float pos[3];
|
||||
float uv[2];
|
||||
};
|
||||
static const Vert quad[4] =
|
||||
{
|
||||
{{1.0,1.0},{1.0,1.0}},
|
||||
{{-1.0,1.0},{0.0,1.0}},
|
||||
{{1.0,-1.0},{1.0,0.0}},
|
||||
{{-1.0,-1.0},{0.0,0.0}}
|
||||
};
|
||||
|
||||
VkBufferCreateInfo bufInfo = {};
|
||||
bufInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||
bufInfo.pNext = nullptr;
|
||||
bufInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
|
||||
bufInfo.size = sizeof(quad);
|
||||
bufInfo.queueFamilyIndexCount = 0;
|
||||
bufInfo.pQueueFamilyIndices = nullptr;
|
||||
bufInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
bufInfo.flags = 0;
|
||||
ThrowIfFailed(vk::CreateBuffer(m_dev, &bufInfo, nullptr, &m_srgbVertBuf));
|
||||
|
||||
VkMemoryAllocateInfo memAlloc = {};
|
||||
memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||
memAlloc.allocationSize = 256;
|
||||
uint32_t memTypeBits = ~0;
|
||||
VkMemoryRequirements memReqs;
|
||||
vk::GetBufferMemoryRequirements(m_dev, m_srgbVertBuf, &memReqs);
|
||||
memTypeBits &= memReqs.memoryTypeBits;
|
||||
ThrowIfFalse(MemoryTypeFromProperties(this, memTypeBits,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
|
||||
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
||||
&memAlloc.memoryTypeIndex));
|
||||
ThrowIfFailed(vk::AllocateMemory(m_dev, &memAlloc, nullptr, &m_srgbVertBufMem));
|
||||
uint8_t* mappedData;
|
||||
ThrowIfFailed(vk::MapMemory(m_dev, m_srgbVertBufMem, 0, memReqs.size, 0, reinterpret_cast<void**>(&mappedData)));
|
||||
memmove(mappedData, &quad, sizeof(quad));
|
||||
vk::UnmapMemory(m_dev, m_srgbVertBufMem);
|
||||
ThrowIfFailed(vk::BindBufferMemory(m_dev, m_srgbVertBuf, m_srgbVertBufMem, 0));
|
||||
|
||||
bufInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||
bufInfo.pNext = nullptr;
|
||||
bufInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
||||
bufInfo.size = 256 * 4;
|
||||
bufInfo.queueFamilyIndexCount = 0;
|
||||
bufInfo.pQueueFamilyIndices = nullptr;
|
||||
bufInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
bufInfo.flags = 0;
|
||||
ThrowIfFailed(vk::CreateBuffer(m_dev, &bufInfo, nullptr, &m_srgbRampTextureBuf));
|
||||
|
||||
memAlloc.allocationSize = 256 * 4;
|
||||
memTypeBits = ~0;
|
||||
vk::GetBufferMemoryRequirements(m_dev, m_srgbRampTextureBuf, &memReqs);
|
||||
memTypeBits &= memReqs.memoryTypeBits;
|
||||
ThrowIfFalse(MemoryTypeFromProperties(this, memTypeBits,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
|
||||
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
||||
&memAlloc.memoryTypeIndex));
|
||||
ThrowIfFailed(vk::AllocateMemory(m_dev, &memAlloc, nullptr, &m_srgbRampTextureMem));
|
||||
float* mappedTexData;
|
||||
ThrowIfFailed(vk::MapMemory(m_dev, m_srgbRampTextureMem, 0, memReqs.size, 0, reinterpret_cast<void**>(&mappedTexData)));
|
||||
for (int i=0 ; i<256 ; ++i)
|
||||
{
|
||||
float val = i / 255.f;
|
||||
if (val <= 0.0031308f)
|
||||
mappedTexData[i] = val * 12.92f;
|
||||
else
|
||||
mappedTexData[i] = 1.055f * std::pow(val, 1.f/2.4f) - 0.055f;
|
||||
}
|
||||
vk::UnmapMemory(m_dev, m_srgbRampTextureMem);
|
||||
ThrowIfFailed(vk::BindBufferMemory(m_dev, m_srgbRampTextureBuf, m_srgbRampTextureMem, 0));
|
||||
|
||||
VkImageCreateInfo texCreateInfo = {};
|
||||
texCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
texCreateInfo.imageType = VK_IMAGE_TYPE_1D;
|
||||
texCreateInfo.format = VK_FORMAT_R32_SFLOAT;
|
||||
texCreateInfo.mipLevels = 1;
|
||||
texCreateInfo.arrayLayers = 1;
|
||||
texCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
texCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
texCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||
texCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
texCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
texCreateInfo.extent = { 256, 1, 1 };
|
||||
texCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||
ThrowIfFailed(vk::CreateImage(m_dev, &texCreateInfo, nullptr, &m_srgbRampTexture));
|
||||
|
||||
memAlloc.allocationSize = 256;
|
||||
memTypeBits = ~0;
|
||||
vk::GetImageMemoryRequirements(m_dev, m_srgbRampTexture, &memReqs);
|
||||
memTypeBits &= memReqs.memoryTypeBits;
|
||||
ThrowIfFalse(MemoryTypeFromProperties(this, memTypeBits, 0,
|
||||
&memAlloc.memoryTypeIndex));
|
||||
ThrowIfFailed(vk::AllocateMemory(m_dev, &memAlloc, nullptr, &m_srgbRampTextureMem));
|
||||
//ThrowIfFailed(vk::MapMemory(m_dev, m_srgbRampTextureMem, 0, memAlloc.allocationSize, 0, reinterpret_cast<void**>(&mappedData)));
|
||||
//memset(mappedData, 0, memAlloc.allocationSize);
|
||||
//vk::UnmapMemory(m_dev, m_srgbRampTextureMem);
|
||||
ThrowIfFailed(vk::BindImageMemory(m_dev, m_srgbRampTexture, m_srgbRampTextureMem, 0));
|
||||
|
||||
/* Put the copy command into the command buffer */
|
||||
VkBufferImageCopy copyRegion = {};
|
||||
copyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
copyRegion.imageSubresource.mipLevel = 0;
|
||||
copyRegion.imageSubresource.baseArrayLayer = 0;
|
||||
copyRegion.imageSubresource.layerCount = 1;
|
||||
copyRegion.imageExtent.width = 256;
|
||||
copyRegion.imageExtent.height = 1;
|
||||
copyRegion.imageExtent.depth = 1;
|
||||
copyRegion.bufferOffset = 0;
|
||||
|
||||
SetImageLayout(m_loadCmdBuf, m_srgbRampTexture, VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, 1);
|
||||
|
||||
vk::CmdCopyBufferToImage(m_loadCmdBuf,
|
||||
m_srgbRampTextureBuf,
|
||||
m_srgbRampTexture,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
1,
|
||||
©Region);
|
||||
|
||||
SetImageLayout(m_loadCmdBuf, m_srgbRampTexture, VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 1, 1);
|
||||
|
||||
VkImageViewCreateInfo viewInfo = {};
|
||||
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
viewInfo.pNext = nullptr;
|
||||
viewInfo.image = m_srgbRampTexture;
|
||||
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_1D;
|
||||
viewInfo.format = VK_FORMAT_R32_SFLOAT;
|
||||
viewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
|
||||
viewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
|
||||
viewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
|
||||
viewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
|
||||
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
viewInfo.subresourceRange.baseMipLevel = 0;
|
||||
viewInfo.subresourceRange.levelCount = 1;
|
||||
viewInfo.subresourceRange.baseArrayLayer = 0;
|
||||
viewInfo.subresourceRange.layerCount = 1;
|
||||
ThrowIfFailed(vk::CreateImageView(m_dev, &viewInfo, nullptr, &m_srgbRampTextureView));
|
||||
|
||||
VkDescriptorSetLayoutBinding textureBindings[2] = {};
|
||||
textureBindings[0].binding = 0;
|
||||
textureBindings[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
textureBindings[0].descriptorCount = 1;
|
||||
textureBindings[0].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
textureBindings[0].pImmutableSamplers = &m_linearSampler;
|
||||
|
||||
textureBindings[1].binding = 1;
|
||||
textureBindings[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
textureBindings[1].descriptorCount = 1;
|
||||
textureBindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
textureBindings[1].pImmutableSamplers = &m_linearSampler;
|
||||
|
||||
VkDescriptorSetLayoutCreateInfo descriptorLayout = {};
|
||||
descriptorLayout.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||
descriptorLayout.pNext = nullptr;
|
||||
descriptorLayout.bindingCount = 2;
|
||||
descriptorLayout.pBindings = textureBindings;
|
||||
|
||||
ThrowIfFailed(vk::CreateDescriptorSetLayout(m_dev, &descriptorLayout, nullptr,
|
||||
&m_srgbDescSetLayout));
|
||||
|
||||
VkDescriptorPoolSize poolSizes[1] = {};
|
||||
VkDescriptorPoolCreateInfo descriptorPoolInfo = {};
|
||||
descriptorPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
||||
descriptorPoolInfo.pNext = nullptr;
|
||||
descriptorPoolInfo.maxSets = 1;
|
||||
descriptorPoolInfo.poolSizeCount = 1;
|
||||
descriptorPoolInfo.pPoolSizes = poolSizes;
|
||||
|
||||
poolSizes[0].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
poolSizes[0].descriptorCount = 2;
|
||||
ThrowIfFailed(vk::CreateDescriptorPool(m_dev, &descriptorPoolInfo, nullptr, &m_srgbDescPool));
|
||||
|
||||
VkDescriptorSetAllocateInfo descAllocInfo;
|
||||
descAllocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
||||
descAllocInfo.pNext = nullptr;
|
||||
descAllocInfo.descriptorPool = m_srgbDescPool;
|
||||
descAllocInfo.descriptorSetCount = 1;
|
||||
descAllocInfo.pSetLayouts = &m_srgbDescSetLayout;
|
||||
ThrowIfFailed(vk::AllocateDescriptorSets(m_dev, &descAllocInfo, &m_srgbDescSet));
|
||||
|
||||
VkDescriptorImageInfo imageInfo = {};
|
||||
imageInfo.sampler = m_linearSampler;
|
||||
imageInfo.imageView = m_srgbRampTextureView;
|
||||
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
|
||||
VkWriteDescriptorSet writes[1] = {};
|
||||
writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
writes[0].pNext = nullptr;
|
||||
writes[0].dstSet = m_srgbDescSet;
|
||||
writes[0].descriptorCount = 1;
|
||||
writes[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
writes[0].pImageInfo = &imageInfo;
|
||||
writes[0].dstArrayElement = 0;
|
||||
writes[0].dstBinding = 1;
|
||||
vk::UpdateDescriptorSets(m_dev, 1, writes, 0, nullptr);
|
||||
|
||||
VkPipelineLayoutCreateInfo pipelineLayout = {};
|
||||
pipelineLayout.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||
pipelineLayout.setLayoutCount = 1;
|
||||
pipelineLayout.pSetLayouts = &m_srgbDescSetLayout;
|
||||
ThrowIfFailed(vk::CreatePipelineLayout(m_dev, &pipelineLayout, nullptr, &m_srgbPipelinelayout));
|
||||
|
||||
VkAttachmentDescription attachments[1] = {};
|
||||
|
||||
/* color attachment */
|
||||
attachments[0].format = format;
|
||||
attachments[0].samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
attachments[0].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
attachments[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
VkAttachmentReference colorAttachmentRef = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
|
||||
|
||||
/* render subpass */
|
||||
VkSubpassDescription subpass = {};
|
||||
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||
subpass.colorAttachmentCount = 1;
|
||||
subpass.pColorAttachments = &colorAttachmentRef;
|
||||
subpass.pDepthStencilAttachment = nullptr;
|
||||
|
||||
/* render pass */
|
||||
VkRenderPassCreateInfo renderPass = {};
|
||||
renderPass.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||
renderPass.attachmentCount = 1;
|
||||
renderPass.pAttachments = attachments;
|
||||
renderPass.subpassCount = 1;
|
||||
renderPass.pSubpasses = &subpass;
|
||||
ThrowIfFailed(vk::CreateRenderPass(m_dev, &renderPass, nullptr, &m_srgbPass));
|
||||
|
||||
/* pipeline cache */
|
||||
VkPipelineCacheCreateInfo cacheDataInfo = {};
|
||||
cacheDataInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
|
||||
ThrowIfFailed(vk::CreatePipelineCache(m_dev, &cacheDataInfo, nullptr, &m_srgbPipelineCache));
|
||||
|
||||
/* shaders */
|
||||
const EShMessages messages = EShMessages(EShMsgSpvRules | EShMsgVulkanRules);
|
||||
|
||||
glslang::TShader vs(EShLangVertex);
|
||||
vs.setStrings(&LinToSrgbVS, 1);
|
||||
if (!vs.parse(&glslang::DefaultTBuiltInResource, 110, false, messages))
|
||||
{
|
||||
Log.report(logvisor::Fatal, "unable to compile vertex shader\n%s", vs.getInfoLog());
|
||||
return;
|
||||
}
|
||||
|
||||
glslang::TShader fs(EShLangFragment);
|
||||
fs.setStrings(&LinToSrgbFS, 1);
|
||||
if (!fs.parse(&glslang::DefaultTBuiltInResource, 110, false, messages))
|
||||
{
|
||||
Log.report(logvisor::Fatal, "unable to compile fragment shader\n%s", fs.getInfoLog());
|
||||
return;
|
||||
}
|
||||
|
||||
glslang::TProgram prog;
|
||||
prog.addShader(&vs);
|
||||
prog.addShader(&fs);
|
||||
if (!prog.link(messages))
|
||||
{
|
||||
Log.report(logvisor::Fatal, "unable to link shader program\n%s", prog.getInfoLog());
|
||||
return;
|
||||
}
|
||||
std::vector<unsigned int> vertBlobOut;
|
||||
std::vector<unsigned int> fragBlobOut;
|
||||
glslang::GlslangToSpv(*prog.getIntermediate(EShLangVertex), vertBlobOut);
|
||||
glslang::GlslangToSpv(*prog.getIntermediate(EShLangFragment), fragBlobOut);
|
||||
|
||||
VkShaderModuleCreateInfo smCreateInfo = {};
|
||||
smCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||
smCreateInfo.pNext = nullptr;
|
||||
smCreateInfo.flags = 0;
|
||||
|
||||
smCreateInfo.codeSize = vertBlobOut.size() * sizeof(unsigned int);
|
||||
smCreateInfo.pCode = vertBlobOut.data();
|
||||
ThrowIfFailed(vk::CreateShaderModule(m_dev, &smCreateInfo, nullptr, &m_srgbVert));
|
||||
|
||||
smCreateInfo.codeSize = fragBlobOut.size() * sizeof(unsigned int);
|
||||
smCreateInfo.pCode = fragBlobOut.data();
|
||||
ThrowIfFailed(vk::CreateShaderModule(m_dev, &smCreateInfo, nullptr, &m_srgbFrag));
|
||||
|
||||
/* pipeline */
|
||||
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_srgbVert;
|
||||
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_srgbFrag;
|
||||
stages[1].pName = "main";
|
||||
stages[1].pSpecializationInfo = nullptr;
|
||||
|
||||
VkVertexInputBindingDescription vertexBinding = {};
|
||||
vertexBinding.binding = 0;
|
||||
vertexBinding.stride = 20;
|
||||
vertexBinding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
|
||||
|
||||
VkVertexInputAttributeDescription vertexAttrs[2] = {};
|
||||
vertexAttrs[0].location = 0;
|
||||
vertexAttrs[0].binding = 0;
|
||||
vertexAttrs[0].format = VK_FORMAT_R32G32B32_SFLOAT;
|
||||
vertexAttrs[0].offset = 0;
|
||||
|
||||
vertexAttrs[1].location = 1;
|
||||
vertexAttrs[1].binding = 0;
|
||||
vertexAttrs[1].format = VK_FORMAT_R32G32_SFLOAT;
|
||||
vertexAttrs[1].offset = 12;
|
||||
|
||||
VkPipelineVertexInputStateCreateInfo vertexInput = {};
|
||||
vertexInput.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
||||
vertexInput.pNext = nullptr;
|
||||
vertexInput.vertexBindingDescriptionCount = 1;
|
||||
vertexInput.pVertexBindingDescriptions = &vertexBinding;
|
||||
vertexInput.vertexAttributeDescriptionCount = 2;
|
||||
vertexInput.pVertexAttributeDescriptions = vertexAttrs;
|
||||
|
||||
VkPipelineInputAssemblyStateCreateInfo assemblyInfo = {};
|
||||
assemblyInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
||||
assemblyInfo.pNext = nullptr;
|
||||
assemblyInfo.flags = 0;
|
||||
assemblyInfo.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
|
||||
assemblyInfo.primitiveRestartEnable = VK_FALSE;
|
||||
|
||||
VkViewport viewport = {};
|
||||
viewport.width = swapChainExtent.width;
|
||||
viewport.height = swapChainExtent.height;
|
||||
viewport.maxDepth = 1.f;
|
||||
|
||||
VkRect2D scissor = {};
|
||||
scissor.extent = swapChainExtent;
|
||||
|
||||
VkPipelineViewportStateCreateInfo viewportInfo = {};
|
||||
viewportInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
||||
viewportInfo.pNext = nullptr;
|
||||
viewportInfo.flags = 0;
|
||||
viewportInfo.viewportCount = 1;
|
||||
viewportInfo.pViewports = &viewport;
|
||||
viewportInfo.scissorCount = 1;
|
||||
viewportInfo.pScissors = &scissor;
|
||||
|
||||
VkPipelineRasterizationStateCreateInfo rasterizationInfo = {};
|
||||
rasterizationInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
||||
rasterizationInfo.pNext = nullptr;
|
||||
rasterizationInfo.flags = 0;
|
||||
rasterizationInfo.depthClampEnable = VK_TRUE;
|
||||
rasterizationInfo.rasterizerDiscardEnable = VK_FALSE;
|
||||
rasterizationInfo.polygonMode = VK_POLYGON_MODE_FILL;
|
||||
rasterizationInfo.cullMode = VK_CULL_MODE_NONE;
|
||||
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 = VK_FALSE;
|
||||
depthStencilInfo.depthWriteEnable = VK_FALSE;
|
||||
depthStencilInfo.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
|
||||
depthStencilInfo.front.compareOp = VK_COMPARE_OP_ALWAYS;
|
||||
depthStencilInfo.back.compareOp = VK_COMPARE_OP_ALWAYS;
|
||||
|
||||
VkPipelineColorBlendAttachmentState colorAttachment = {};
|
||||
colorAttachment.blendEnable = 0;
|
||||
colorAttachment.colorWriteMask = 0xf;
|
||||
|
||||
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 = &vertexInput;
|
||||
pipelineCreateInfo.pInputAssemblyState = &assemblyInfo;
|
||||
pipelineCreateInfo.pViewportState = &viewportInfo;
|
||||
pipelineCreateInfo.pRasterizationState = &rasterizationInfo;
|
||||
pipelineCreateInfo.pMultisampleState = &multisampleInfo;
|
||||
pipelineCreateInfo.pDepthStencilState = &depthStencilInfo;
|
||||
pipelineCreateInfo.pColorBlendState = &colorBlendInfo;
|
||||
pipelineCreateInfo.pDynamicState = nullptr;
|
||||
pipelineCreateInfo.layout = m_srgbPipelinelayout;
|
||||
pipelineCreateInfo.renderPass = m_srgbPass;
|
||||
|
||||
ThrowIfFailed(vk::CreateGraphicsPipelines(m_dev, m_srgbPipelineCache, 1, &pipelineCreateInfo,
|
||||
nullptr, &m_srgbPipeline));
|
||||
#endif
|
||||
/* framebuffers */
|
||||
sc.m_bufs.resize(swapchainImageCount);
|
||||
for (uint32_t i=0 ; i<swapchainImageCount ; ++i)
|
||||
{
|
||||
Window::SwapChain::Buffer& buf = sc.m_bufs[i];
|
||||
buf.m_image = swapchainImages[i];
|
||||
#if SRGB_HACK
|
||||
|
||||
VkImageViewCreateInfo viewInfo = {};
|
||||
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
viewInfo.pNext = nullptr;
|
||||
viewInfo.image = buf.m_image;
|
||||
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
viewInfo.format = format;
|
||||
viewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
|
||||
viewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
|
||||
viewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
|
||||
viewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
|
||||
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
viewInfo.subresourceRange.baseMipLevel = 0;
|
||||
viewInfo.subresourceRange.levelCount = 1;
|
||||
viewInfo.subresourceRange.baseArrayLayer = 0;
|
||||
viewInfo.subresourceRange.layerCount = 1;
|
||||
ThrowIfFailed(vk::CreateImageView(m_dev, &viewInfo, nullptr, &buf.m_view));
|
||||
|
||||
VkFramebufferCreateInfo fbCreateInfo = {};
|
||||
fbCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||
fbCreateInfo.pNext = nullptr;
|
||||
fbCreateInfo.renderPass = m_srgbPass;
|
||||
fbCreateInfo.attachmentCount = 1;
|
||||
fbCreateInfo.width = swapChainExtent.width;
|
||||
fbCreateInfo.height = swapChainExtent.height;
|
||||
fbCreateInfo.layers = 1;
|
||||
VkImageView attachments[1] = {buf.m_view};
|
||||
fbCreateInfo.pAttachments = attachments;
|
||||
ThrowIfFailed(vk::CreateFramebuffer(m_dev, &fbCreateInfo, nullptr, &buf.m_framebuffer));
|
||||
#endif
|
||||
}
|
||||
|
||||
free(swapchainImages);
|
||||
}
|
||||
|
||||
|
||||
void VulkanContext::resizeSwapChain(VulkanContext::Window& windowCtx, VkSurfaceKHR surface, VkFormat format)
|
||||
void VulkanContext::resizeSwapChain(VulkanContext::Window& windowCtx, VkSurfaceKHR surface, VkFormat format, VkColorSpaceKHR colorspace)
|
||||
{
|
||||
VkSurfaceCapabilitiesKHR surfCapabilities;
|
||||
ThrowIfFailed(vk::GetPhysicalDeviceSurfaceCapabilitiesKHR(m_gpus[0], surface, &surfCapabilities));
|
||||
|
@ -576,8 +1083,12 @@ void VulkanContext::resizeSwapChain(VulkanContext::Window& windowCtx, VkSurfaceK
|
|||
swapChainInfo.presentMode = swapchainPresentMode;
|
||||
swapChainInfo.oldSwapchain = nullptr;
|
||||
swapChainInfo.clipped = true;
|
||||
swapChainInfo.imageColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
|
||||
swapChainInfo.imageColorSpace = colorspace;
|
||||
#if SRGB_HACK
|
||||
swapChainInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
#else
|
||||
swapChainInfo.imageUsage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||
#endif
|
||||
swapChainInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
swapChainInfo.queueFamilyIndexCount = 0;
|
||||
swapChainInfo.pQueueFamilyIndices = nullptr;
|
||||
|
@ -593,9 +1104,173 @@ void VulkanContext::resizeSwapChain(VulkanContext::Window& windowCtx, VkSurfaceK
|
|||
VkImage* swapchainImages = (VkImage*)malloc(swapchainImageCount * sizeof(VkImage));
|
||||
ThrowIfFailed(vk::GetSwapchainImagesKHR(m_dev, sc.m_swapChain, &swapchainImageCount, swapchainImages));
|
||||
|
||||
#if SRGB_HACK
|
||||
/* recreate srgb pipeline */
|
||||
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_srgbVert;
|
||||
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_srgbFrag;
|
||||
stages[1].pName = "main";
|
||||
stages[1].pSpecializationInfo = nullptr;
|
||||
|
||||
VkVertexInputBindingDescription vertexBinding = {};
|
||||
vertexBinding.binding = 0;
|
||||
vertexBinding.stride = 20;
|
||||
vertexBinding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
|
||||
|
||||
VkVertexInputAttributeDescription vertexAttrs[2] = {};
|
||||
vertexAttrs[0].location = 0;
|
||||
vertexAttrs[0].binding = 0;
|
||||
vertexAttrs[0].format = VK_FORMAT_R32G32B32_SFLOAT;
|
||||
vertexAttrs[0].offset = 0;
|
||||
|
||||
vertexAttrs[1].location = 1;
|
||||
vertexAttrs[1].binding = 0;
|
||||
vertexAttrs[1].format = VK_FORMAT_R32G32_SFLOAT;
|
||||
vertexAttrs[1].offset = 12;
|
||||
|
||||
VkPipelineVertexInputStateCreateInfo vertexInput = {};
|
||||
vertexInput.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
||||
vertexInput.pNext = nullptr;
|
||||
vertexInput.vertexBindingDescriptionCount = 1;
|
||||
vertexInput.pVertexBindingDescriptions = &vertexBinding;
|
||||
vertexInput.vertexAttributeDescriptionCount = 2;
|
||||
vertexInput.pVertexAttributeDescriptions = vertexAttrs;
|
||||
|
||||
VkPipelineInputAssemblyStateCreateInfo assemblyInfo = {};
|
||||
assemblyInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
||||
assemblyInfo.pNext = nullptr;
|
||||
assemblyInfo.flags = 0;
|
||||
assemblyInfo.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
|
||||
assemblyInfo.primitiveRestartEnable = VK_FALSE;
|
||||
|
||||
VkViewport viewport = {};
|
||||
viewport.width = swapChainExtent.width;
|
||||
viewport.height = swapChainExtent.height;
|
||||
viewport.maxDepth = 1.f;
|
||||
|
||||
VkPipelineViewportStateCreateInfo viewportInfo = {};
|
||||
viewportInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
||||
viewportInfo.pNext = nullptr;
|
||||
viewportInfo.flags = 0;
|
||||
viewportInfo.viewportCount = 1;
|
||||
viewportInfo.pViewports = &viewport;
|
||||
viewportInfo.scissorCount = 0;
|
||||
viewportInfo.pScissors = nullptr;
|
||||
|
||||
VkPipelineRasterizationStateCreateInfo rasterizationInfo = {};
|
||||
rasterizationInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
||||
rasterizationInfo.pNext = nullptr;
|
||||
rasterizationInfo.flags = 0;
|
||||
rasterizationInfo.depthClampEnable = VK_TRUE;
|
||||
rasterizationInfo.rasterizerDiscardEnable = VK_FALSE;
|
||||
rasterizationInfo.polygonMode = VK_POLYGON_MODE_FILL;
|
||||
rasterizationInfo.cullMode = VK_CULL_MODE_NONE;
|
||||
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 = VK_FALSE;
|
||||
depthStencilInfo.depthWriteEnable = VK_FALSE;
|
||||
depthStencilInfo.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
|
||||
depthStencilInfo.front.compareOp = VK_COMPARE_OP_ALWAYS;
|
||||
depthStencilInfo.back.compareOp = VK_COMPARE_OP_ALWAYS;
|
||||
|
||||
VkPipelineColorBlendAttachmentState colorAttachment = {};
|
||||
colorAttachment.blendEnable = 0;
|
||||
colorAttachment.colorWriteMask = 0xf;
|
||||
|
||||
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 = &vertexInput;
|
||||
pipelineCreateInfo.pInputAssemblyState = &assemblyInfo;
|
||||
pipelineCreateInfo.pViewportState = &viewportInfo;
|
||||
pipelineCreateInfo.pRasterizationState = &rasterizationInfo;
|
||||
pipelineCreateInfo.pMultisampleState = &multisampleInfo;
|
||||
pipelineCreateInfo.pDepthStencilState = &depthStencilInfo;
|
||||
pipelineCreateInfo.pColorBlendState = &colorBlendInfo;
|
||||
pipelineCreateInfo.pDynamicState = nullptr;
|
||||
pipelineCreateInfo.layout = m_srgbPipelinelayout;
|
||||
pipelineCreateInfo.renderPass = m_srgbPass;
|
||||
|
||||
if (m_srgbPipelinePreResize)
|
||||
vk::DestroyPipeline(m_dev, m_srgbPipelinePreResize, nullptr);
|
||||
ThrowIfFailed(vk::CreateGraphicsPipelines(m_dev, m_srgbPipelineCache, 1, &pipelineCreateInfo,
|
||||
nullptr, &m_srgbPipelinePreResize));
|
||||
#endif
|
||||
|
||||
/* framebuffers */
|
||||
sc.m_bufs.resize(swapchainImageCount);
|
||||
for (uint32_t i=0 ; i<swapchainImageCount ; ++i)
|
||||
sc.m_bufs[i].m_image = swapchainImages[i];
|
||||
{
|
||||
Window::SwapChain::Buffer& buf = sc.m_bufs[i];
|
||||
buf.m_image = swapchainImages[i];
|
||||
#if SRGB_HACK
|
||||
|
||||
VkImageViewCreateInfo viewInfo = {};
|
||||
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
viewInfo.pNext = nullptr;
|
||||
viewInfo.image = buf.m_image;
|
||||
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
viewInfo.format = format;
|
||||
viewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
|
||||
viewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
|
||||
viewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
|
||||
viewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
|
||||
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
viewInfo.subresourceRange.baseMipLevel = 0;
|
||||
viewInfo.subresourceRange.levelCount = 1;
|
||||
viewInfo.subresourceRange.baseArrayLayer = 0;
|
||||
viewInfo.subresourceRange.layerCount = 1;
|
||||
ThrowIfFailed(vk::CreateImageView(m_dev, &viewInfo, nullptr, &buf.m_view));
|
||||
|
||||
VkFramebufferCreateInfo fbCreateInfo = {};
|
||||
fbCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||
fbCreateInfo.pNext = nullptr;
|
||||
fbCreateInfo.renderPass = m_srgbPass;
|
||||
fbCreateInfo.attachmentCount = 1;
|
||||
fbCreateInfo.width = swapChainExtent.width;
|
||||
fbCreateInfo.height = swapChainExtent.height;
|
||||
fbCreateInfo.layers = 1;
|
||||
VkImageView attachments[1] = {buf.m_view};
|
||||
fbCreateInfo.pAttachments = attachments;
|
||||
ThrowIfFailed(vk::CreateFramebuffer(m_dev, &fbCreateInfo, nullptr, &buf.m_framebuffer));
|
||||
#endif
|
||||
}
|
||||
|
||||
free(swapchainImages);
|
||||
}
|
||||
|
||||
|
@ -613,6 +1288,7 @@ struct VulkanData : IGraphicsData
|
|||
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;
|
||||
VulkanData(VulkanContext* ctx) : m_ctx(ctx) {}
|
||||
~VulkanData()
|
||||
{
|
||||
|
@ -1739,8 +2415,8 @@ class VulkanShaderPipeline : public IShaderPipeline
|
|||
colorAttachment.srcColorBlendFactor = BLEND_FACTOR_TABLE[int(srcFac)];
|
||||
colorAttachment.dstColorBlendFactor = BLEND_FACTOR_TABLE[int(dstFac)];
|
||||
colorAttachment.colorBlendOp = VK_BLEND_OP_ADD;
|
||||
colorAttachment.srcAlphaBlendFactor = BLEND_FACTOR_TABLE[int(srcFac)];
|
||||
colorAttachment.dstAlphaBlendFactor = BLEND_FACTOR_TABLE[int(dstFac)];
|
||||
colorAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
|
||||
colorAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
|
||||
colorAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
|
||||
colorAttachment.colorWriteMask = 0xf;
|
||||
|
||||
|
@ -2358,12 +3034,22 @@ struct VulkanCommandQueue : IGraphicsCommandQueue
|
|||
ThrowIfFailed(vk::AcquireNextImageKHR(m_ctx->m_dev, sc.m_swapChain, UINT64_MAX,
|
||||
m_swapChainReadySem, nullptr, &sc.m_backBuf));
|
||||
VulkanContext::Window::SwapChain::Buffer& dest = sc.m_bufs[sc.m_backBuf];
|
||||
#if SRGB_HACK
|
||||
SetImageLayout(cmdBuf, dest.m_image, VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
dest.m_layout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, 1);
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1, 1);
|
||||
#else
|
||||
SetImageLayout(cmdBuf, dest.m_image, VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, 1);
|
||||
#endif
|
||||
|
||||
if (m_resolveDispSource == m_boundTarget)
|
||||
#if SRGB_HACK
|
||||
SetImageLayout(cmdBuf, csource->m_colorTex, VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 1, 1);
|
||||
#else
|
||||
SetImageLayout(cmdBuf, csource->m_colorTex, VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 1, 1);
|
||||
#endif
|
||||
|
||||
if (csource->m_samples > 1)
|
||||
{
|
||||
|
@ -2386,7 +3072,44 @@ struct VulkanCommandQueue : IGraphicsCommandQueue
|
|||
}
|
||||
else
|
||||
{
|
||||
if (sc.m_format == VK_FORMAT_R8G8B8A8_UNORM)
|
||||
#if SRGB_HACK
|
||||
VkDescriptorImageInfo imageInfo = {};
|
||||
imageInfo.sampler = m_ctx->m_linearSampler;
|
||||
imageInfo.imageView = csource->m_colorView;
|
||||
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
|
||||
VkWriteDescriptorSet writes[1] = {};
|
||||
writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
writes[0].pNext = nullptr;
|
||||
writes[0].dstSet = m_ctx->m_srgbDescSet;
|
||||
writes[0].descriptorCount = 1;
|
||||
writes[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
writes[0].pImageInfo = &imageInfo;
|
||||
writes[0].dstArrayElement = 0;
|
||||
writes[0].dstBinding = 0;
|
||||
vk::UpdateDescriptorSets(m_ctx->m_dev, 1, writes, 0, nullptr);
|
||||
|
||||
VkRenderPassBeginInfo passInfo = {};
|
||||
passInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||
passInfo.pNext = nullptr;
|
||||
passInfo.renderPass = m_ctx->m_srgbPass;
|
||||
passInfo.framebuffer = dest.m_framebuffer;
|
||||
passInfo.renderArea.offset.x = 0;
|
||||
passInfo.renderArea.offset.y = 0;
|
||||
passInfo.renderArea.extent.width = csource->m_width;
|
||||
passInfo.renderArea.extent.height = csource->m_height;
|
||||
passInfo.clearValueCount = 0;
|
||||
passInfo.pClearValues = nullptr;
|
||||
vk::CmdBeginRenderPass(cmdBuf, &passInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||
VkDeviceSize offset = 0;
|
||||
vk::CmdBindPipeline(cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, m_ctx->m_srgbPipeline);
|
||||
vk::CmdBindDescriptorSets(cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, m_ctx->m_srgbPipelinelayout, 0, 1, &m_ctx->m_srgbDescSet, 0, nullptr);
|
||||
vk::CmdBindVertexBuffers(cmdBuf, 0, 1, &m_ctx->m_srgbVertBuf, &offset);
|
||||
vk::CmdDraw(cmdBuf, 4, 1, 0, 0);
|
||||
vk::CmdEndRenderPass(cmdBuf);
|
||||
|
||||
#else
|
||||
if (sc.m_format == VK_FORMAT_B8G8R8A8_SRGB)
|
||||
{
|
||||
VkImageCopy copyInfo = {};
|
||||
copyInfo.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
|
@ -2421,15 +3144,26 @@ struct VulkanCommandQueue : IGraphicsCommandQueue
|
|||
dest.m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
1, &blitInfo, VK_FILTER_NEAREST);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if SRGB_HACK
|
||||
SetImageLayout(cmdBuf, dest.m_image, VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, 1, 1);
|
||||
#else
|
||||
SetImageLayout(cmdBuf, dest.m_image, VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, 1, 1);
|
||||
#endif
|
||||
dest.m_layout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
|
||||
if (m_resolveDispSource == m_boundTarget)
|
||||
#if SRGB_HACK
|
||||
SetImageLayout(cmdBuf, csource->m_colorTex, VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1, 1);
|
||||
#else
|
||||
SetImageLayout(cmdBuf, csource->m_colorTex, VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1, 1);
|
||||
#endif
|
||||
|
||||
m_resolveDispSource = nullptr;
|
||||
return true;
|
||||
|
@ -2712,10 +3446,8 @@ void VulkanTextureD::unmap()
|
|||
|
||||
void VulkanDataFactory::destroyData(IGraphicsData* d)
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_committedMutex);
|
||||
VulkanData* data = static_cast<VulkanData*>(d);
|
||||
m_committedData.erase(data);
|
||||
delete data;
|
||||
data->m_dead = true;
|
||||
}
|
||||
|
||||
void VulkanDataFactory::destroyAllData()
|
||||
|
@ -2729,17 +3461,6 @@ void VulkanDataFactory::destroyAllData()
|
|||
VulkanDataFactory::VulkanDataFactory(IGraphicsContext* parent, VulkanContext* ctx, uint32_t drawSamples)
|
||||
: m_parent(parent), m_ctx(ctx), m_drawSamples(drawSamples)
|
||||
{
|
||||
VkSamplerCreateInfo samplerInfo = {};
|
||||
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||
samplerInfo.pNext = nullptr;
|
||||
samplerInfo.magFilter = VK_FILTER_LINEAR;
|
||||
samplerInfo.minFilter = VK_FILTER_LINEAR;
|
||||
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
ThrowIfFailed(vk::CreateSampler(ctx->m_dev, &samplerInfo, nullptr, &ctx->m_linearSampler));
|
||||
|
||||
VkDescriptorSetLayoutBinding layoutBindings[BOO_GLSL_MAX_UNIFORM_COUNT + BOO_GLSL_MAX_TEXTURE_COUNT];
|
||||
for (int i=0 ; i<BOO_GLSL_MAX_UNIFORM_COUNT ; ++i)
|
||||
{
|
||||
|
@ -3147,6 +3868,20 @@ void VulkanCommandQueue::execute()
|
|||
return;
|
||||
}
|
||||
|
||||
/* Clear dead data */
|
||||
datalk.lock();
|
||||
for (auto it = gfxF->m_committedData.begin() ; it != gfxF->m_committedData.end() ;)
|
||||
{
|
||||
if ((*it)->m_dead)
|
||||
{
|
||||
delete *it;
|
||||
it = gfxF->m_committedData.erase(it);
|
||||
continue;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
datalk.unlock();
|
||||
|
||||
/* Perform texture resizes */
|
||||
if (m_texResizes.size())
|
||||
{
|
||||
|
@ -3167,6 +3902,14 @@ void VulkanCommandQueue::execute()
|
|||
VulkanContext::Window::SwapChain& thisSc = m_windowCtx->m_swapChains[m_windowCtx->m_activeSwapChain];
|
||||
thisSc.destroy(m_ctx->m_dev);
|
||||
m_windowCtx->m_activeSwapChain ^= 1;
|
||||
#if SRGB_HACK
|
||||
if (m_ctx->m_srgbPipelinePreResize)
|
||||
{
|
||||
vk::DestroyPipeline(m_ctx->m_dev, m_ctx->m_srgbPipeline, nullptr);
|
||||
m_ctx->m_srgbPipeline = m_ctx->m_srgbPipelinePreResize;
|
||||
m_ctx->m_srgbPipelinePreResize = VK_NULL_HANDLE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -598,6 +598,7 @@ struct GraphicsContextXlibVulkan : GraphicsContextXlib
|
|||
VulkanContext* m_ctx;
|
||||
VkSurfaceKHR m_surface = VK_NULL_HANDLE;
|
||||
VkFormat m_format;
|
||||
VkColorSpaceKHR m_colorspace;
|
||||
|
||||
GLXFBConfig m_fbconfig = 0;
|
||||
int m_visualid = 0;
|
||||
|
@ -623,63 +624,9 @@ public:
|
|||
: GraphicsContextXlib(EGraphicsAPI::Vulkan, EPixelFormat::RGBA8, parentWindow, display, drawSamples),
|
||||
m_xcbConn(xcbConn), m_ctx(ctx)
|
||||
{
|
||||
/* Query framebuffer configurations */
|
||||
GLXFBConfig* fbConfigs = nullptr;
|
||||
int numFBConfigs = 0;
|
||||
fbConfigs = glXGetFBConfigs(display, defaultScreen, &numFBConfigs);
|
||||
if (!fbConfigs || numFBConfigs == 0)
|
||||
{
|
||||
Log.report(logvisor::Fatal, "glXGetFBConfigs failed");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i=0 ; i<numFBConfigs ; ++i)
|
||||
{
|
||||
GLXFBConfig config = fbConfigs[i];
|
||||
int visualId, depthSize, colorSize, doubleBuffer;
|
||||
glXGetFBConfigAttrib(display, config, GLX_VISUAL_ID, &visualId);
|
||||
glXGetFBConfigAttrib(display, config, GLX_DEPTH_SIZE, &depthSize);
|
||||
glXGetFBConfigAttrib(display, config, GLX_BUFFER_SIZE, &colorSize);
|
||||
glXGetFBConfigAttrib(display, config, GLX_DOUBLEBUFFER, &doubleBuffer);
|
||||
|
||||
/* Double-buffer only */
|
||||
if (!doubleBuffer)
|
||||
continue;
|
||||
|
||||
if (m_pf == EPixelFormat::RGBA8 && colorSize >= 32)
|
||||
{
|
||||
m_fbconfig = config;
|
||||
m_visualid = visualId;
|
||||
break;
|
||||
}
|
||||
else if (m_pf == EPixelFormat::RGBA8_Z24 && colorSize >= 32 && depthSize >= 24)
|
||||
{
|
||||
m_fbconfig = config;
|
||||
m_visualid = visualId;
|
||||
break;
|
||||
}
|
||||
else if (m_pf == EPixelFormat::RGBAF32 && colorSize >= 128)
|
||||
{
|
||||
m_fbconfig = config;
|
||||
m_visualid = visualId;
|
||||
break;
|
||||
}
|
||||
else if (m_pf == EPixelFormat::RGBAF32_Z24 && colorSize >= 128 && depthSize >= 24)
|
||||
{
|
||||
m_fbconfig = config;
|
||||
m_visualid = visualId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
XFree(fbConfigs);
|
||||
|
||||
if (!m_fbconfig)
|
||||
{
|
||||
Log.report(logvisor::Fatal, "unable to find suitable pixel format");
|
||||
return;
|
||||
}
|
||||
|
||||
visualIdOut = m_visualid;
|
||||
Screen* screen = ScreenOfDisplay(display, defaultScreen);
|
||||
m_visualid = screen->root_visual->visualid;
|
||||
visualIdOut = screen->root_visual->visualid;
|
||||
}
|
||||
|
||||
void destroy()
|
||||
|
@ -703,7 +650,7 @@ public:
|
|||
void resized(SWindowRect& rect)
|
||||
{
|
||||
if (m_windowCtx)
|
||||
m_ctx->resizeSwapChain(*m_windowCtx, m_surface, m_format);
|
||||
m_ctx->resizeSwapChain(*m_windowCtx, m_surface, m_format, m_colorspace);
|
||||
}
|
||||
|
||||
void _setCallback(IWindowCallback* cb)
|
||||
|
@ -816,11 +763,12 @@ public:
|
|||
m_format = VK_FORMAT_B8G8R8A8_UNORM;
|
||||
else
|
||||
m_format = surfFormats[0].format;
|
||||
m_colorspace = surfFormats[0].colorSpace;
|
||||
}
|
||||
else
|
||||
Log.report(logvisor::Fatal, "no surface formats available for Vulkan swapchain");
|
||||
|
||||
m_ctx->initSwapChain(*m_windowCtx, m_surface, m_format);
|
||||
m_ctx->initSwapChain(*m_windowCtx, m_surface, m_format, m_colorspace);
|
||||
|
||||
/* Spawn vsync thread */
|
||||
m_vsyncRunning = true;
|
||||
|
|
Loading…
Reference in New Issue