From 6de30424e3d03b3e51f622820bc0c7022e4e9e5e Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Tue, 23 Feb 2016 17:11:58 -1000 Subject: [PATCH] GLSL bindings and Vulkan bug fixes --- CMakeLists.txt | 1 + glslang | 2 +- include/boo/IApplication.hpp | 2 +- include/boo/graphicsdev/GL.hpp | 6 +- include/boo/graphicsdev/GLSLMacros.hpp | 45 +++ .../boo/graphicsdev/IGraphicsDataFactory.hpp | 2 +- include/boo/graphicsdev/Vulkan.hpp | 8 +- lib/graphicsdev/GL.cpp | 8 +- lib/graphicsdev/Vulkan.cpp | 275 ++++++++++++++---- lib/x11/ApplicationWayland.hpp | 2 +- lib/x11/ApplicationXlib.hpp | 10 +- lib/x11/WindowXlib.cpp | 29 +- test/main.cpp | 7 +- 13 files changed, 301 insertions(+), 96 deletions(-) create mode 100644 include/boo/graphicsdev/GLSLMacros.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 120bf89..944eeeb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,7 @@ list(APPEND PLAT_SRCS lib/graphicsdev/glew.c) list(APPEND PLAT_HDRS + include/boo/graphicsdev/GLSLMacros.hpp include/boo/graphicsdev/GL.hpp include/boo/graphicsdev/Vulkan.hpp) endif() diff --git a/glslang b/glslang index d5c11e0..c8720ad 160000 --- a/glslang +++ b/glslang @@ -1 +1 @@ -Subproject commit d5c11e053726b03917df6879ac3ae746ae0d99af +Subproject commit c8720ad209ba609f80a736dc777887c805b7b2f5 diff --git a/include/boo/IApplication.hpp b/include/boo/IApplication.hpp index 545924d..d704bf9 100644 --- a/include/boo/IApplication.hpp +++ b/include/boo/IApplication.hpp @@ -51,7 +51,7 @@ public: virtual const std::vector& getArgs() const=0; /* Constructors/initializers for sub-objects */ - virtual IWindow* newWindow(const SystemString& title)=0; + virtual IWindow* newWindow(const SystemString& title, uint32_t drawSamples)=0; }; diff --git a/include/boo/graphicsdev/GL.hpp b/include/boo/graphicsdev/GL.hpp index 7016879..adbb848 100644 --- a/include/boo/graphicsdev/GL.hpp +++ b/include/boo/graphicsdev/GL.hpp @@ -4,6 +4,7 @@ #include "IGraphicsDataFactory.hpp" #include "IGraphicsCommandQueue.hpp" #include "boo/IGraphicsContext.hpp" +#include "GLSLMacros.hpp" #include #include #include @@ -15,6 +16,7 @@ class GLDataFactory : public IGraphicsDataFactory { friend struct GLCommandQueue; IGraphicsContext* m_parent; + uint32_t m_drawSamples; static ThreadLocalPtr m_deferredData; std::unordered_set m_committedData; std::mutex m_committedMutex; @@ -22,7 +24,7 @@ class GLDataFactory : public IGraphicsDataFactory void destroyData(IGraphicsData*); void destroyAllData(); public: - GLDataFactory(IGraphicsContext* parent); + GLDataFactory(IGraphicsContext* parent, uint32_t drawSamples); ~GLDataFactory() {destroyAllData();} Platform platform() const {return Platform::OGL;} @@ -39,7 +41,7 @@ public: ITextureSA* newStaticArrayTexture(size_t width, size_t height, size_t layers, TextureFormat fmt, const void* data, size_t sz); ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt); - ITextureR* newRenderTexture(size_t width, size_t height, size_t samples); + ITextureR* newRenderTexture(size_t width, size_t height); bool bindingNeedsVertexFormat() const {return true;} IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements); diff --git a/include/boo/graphicsdev/GLSLMacros.hpp b/include/boo/graphicsdev/GLSLMacros.hpp new file mode 100644 index 0000000..9afd178 --- /dev/null +++ b/include/boo/graphicsdev/GLSLMacros.hpp @@ -0,0 +1,45 @@ +#ifndef GDEV_GLSLMACROS_HPP +#define GDEV_GLSLMACROS_HPP + +#define BOO_GLSL_MAX_UNIFORM_COUNT 8 +#define BOO_GLSL_MAX_TEXTURE_COUNT 8 + +#define BOO_GLSL_BINDING_HEAD \ +"#extension GL_ARB_shading_language_420pack: enable\n" \ +"#ifdef GL_ARB_shading_language_420pack\n" \ +"#define UBINDING0 layout(binding=0)\n" \ +"#define UBINDING1 layout(binding=1)\n" \ +"#define UBINDING2 layout(binding=2)\n" \ +"#define UBINDING3 layout(binding=3)\n" \ +"#define UBINDING4 layout(binding=4)\n" \ +"#define UBINDING5 layout(binding=5)\n" \ +"#define UBINDING6 layout(binding=6)\n" \ +"#define UBINDING7 layout(binding=7)\n" \ +"#define TBINDING0 layout(binding=8)\n" \ +"#define TBINDING1 layout(binding=9)\n" \ +"#define TBINDING2 layout(binding=10)\n" \ +"#define TBINDING3 layout(binding=11)\n" \ +"#define TBINDING4 layout(binding=12)\n" \ +"#define TBINDING5 layout(binding=13)\n" \ +"#define TBINDING6 layout(binding=14)\n" \ +"#define TBINDING7 layout(binding=15)\n" \ +"#else\n" \ +"#define UBINDING0\n" \ +"#define UBINDING1\n" \ +"#define UBINDING2\n" \ +"#define UBINDING3\n" \ +"#define UBINDING4\n" \ +"#define UBINDING5\n" \ +"#define UBINDING6\n" \ +"#define UBINDING7\n" \ +"#define TBINDING0\n" \ +"#define TBINDING1\n" \ +"#define TBINDING2\n" \ +"#define TBINDING3\n" \ +"#define TBINDING4\n" \ +"#define TBINDING5\n" \ +"#define TBINDING6\n" \ +"#define TBINDING7\n" \ +"#endif\n" + +#endif // GDEV_GLSLMACROS_HPP diff --git a/include/boo/graphicsdev/IGraphicsDataFactory.hpp b/include/boo/graphicsdev/IGraphicsDataFactory.hpp index 2eca90d..3af80ba 100644 --- a/include/boo/graphicsdev/IGraphicsDataFactory.hpp +++ b/include/boo/graphicsdev/IGraphicsDataFactory.hpp @@ -208,7 +208,7 @@ struct IGraphicsDataFactory virtual ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt)=0; virtual ITextureR* - newRenderTexture(size_t width, size_t height, size_t samples)=0; + newRenderTexture(size_t width, size_t height)=0; virtual bool bindingNeedsVertexFormat() const=0; virtual IVertexFormat* diff --git a/include/boo/graphicsdev/Vulkan.hpp b/include/boo/graphicsdev/Vulkan.hpp index 9371257..4d6e4a9 100644 --- a/include/boo/graphicsdev/Vulkan.hpp +++ b/include/boo/graphicsdev/Vulkan.hpp @@ -5,6 +5,7 @@ #include "IGraphicsDataFactory.hpp" #include "IGraphicsCommandQueue.hpp" #include "boo/IGraphicsContext.hpp" +#include "GLSLMacros.hpp" #include #include #include @@ -36,7 +37,7 @@ struct VulkanContext std::vector m_queueProps; VkQueue m_queue; VkDescriptorSetLayout m_descSetLayout; - VkPipelineLayout m_layout; + VkPipelineLayout m_pipelinelayout; VkRenderPass m_pass; VkCommandPool m_loadPool; VkCommandBuffer m_loadCmdBuf; @@ -72,6 +73,7 @@ class VulkanDataFactory : public IGraphicsDataFactory friend struct VulkanCommandQueue; IGraphicsContext* m_parent; VulkanContext* m_ctx; + uint32_t m_drawSamples; static ThreadLocalPtr m_deferredData; std::unordered_set m_committedData; std::mutex m_committedMutex; @@ -79,7 +81,7 @@ class VulkanDataFactory : public IGraphicsDataFactory void destroyData(IGraphicsData*); void destroyAllData(); public: - VulkanDataFactory(IGraphicsContext* parent, VulkanContext* ctx); + VulkanDataFactory(IGraphicsContext* parent, VulkanContext* ctx, uint32_t drawSamples); ~VulkanDataFactory() {destroyAllData();} Platform platform() const {return Platform::Vulkan;} @@ -95,7 +97,7 @@ public: ITextureSA* newStaticArrayTexture(size_t width, size_t height, size_t layers, TextureFormat fmt, const void* data, size_t sz); ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt); - ITextureR* newRenderTexture(size_t width, size_t height, size_t samples); + ITextureR* newRenderTexture(size_t width, size_t height); bool bindingNeedsVertexFormat() const {return true;} IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements); diff --git a/lib/graphicsdev/GL.cpp b/lib/graphicsdev/GL.cpp index f335f0a..54dffce 100644 --- a/lib/graphicsdev/GL.cpp +++ b/lib/graphicsdev/GL.cpp @@ -611,8 +611,8 @@ GLDataFactory::newShaderDataBinding(IShaderPipeline* pipeline, return retval; } -GLDataFactory::GLDataFactory(IGraphicsContext* parent) -: m_parent(parent) {} +GLDataFactory::GLDataFactory(IGraphicsContext* parent, uint32_t drawSamples) +: m_parent(parent), m_drawSamples(drawSamples) {} void GLDataFactory::reset() { @@ -1304,10 +1304,10 @@ GLTextureR::GLTextureR(GLCommandQueue* q, size_t width, size_t height, size_t sa GLTextureR::~GLTextureR() {glDeleteTextures(2, m_texs); m_q->delFBO(this);} ITextureR* -GLDataFactory::newRenderTexture(size_t width, size_t height, size_t samples) +GLDataFactory::newRenderTexture(size_t width, size_t height) { GLCommandQueue* q = static_cast(m_parent->getCommandQueue()); - GLTextureR* retval = new GLTextureR(q, width, height, samples); + GLTextureR* retval = new GLTextureR(q, width, height, m_drawSamples); q->resizeRenderTexture(retval, width, height); if (!m_deferredData.get()) m_deferredData.reset(new struct GLData()); diff --git a/lib/graphicsdev/Vulkan.cpp b/lib/graphicsdev/Vulkan.cpp index 82d5631..61a80ff 100644 --- a/lib/graphicsdev/Vulkan.cpp +++ b/lib/graphicsdev/Vulkan.cpp @@ -9,6 +9,8 @@ #include #include #include +#include +#include "boo/graphicsdev/GLSLMacros.hpp" #include @@ -16,10 +18,7 @@ #undef max #undef None -#define MAX_UNIFORM_COUNT 8 -#define MAX_TEXTURE_COUNT 8 - -static const TBuiltInResource DefaultBuiltInResource = +static TBuiltInResource DefaultBuiltInResource = { 32, 6, @@ -118,6 +117,101 @@ static const TBuiltInResource DefaultBuiltInResource = } }; +static void init_resources(TBuiltInResource &Resources) { + Resources.maxLights = 32; + Resources.maxClipPlanes = 6; + Resources.maxTextureUnits = 32; + Resources.maxTextureCoords = 32; + Resources.maxVertexAttribs = 64; + Resources.maxVertexUniformComponents = 4096; + Resources.maxVaryingFloats = 64; + Resources.maxVertexTextureImageUnits = 32; + Resources.maxCombinedTextureImageUnits = 80; + Resources.maxTextureImageUnits = 32; + Resources.maxFragmentUniformComponents = 4096; + Resources.maxDrawBuffers = 32; + Resources.maxVertexUniformVectors = 128; + Resources.maxVaryingVectors = 8; + Resources.maxFragmentUniformVectors = 16; + Resources.maxVertexOutputVectors = 16; + Resources.maxFragmentInputVectors = 15; + Resources.minProgramTexelOffset = -8; + Resources.maxProgramTexelOffset = 7; + Resources.maxClipDistances = 8; + Resources.maxComputeWorkGroupCountX = 65535; + Resources.maxComputeWorkGroupCountY = 65535; + Resources.maxComputeWorkGroupCountZ = 65535; + Resources.maxComputeWorkGroupSizeX = 1024; + Resources.maxComputeWorkGroupSizeY = 1024; + Resources.maxComputeWorkGroupSizeZ = 64; + Resources.maxComputeUniformComponents = 1024; + Resources.maxComputeTextureImageUnits = 16; + Resources.maxComputeImageUniforms = 8; + Resources.maxComputeAtomicCounters = 8; + Resources.maxComputeAtomicCounterBuffers = 1; + Resources.maxVaryingComponents = 60; + Resources.maxVertexOutputComponents = 64; + Resources.maxGeometryInputComponents = 64; + Resources.maxGeometryOutputComponents = 128; + Resources.maxFragmentInputComponents = 128; + Resources.maxImageUnits = 8; + Resources.maxCombinedImageUnitsAndFragmentOutputs = 8; + Resources.maxCombinedShaderOutputResources = 8; + Resources.maxImageSamples = 0; + Resources.maxVertexImageUniforms = 0; + Resources.maxTessControlImageUniforms = 0; + Resources.maxTessEvaluationImageUniforms = 0; + Resources.maxGeometryImageUniforms = 0; + Resources.maxFragmentImageUniforms = 8; + Resources.maxCombinedImageUniforms = 8; + Resources.maxGeometryTextureImageUnits = 16; + Resources.maxGeometryOutputVertices = 256; + Resources.maxGeometryTotalOutputComponents = 1024; + Resources.maxGeometryUniformComponents = 1024; + Resources.maxGeometryVaryingComponents = 64; + Resources.maxTessControlInputComponents = 128; + Resources.maxTessControlOutputComponents = 128; + Resources.maxTessControlTextureImageUnits = 16; + Resources.maxTessControlUniformComponents = 1024; + Resources.maxTessControlTotalOutputComponents = 4096; + Resources.maxTessEvaluationInputComponents = 128; + Resources.maxTessEvaluationOutputComponents = 128; + Resources.maxTessEvaluationTextureImageUnits = 16; + Resources.maxTessEvaluationUniformComponents = 1024; + Resources.maxTessPatchComponents = 120; + Resources.maxPatchVertices = 32; + Resources.maxTessGenLevel = 64; + Resources.maxViewports = 16; + Resources.maxVertexAtomicCounters = 0; + Resources.maxTessControlAtomicCounters = 0; + Resources.maxTessEvaluationAtomicCounters = 0; + Resources.maxGeometryAtomicCounters = 0; + Resources.maxFragmentAtomicCounters = 8; + Resources.maxCombinedAtomicCounters = 8; + Resources.maxAtomicCounterBindings = 1; + Resources.maxVertexAtomicCounterBuffers = 0; + Resources.maxTessControlAtomicCounterBuffers = 0; + Resources.maxTessEvaluationAtomicCounterBuffers = 0; + Resources.maxGeometryAtomicCounterBuffers = 0; + Resources.maxFragmentAtomicCounterBuffers = 1; + Resources.maxCombinedAtomicCounterBuffers = 1; + Resources.maxAtomicCounterBufferSize = 16384; + Resources.maxTransformFeedbackBuffers = 4; + Resources.maxTransformFeedbackInterleavedComponents = 64; + Resources.maxCullDistances = 8; + Resources.maxCombinedClipAndCullDistances = 8; + Resources.maxSamples = 4; + Resources.limits.nonInductiveForLoops = 1; + Resources.limits.whileLoops = 1; + Resources.limits.doWhileLoops = 1; + Resources.limits.generalUniformIndexing = 1; + Resources.limits.generalAttributeMatrixVectorIndexing = 1; + Resources.limits.generalVaryingIndexing = 1; + Resources.limits.generalSamplerIndexing = 1; + Resources.limits.generalVariableIndexing = 1; + Resources.limits.generalConstantMatrixVectorIndexing = 1; +} + namespace boo { static LogVisor::LogModule Log("boo::Vulkan"); @@ -305,7 +399,7 @@ void VulkanContext::initVulkan(const char* appName) * entries loaded into the data pointer - in case the number * of layers went down or is smaller than the size given. */ - putenv("VK_LAYER_PATH=/usr/share/vulkan/explicit_layer.d"); + setenv("VK_LAYER_PATH", "/usr/share/vulkan/explicit_layer.d", 1); do { ThrowIfFailed(vkEnumerateInstanceLayerProperties(&instanceLayerCount, nullptr)); @@ -1814,7 +1908,7 @@ class VulkanShaderPipeline : public IShaderPipeline pipelineCreateInfo.pDepthStencilState = &depthStencilInfo; pipelineCreateInfo.pColorBlendState = &colorBlendInfo; pipelineCreateInfo.pDynamicState = &dynamicState; - pipelineCreateInfo.layout = ctx->m_layout; + pipelineCreateInfo.layout = ctx->m_pipelinelayout; pipelineCreateInfo.renderPass = ctx->m_pass; ThrowIfFailed(vkCreateGraphicsPipelines(ctx->m_dev, pipelineCache, 1, &pipelineCreateInfo, @@ -2004,7 +2098,7 @@ struct VulkanShaderDataBinding : IShaderDataBinding void commit(VulkanContext* ctx) { - VkWriteDescriptorSet writes[(MAX_UNIFORM_COUNT + MAX_TEXTURE_COUNT) * 2] = {}; + VkWriteDescriptorSet writes[(BOO_GLSL_MAX_UNIFORM_COUNT + BOO_GLSL_MAX_TEXTURE_COUNT) * 2] = {}; size_t totalWrites = 0; for (int b=0 ; b<2 ; ++b) { @@ -2028,7 +2122,7 @@ struct VulkanShaderDataBinding : IShaderDataBinding } size_t binding = 0; - for (size_t i=0 ; im_pipeline); - vkCmdBindDescriptorSets(cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, m_ctx->m_layout, 0, 1, &m_descSets[b], 0, nullptr); + vkCmdBindDescriptorSets(cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, m_ctx->m_pipelinelayout, 0, 1, &m_descSets[b], 0, nullptr); vkCmdBindVertexBuffers(cmdBuf, 0, 2, m_vboBufs[b], m_vboOffs[b]); if (m_ibuf) vkCmdBindIndexBuffer(cmdBuf, m_iboBufs[b], m_iboOffs[b], VK_INDEX_TYPE_UINT32); @@ -2610,8 +2704,8 @@ void VulkanDataFactory::destroyAllData() m_committedData.clear(); } -VulkanDataFactory::VulkanDataFactory(IGraphicsContext* parent, VulkanContext* ctx) -: m_parent(parent), m_ctx(ctx) +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; @@ -2625,8 +2719,8 @@ VulkanDataFactory::VulkanDataFactory(IGraphicsContext* parent, VulkanContext* ct samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; ThrowIfFailed(vkCreateSampler(ctx->m_dev, &samplerInfo, nullptr, &ctx->m_linearSampler)); - VkDescriptorSetLayoutBinding layoutBindings[MAX_UNIFORM_COUNT + MAX_TEXTURE_COUNT]; - for (int i=0 ; im_dev, &descriptorLayout, nullptr, &ctx->m_descSetLayout)); + + VkPipelineLayoutCreateInfo pipelineLayout = {}; + pipelineLayout.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + pipelineLayout.setLayoutCount = 1; + pipelineLayout.pSetLayouts = &ctx->m_descSetLayout; + ThrowIfFailed(vkCreatePipelineLayout(ctx->m_dev, &pipelineLayout, nullptr, &ctx->m_pipelinelayout)); + + VkAttachmentDescription attachments[2] = {}; + + /* color attachment */ + attachments[0].format = VK_FORMAT_R8G8B8A8_UNORM; + attachments[0].samples = VkSampleCountFlagBits(drawSamples); + attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + 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}; + + /* depth attachment */ + attachments[1].format = VK_FORMAT_D24_UNORM_S8_UINT; + attachments[1].samples = VkSampleCountFlagBits(drawSamples); + attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE; + attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attachments[1].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + attachments[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + VkAttachmentReference depthAttachmentRef = {1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; + + /* render subpass */ + VkSubpassDescription subpass = {}; + subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + subpass.colorAttachmentCount = 1; + subpass.pColorAttachments = &colorAttachmentRef; + subpass.pDepthStencilAttachment = &depthAttachmentRef; + + /* render pass */ + VkRenderPassCreateInfo renderPass = {}; + renderPass.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + renderPass.attachmentCount = 2; + renderPass.pAttachments = attachments; + renderPass.subpassCount = 1; + renderPass.pSubpasses = &subpass; + ThrowIfFailed(vkCreateRenderPass(ctx->m_dev, &renderPass, nullptr, &ctx->m_pass)); } IShaderPipeline* VulkanDataFactory::newShaderPipeline @@ -2662,33 +2802,37 @@ IShaderPipeline* VulkanDataFactory::newShaderPipeline { if (vertBlobOut.empty() || fragBlobOut.empty()) { + const EShMessages messages = EShMessages(EShMsgSpvRules | EShMsgVulkanRules); + //init_resources(DefaultBuiltInResource); + glslang::TShader vs(EShLangVertex); vs.setStrings(&vertSource, 1); - if (!vs.parse(&DefaultBuiltInResource, 110, true, EShMsgDefault)) + if (!vs.parse(&DefaultBuiltInResource, 110, false, messages)) { - Log.report(LogVisor::Error, "unable to compile vertex shader\n%s", vs.getInfoLog()); + Log.report(LogVisor::FatalError, "unable to compile vertex shader\n%s", vs.getInfoLog()); return nullptr; } glslang::TShader fs(EShLangFragment); fs.setStrings(&fragSource, 1); - if (!fs.parse(&DefaultBuiltInResource, 110, true, EShMsgDefault)) + if (!fs.parse(&DefaultBuiltInResource, 110, false, messages)) { - Log.report(LogVisor::Error, "unable to compile fragment shader\n%s", fs.getInfoLog()); + Log.report(LogVisor::FatalError, "unable to compile fragment shader\n%s", fs.getInfoLog()); return nullptr; } glslang::TProgram prog; prog.addShader(&vs); prog.addShader(&fs); - if (!prog.link(EShMsgDefault)) + if (!prog.link(messages)) { - Log.report(LogVisor::Error, "unable to link shader program\n%s", prog.getInfoLog()); + Log.report(LogVisor::FatalError, "unable to link shader program\n%s", prog.getInfoLog()); return nullptr; } - glslang::GlslangToSpv(*prog.getIntermediate(EShLangVertex), vertBlobOut); + spv::Disassemble(std::cerr, vertBlobOut); glslang::GlslangToSpv(*prog.getIntermediate(EShLangFragment), fragBlobOut); + spv::Disassemble(std::cerr, fragBlobOut); } VkShaderModuleCreateInfo smCreateInfo = {}; @@ -2732,6 +2876,10 @@ IShaderPipeline* VulkanDataFactory::newShaderPipeline } } + vkDestroyPipelineCache(m_ctx->m_dev, pipelineCache, nullptr); + vkDestroyShaderModule(m_ctx->m_dev, fragModule, nullptr); + vkDestroyShaderModule(m_ctx->m_dev, vertModule, nullptr); + if (!m_deferredData.get()) m_deferredData.reset(new struct VulkanData(m_ctx)); static_cast(m_deferredData.get())->m_SPs.emplace_back(retval); @@ -2839,10 +2987,10 @@ ITextureD* VulkanDataFactory::newDynamicTexture(size_t width, size_t height, Tex return retval; } -ITextureR* VulkanDataFactory::newRenderTexture(size_t width, size_t height, size_t samples) +ITextureR* VulkanDataFactory::newRenderTexture(size_t width, size_t height) { VulkanCommandQueue* q = static_cast(m_parent->getCommandQueue()); - VulkanTextureR* retval = new VulkanTextureR(m_ctx, q, width, height, samples); + VulkanTextureR* retval = new VulkanTextureR(m_ctx, q, width, height, m_drawSamples); if (!m_deferredData.get()) m_deferredData.reset(new struct VulkanData(m_ctx)); static_cast(m_deferredData.get())->m_RTexs.emplace_back(retval); @@ -2906,47 +3054,54 @@ GraphicsDataToken VulkanDataFactory::commit() for (std::unique_ptr& tex : retval->m_DTexs) texMemSize = tex->sizeForGPU(m_ctx, texMemTypeBits, texMemSize); - /* allocate memory */ - VkMemoryAllocateInfo memAlloc = {}; - memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - memAlloc.pNext = nullptr; - memAlloc.memoryTypeIndex = 0; - memAlloc.allocationSize = bufMemSize; - ThrowIfFalse(MemoryTypeFromProperties(m_ctx, bufMemTypeBits, 0, &memAlloc.memoryTypeIndex)); - ThrowIfFailed(vkAllocateMemory(m_ctx->m_dev, &memAlloc, nullptr, &retval->m_bufMem)); + /* allocate memory and place textures */ + if (bufMemSize) + { + VkMemoryAllocateInfo memAlloc = {}; + memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + memAlloc.allocationSize = bufMemSize; + ThrowIfFalse(MemoryTypeFromProperties(m_ctx, bufMemTypeBits, 0, &memAlloc.memoryTypeIndex)); + ThrowIfFailed(vkAllocateMemory(m_ctx->m_dev, &memAlloc, nullptr, &retval->m_bufMem)); - memAlloc.allocationSize = texMemSize; - ThrowIfFalse(MemoryTypeFromProperties(m_ctx, texMemTypeBits, 0, &memAlloc.memoryTypeIndex)); - ThrowIfFailed(vkAllocateMemory(m_ctx->m_dev, &memAlloc, nullptr, &retval->m_texMem)); + /* place resources */ + uint8_t* mappedData; + ThrowIfFailed(vkMapMemory(m_ctx->m_dev, retval->m_bufMem, 0, bufMemSize, 0, reinterpret_cast(&mappedData))); - /* place resources */ - uint8_t* mappedData; - ThrowIfFailed(vkMapMemory(m_ctx->m_dev, retval->m_bufMem, 0, bufMemSize, 0, reinterpret_cast(&mappedData))); + for (std::unique_ptr& buf : retval->m_SBufs) + buf->placeForGPU(m_ctx, retval->m_bufMem, mappedData); - for (std::unique_ptr& buf : retval->m_SBufs) - buf->placeForGPU(m_ctx, retval->m_bufMem, mappedData); + /* flush static buffers to gpu */ + VkMappedMemoryRange mappedRange; + mappedRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; + mappedRange.pNext = nullptr; + mappedRange.memory = retval->m_bufMem; + mappedRange.offset = 0; + mappedRange.size = bufMemSize; + ThrowIfFailed(vkFlushMappedMemoryRanges(m_ctx->m_dev, 1, &mappedRange)); + vkUnmapMemory(m_ctx->m_dev, retval->m_bufMem); - /* flush static buffers to gpu */ - VkMappedMemoryRange mappedRange; - mappedRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; - mappedRange.pNext = nullptr; - mappedRange.memory = retval->m_bufMem; - mappedRange.offset = 0; - mappedRange.size = bufMemSize; - ThrowIfFailed(vkFlushMappedMemoryRanges(m_ctx->m_dev, 1, &mappedRange)); - vkUnmapMemory(m_ctx->m_dev, retval->m_bufMem); + for (std::unique_ptr& buf : retval->m_DBufs) + buf->placeForGPU(m_ctx, retval->m_bufMem); + } - for (std::unique_ptr& buf : retval->m_DBufs) - buf->placeForGPU(m_ctx, retval->m_bufMem); + /* allocate memory and place textures */ + if (texMemSize) + { + VkMemoryAllocateInfo memAlloc = {}; + memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + memAlloc.allocationSize = texMemSize; + ThrowIfFalse(MemoryTypeFromProperties(m_ctx, texMemTypeBits, 0, &memAlloc.memoryTypeIndex)); + ThrowIfFailed(vkAllocateMemory(m_ctx->m_dev, &memAlloc, nullptr, &retval->m_texMem)); - for (std::unique_ptr& tex : retval->m_STexs) - tex->placeForGPU(m_ctx, retval->m_texMem); + for (std::unique_ptr& tex : retval->m_STexs) + tex->placeForGPU(m_ctx, retval->m_texMem); - for (std::unique_ptr& tex : retval->m_SATexs) - tex->placeForGPU(m_ctx, retval->m_texMem); + for (std::unique_ptr& tex : retval->m_SATexs) + tex->placeForGPU(m_ctx, retval->m_texMem); - for (std::unique_ptr& tex : retval->m_DTexs) - tex->placeForGPU(m_ctx, retval->m_texMem); + for (std::unique_ptr& tex : retval->m_DTexs) + tex->placeForGPU(m_ctx, retval->m_texMem); + } /* Execute static uploads */ ThrowIfFailed(vkEndCommandBuffer(m_ctx->m_loadCmdBuf)); @@ -3094,9 +3249,5 @@ IGraphicsCommandQueue* _NewVulkanCommandQueue(VulkanContext* ctx, VulkanContext: return new struct VulkanCommandQueue(ctx, windowCtx, parent); } -IGraphicsDataFactory* _NewVulkanDataFactory(VulkanContext* ctx, IGraphicsContext* parent) -{ - return new VulkanDataFactory(parent, ctx); -} } diff --git a/lib/x11/ApplicationWayland.hpp b/lib/x11/ApplicationWayland.hpp index 4399890..32cb7bb 100644 --- a/lib/x11/ApplicationWayland.hpp +++ b/lib/x11/ApplicationWayland.hpp @@ -71,7 +71,7 @@ public: return m_args; } - IWindow* newWindow(const std::string& title) + IWindow* newWindow(const std::string& title, uint32_t drawSamples) { return _WindowWaylandNew(title); } diff --git a/lib/x11/ApplicationXlib.hpp b/lib/x11/ApplicationXlib.hpp index 825bfaa..63acd92 100644 --- a/lib/x11/ApplicationXlib.hpp +++ b/lib/x11/ApplicationXlib.hpp @@ -113,9 +113,9 @@ static Window GetWindowOfEvent(XEvent* event, bool& windowEvent) } IWindow* _WindowXlibNew(const std::string& title, - Display* display, void* xcbConn, + Display* display, void* xcbConn, int defaultScreen, XIM xIM, XIMStyle bestInputStyle, XFontSet fontset, - GLXContext lastCtx, bool useVulkan); + GLXContext lastCtx, bool useVulkan, uint32_t drawSamples); static XIMStyle ChooseBetterStyle(XIMStyle style1, XIMStyle style2) { @@ -473,14 +473,14 @@ public: return m_args; } - IWindow* newWindow(const std::string& title) + IWindow* newWindow(const std::string& title, uint32_t drawSamples) { #if BOO_HAS_VULKAN IWindow* newWindow = _WindowXlibNew(title, m_xDisp, m_xcbConn, m_xDefaultScreen, m_xIM, - m_bestStyle, m_fontset, m_lastGlxCtx, m_useVulkan); + m_bestStyle, m_fontset, m_lastGlxCtx, m_useVulkan, drawSamples); #else IWindow* newWindow = _WindowXlibNew(title, m_xDisp, nullptr, m_xDefaultScreen, m_xIM, - m_bestStyle, m_fontset, m_lastGlxCtx, false); + m_bestStyle, m_fontset, m_lastGlxCtx, false, drawSamples); #endif m_windows[(Window)newWindow->getPlatformHandle()] = newWindow; return newWindow; diff --git a/lib/x11/WindowXlib.cpp b/lib/x11/WindowXlib.cpp index edf4bd1..b5b257c 100644 --- a/lib/x11/WindowXlib.cpp +++ b/lib/x11/WindowXlib.cpp @@ -282,15 +282,17 @@ struct GraphicsContextXlib : IGraphicsContext { EGraphicsAPI m_api; EPixelFormat m_pf; + uint32_t m_drawSamples; IWindow* m_parentWindow; Display* m_xDisp; std::mutex m_vsyncmt; std::condition_variable m_vsynccv; - GraphicsContextXlib(EGraphicsAPI api, EPixelFormat pf, IWindow* parentWindow, Display* disp) + GraphicsContextXlib(EGraphicsAPI api, EPixelFormat pf, IWindow* parentWindow, Display* disp, uint32_t drawSamples) : m_api(api), m_pf(pf), + m_drawSamples(drawSamples), m_parentWindow(parentWindow), m_xDisp(disp) {} virtual void destroy()=0; @@ -318,11 +320,11 @@ public: GraphicsContextXlibGLX(EGraphicsAPI api, IWindow* parentWindow, Display* display, int defaultScreen, - GLXContext lastCtx, uint32_t& visualIdOut) - : GraphicsContextXlib(api, EPixelFormat::RGBA8, parentWindow, display), + GLXContext lastCtx, uint32_t& visualIdOut, uint32_t drawSamples) + : GraphicsContextXlib(api, EPixelFormat::RGBA8, parentWindow, display, drawSamples), m_lastCtx(lastCtx) { - m_dataFactory = new class GLDataFactory(this); + m_dataFactory = new class GLDataFactory(this, drawSamples); /* Query framebuffer configurations */ GLXFBConfig* fbConfigs = nullptr; @@ -619,8 +621,8 @@ public: GraphicsContextXlibVulkan(IWindow* parentWindow, Display* display, xcb_connection_t* xcbConn, int defaultScreen, - VulkanContext* ctx, uint32_t& visualIdOut) - : GraphicsContextXlib(EGraphicsAPI::Vulkan, EPixelFormat::RGBA8, parentWindow, display), + VulkanContext* ctx, uint32_t& visualIdOut, uint32_t drawSamples) + : GraphicsContextXlib(EGraphicsAPI::Vulkan, EPixelFormat::RGBA8, parentWindow, display, drawSamples), m_xcbConn(xcbConn), m_ctx(ctx) { /* Query framebuffer configurations */ @@ -856,7 +858,7 @@ public: }); initcv.wait(outerLk); - m_dataFactory = new class VulkanDataFactory(this, m_ctx); + m_dataFactory = new class VulkanDataFactory(this, m_ctx, m_drawSamples); m_commandQueue = _NewVulkanCommandQueue(m_ctx, m_ctx->m_windows[m_parentWindow].get(), this); } @@ -944,7 +946,7 @@ public: WindowXlib(const std::string& title, Display* display, void* xcbConn, int defaultScreen, XIM xIM, XIMStyle bestInputStyle, XFontSet fontset, - GLXContext lastCtx, bool useVulkan) + GLXContext lastCtx, bool useVulkan, uint32_t drawSamples) : m_xDisp(display), m_callback(nullptr), m_bestStyle(bestInputStyle) { @@ -954,11 +956,11 @@ public: #if BOO_HAS_VULKAN if (useVulkan) m_gfxCtx.reset(new GraphicsContextXlibVulkan(this, display, (xcb_connection_t*)xcbConn, defaultScreen, - &g_VulkanContext, m_visualId)); + &g_VulkanContext, m_visualId, drawSamples)); else #endif m_gfxCtx.reset(new GraphicsContextXlibGLX(IGraphicsContext::EGraphicsAPI::OpenGL3_3, - this, display, defaultScreen, lastCtx, m_visualId)); + this, display, defaultScreen, lastCtx, m_visualId, drawSamples)); /* Default screen */ Screen* screen = ScreenOfDisplay(display, defaultScreen); @@ -1949,12 +1951,13 @@ public: }; IWindow* _WindowXlibNew(const std::string& title, - Display* display, void* xcbConn, + Display* display, void* xcbConn, int defaultScreen, XIM xIM, XIMStyle bestInputStyle, XFontSet fontset, - GLXContext lastCtx, bool useVulkan) + GLXContext lastCtx, bool useVulkan, uint32_t drawSamples) { XLockDisplay(display); - IWindow* ret = new WindowXlib(title, display, xcbConn, defaultScreen, xIM, bestInputStyle, fontset, lastCtx, useVulkan); + IWindow* ret = new WindowXlib(title, display, xcbConn, defaultScreen, xIM, + bestInputStyle, fontset, lastCtx, useVulkan, drawSamples); XUnlockDisplay(display); return ret; } diff --git a/test/main.cpp b/test/main.cpp index cc00b1e..a11eaaf 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -235,7 +235,7 @@ struct TestApplicationCallback : IApplicationCallback /* Create render target */ int x, y, w, h; self->mainWindow->getWindowFrame(x, y, w, h); - self->m_renderTarget = factory->newRenderTexture(w, h, 1); + self->m_renderTarget = factory->newRenderTexture(w, h); /* Make Tri-strip VBO */ struct Vert @@ -294,8 +294,9 @@ struct TestApplicationCallback : IApplicationCallback static const char* FS = "#version 330\n" + BOO_GLSL_BINDING_HEAD "precision highp float;\n" - "uniform sampler2D texs[1];\n" + "TBINDING0 uniform sampler2D texs[1];\n" "layout(location=0) out vec4 out_frag;\n" "in vec2 out_uv;\n" "void main()\n" @@ -395,7 +396,7 @@ struct TestApplicationCallback : IApplicationCallback int appMain(IApplication* app) { - mainWindow = app->newWindow(_S("YAY!")); + mainWindow = app->newWindow(_S("YAY!"), 1); mainWindow->setCallback(&windowCallback); mainWindow->showWindow(); windowCallback.m_lastRect = mainWindow->getWindowFrame();