mirror of https://github.com/AxioDL/boo.git
GLSL bindings and Vulkan bug fixes
This commit is contained in:
parent
74e2f47bcf
commit
6de30424e3
|
@ -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()
|
||||
|
|
2
glslang
2
glslang
|
@ -1 +1 @@
|
|||
Subproject commit d5c11e053726b03917df6879ac3ae746ae0d99af
|
||||
Subproject commit c8720ad209ba609f80a736dc777887c805b7b2f5
|
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
|
@ -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*
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue