GLSL bindings and Vulkan bug fixes

This commit is contained in:
Jack Andersen 2016-02-23 17:11:58 -10:00
parent 74e2f47bcf
commit 6de30424e3
13 changed files with 301 additions and 96 deletions

View File

@ -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()

@ -1 +1 @@
Subproject commit d5c11e053726b03917df6879ac3ae746ae0d99af
Subproject commit c8720ad209ba609f80a736dc777887c805b7b2f5

View File

@ -51,7 +51,7 @@ public:
virtual const std::vector<SystemString>& 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;
};

View File

@ -4,6 +4,7 @@
#include "IGraphicsDataFactory.hpp"
#include "IGraphicsCommandQueue.hpp"
#include "boo/IGraphicsContext.hpp"
#include "GLSLMacros.hpp"
#include <vector>
#include <unordered_set>
#include <mutex>
@ -15,6 +16,7 @@ class GLDataFactory : public IGraphicsDataFactory
{
friend struct GLCommandQueue;
IGraphicsContext* m_parent;
uint32_t m_drawSamples;
static ThreadLocalPtr<struct GLData> m_deferredData;
std::unordered_set<struct GLData*> 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);

View File

@ -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

View File

@ -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*

View File

@ -5,6 +5,7 @@
#include "IGraphicsDataFactory.hpp"
#include "IGraphicsCommandQueue.hpp"
#include "boo/IGraphicsContext.hpp"
#include "GLSLMacros.hpp"
#include <vector>
#include <unordered_set>
#include <unordered_map>
@ -36,7 +37,7 @@ struct VulkanContext
std::vector<VkQueueFamilyProperties> 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<struct VulkanData> m_deferredData;
std::unordered_set<struct VulkanData*> 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);

View File

@ -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<GLCommandQueue*>(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());

View File

@ -9,6 +9,8 @@
#include <vector>
#include <glslang/Public/ShaderLang.h>
#include <SPIRV/GlslangToSpv.h>
#include <SPIRV/disassemble.h>
#include "boo/graphicsdev/GLSLMacros.hpp"
#include <LogVisor/LogVisor.hpp>
@ -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 ; i<MAX_UNIFORM_COUNT ; ++i)
for (size_t i=0 ; i<BOO_GLSL_MAX_UNIFORM_COUNT ; ++i)
{
if (i<m_ubufCount)
{
@ -2044,7 +2138,7 @@ struct VulkanShaderDataBinding : IShaderDataBinding
}
++binding;
}
for (size_t i=0 ; i<MAX_TEXTURE_COUNT ; ++i)
for (size_t i=0 ; i<BOO_GLSL_MAX_TEXTURE_COUNT ; ++i)
{
if (i<m_texCount)
{
@ -2078,7 +2172,7 @@ struct VulkanShaderDataBinding : IShaderDataBinding
#endif
vkCmdBindPipeline(cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline->m_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 ; i<MAX_UNIFORM_COUNT ; ++i)
VkDescriptorSetLayoutBinding layoutBindings[BOO_GLSL_MAX_UNIFORM_COUNT + BOO_GLSL_MAX_TEXTURE_COUNT];
for (int i=0 ; i<BOO_GLSL_MAX_UNIFORM_COUNT ; ++i)
{
layoutBindings[i].binding = i;
layoutBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
@ -2634,7 +2728,7 @@ VulkanDataFactory::VulkanDataFactory(IGraphicsContext* parent, VulkanContext* ct
layoutBindings[i].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
layoutBindings[i].pImmutableSamplers = nullptr;
}
for (int i=MAX_UNIFORM_COUNT ; i<MAX_UNIFORM_COUNT+MAX_TEXTURE_COUNT ; ++i)
for (int i=BOO_GLSL_MAX_UNIFORM_COUNT ; i<BOO_GLSL_MAX_UNIFORM_COUNT+BOO_GLSL_MAX_TEXTURE_COUNT ; ++i)
{
layoutBindings[i].binding = i;
layoutBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
@ -2646,11 +2740,57 @@ VulkanDataFactory::VulkanDataFactory(IGraphicsContext* parent, VulkanContext* ct
VkDescriptorSetLayoutCreateInfo descriptorLayout = {};
descriptorLayout.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
descriptorLayout.pNext = nullptr;
descriptorLayout.bindingCount = MAX_UNIFORM_COUNT + MAX_TEXTURE_COUNT;
descriptorLayout.bindingCount = BOO_GLSL_MAX_UNIFORM_COUNT + BOO_GLSL_MAX_TEXTURE_COUNT;
descriptorLayout.pBindings = layoutBindings;
ThrowIfFailed(vkCreateDescriptorSetLayout(ctx->m_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<VulkanData*>(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<VulkanCommandQueue*>(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<VulkanData*>(m_deferredData.get())->m_RTexs.emplace_back(retval);
@ -2906,47 +3054,54 @@ GraphicsDataToken VulkanDataFactory::commit()
for (std::unique_ptr<VulkanTextureD>& 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<void**>(&mappedData)));
/* place resources */
uint8_t* mappedData;
ThrowIfFailed(vkMapMemory(m_ctx->m_dev, retval->m_bufMem, 0, bufMemSize, 0, reinterpret_cast<void**>(&mappedData)));
for (std::unique_ptr<VulkanGraphicsBufferS>& buf : retval->m_SBufs)
buf->placeForGPU(m_ctx, retval->m_bufMem, mappedData);
for (std::unique_ptr<VulkanGraphicsBufferS>& 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<VulkanGraphicsBufferD>& buf : retval->m_DBufs)
buf->placeForGPU(m_ctx, retval->m_bufMem);
}
for (std::unique_ptr<VulkanGraphicsBufferD>& 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<VulkanTextureS>& tex : retval->m_STexs)
tex->placeForGPU(m_ctx, retval->m_texMem);
for (std::unique_ptr<VulkanTextureS>& tex : retval->m_STexs)
tex->placeForGPU(m_ctx, retval->m_texMem);
for (std::unique_ptr<VulkanTextureSA>& tex : retval->m_SATexs)
tex->placeForGPU(m_ctx, retval->m_texMem);
for (std::unique_ptr<VulkanTextureSA>& tex : retval->m_SATexs)
tex->placeForGPU(m_ctx, retval->m_texMem);
for (std::unique_ptr<VulkanTextureD>& tex : retval->m_DTexs)
tex->placeForGPU(m_ctx, retval->m_texMem);
for (std::unique_ptr<VulkanTextureD>& 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);
}
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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();