Still restoring stuff that was already “sort of” working at some point (a long time ago) lol: so I continue with this VulkanApp I built in Lua with my binding system. And it seems there is still a lot to do on that path…
2022-10-04 19:47:10.908671 [DEBUG] Creating enum ::VkPresentModeKHR 2022-10-04 19:47:10.909671 [DEBUG] Adding type with class target name: VkPresentModeKHR, (canonical type: VkPresentModeKHR) 2022-10-04 19:47:10.910393 [DEBUG] TypeManager: Registering type { "VkPresentModeKHR" } and then: 2022-10-04 19:47:16.318061 [DEBUG] Resolving target for type: VkPresentModeKHR 2022-10-04 19:47:16.318345 [DEBUG] Couldn't resolve type target, using target name instead: VkPresentModeKHR 2022-10-04 19:47:16.318518 [DEBUG] Creating class ::VkPresentModeKHR
2022-10-06 15:09:27.010095 [DEBUG] Cursor 'VkDeviceQueueCreateInfoList' of kind 'TypeAliasDecl'
elseif ckind == clang.CursorKind.TypedefDecl or ckind == clang.CursorKind.TypeAliasDecl then -- logDEBUG("(Namespace) Registering typedef for '",cname, "'") self:registerTypedef(cur) else logDEBUG("Cursor '",cname, "' of kind '", kindName,"'") end
namespace nvk { class VulkanPhysicalDevice; class VulkanInstance; class VulkanSurface; class NVVULKAN_EXPORT VulkanDevice : public nv::RefObject { NV_DECLARE_NO_COPY(VulkanDevice) NV_DECLARE_NO_MOVE(VulkanDevice) };
auto create_device(const nv::StringList& extensions, const QueueInfoList& queueInfos, const VkPhysicalDeviceFeatures* desired_features = nullptr, uint32_t devId = 0) -> nv::RefPtr<VulkanDevice>
static auto _check_create_device_sig1(lua_State* L) -> bool { int luatop = lua_gettop(L); if( luatop<3 || luatop>5 ) return false; if( !luna_isInstanceOf(L,1,LUNA_SID("nvk::VulkanInstance")) ) return false; if( !luna_isInstanceOf(L,2,LUNA_SID("nv::StringList"),false) && lua_istable(L,2)!=1) return false; if( !luna_isInstanceOf(L,3,LUNA_SID("nvk::QueueInfoList"),false) && lua_istable(L,2)!=1 ) return false; if( luatop>=4 && !luna_isInstanceOf(L,4,LUNA_SID("VkPhysicalDeviceFeatures"),true) ) return false; if( luatop>=5 && lua_isnumber(L,5)!=1 ) return false; return true; }
static auto _bind_create_device_sig1(lua_State* L) -> int { int luatop = lua_gettop(L); nvk::VulkanInstance* self = Luna< nvk::VulkanInstance >::get(L,1); LUNA_ASSERT(self!=nullptr); nv::StringList* extensions = Luna< nv::StringList >::get(L,2,false); nvk::QueueInfoList* queueInfos = Luna< nvk::QueueInfoList >::get(L,3,false); VkPhysicalDeviceFeatures* desired_features = luatop>=4? Luna< VkPhysicalDeviceFeatures >::get(L,4,true) : nullptr; uint32_t devId = luatop>=5? (uint32_t)lua_tointeger(L,5) : (uint32_t)0; nv::RefPtr<nvk::VulkanDevice> res = self->create_device(*extensions, *queueInfos, luatop>=4 ? desired_features : nullptr, devId); Luna< nvk::VulkanDevice >::push(L, res.get(), true); return 1; }
nv::StringList extensions_list; nv::StringList* extensions = &extensions_list; if(lua_istable(L, 2)==1) { // Populate the extensions_list object here: num = (int)lua_objlen(L, 2); for (int i = 0; i < num; ++i) { lua_rawgeti(L, 2, i + 1); nv::String str = // Read the data from stack here as a nv::String value. extensions_list.push_back(str); lua_pop(L, 1); } } else { // Otherwise we must already have a valid StringList object: extensions = Luna< nv::StringList >::get(L,2,false); }
static auto _bind_create_device_sig1(lua_State* L) -> int { int luatop = lua_gettop(L); nvk::VulkanInstance* self = Luna< nvk::VulkanInstance >::get(L,1); LUNA_ASSERT(self!=nullptr); nv::StringList extensions_vec; nv::StringList* extensions = &extensions_vec; if(lua_istable(L, 2)==1) { int num = (int)lua_objlen(L, 2); for (int i = 0; i < num; ++i) { lua_rawgeti(L, 2, i + 1); size_t elem_len = 0; const char* elem_cstr = lua_tolstring(L,-1,&elem_len); nv::String elem(elem_cstr, elem_len); extensions_vec.push_back(std::move(elem)); lua_pop(L, 1); } } else { extensions = Luna< nv::StringList >::get(L,2,false); } nvk::QueueInfoList queueInfos_vec; nvk::QueueInfoList* queueInfos = &queueInfos_vec; if(lua_istable(L, 3)==1) { int num = (int)lua_objlen(L, 3); for (int i = 0; i < num; ++i) { lua_rawgeti(L, 3, i + 1); nvk::QueueInfo* elem = Luna< nvk::QueueInfo >::get(L,-1,false); queueInfos_vec.push_back(*elem); lua_pop(L, 1); } } else { queueInfos = Luna< nvk::QueueInfoList >::get(L,3,false); } VkPhysicalDeviceFeatures* desired_features = luatop>=4? Luna< VkPhysicalDeviceFeatures >::get(L,4,true) : nullptr; uint32_t devId = luatop>=5? (uint32_t)lua_tointeger(L,5) : (uint32_t)0; nv::RefPtr<nvk::VulkanDevice> res = self->create_device(*extensions, *queueInfos, luatop>=4 ? desired_features : nullptr, devId); Luna< nvk::VulkanDevice >::push(L, res.get(), true); return 1; }
-- Now we create a device with a simple queue: local qflags = VkQueueFlagBits -- local qinfos = nvk.QueueInfoList() -- qinfos:push_back() -- local extNames = nv.StringList() -- extNames:push_back() local dev = inst:create_device({exts.VK_KHR_SWAPCHAIN}, {nvk.QueueInfo(qflags.GRAPHICS_BIT, 0.3)}, nil, 0) logDEBUG("Done creating device.")
-- Inject the functions: create_func(cl:getName(), "void ()") create_func(cl:getName(), "void (const "..fname.."&)", nil, {{"rhs", cref_type}})
-- Also write our custom functions here directly: self:writeSubLine([[ // Here I'm writing the custom functions that will be bound below for vector class ${1} // with elements of type ${2} static void _lunaext_for_each(const ${1}& obj, lua_State* L, LuaFunction& func) { for(auto i=0; i<obj.size(); ++i) { func((lua_Integer)i, obj[i]); } }; ]], fname, el_name)
template <typename T> void pushArgs(const T& arg0) { logDEBUG("Pushing single arg."); pushArg(arg0); } template <typename T, typename... Args> auto pushArgs(T arg0, const Args&... args) -> bool { logDEBUG("Pushing 1 arg."); pushArg(arg0); logDEBUG("Pushing more args..."); pushArgs(args...); logDEBUG("Done pushing args."); }
template <typename T> void pushArgs(const T& arg0) { pushArg(arg0); } template <typename T1, typename T2> void pushArgs(const T1& arg1, const T2& arg2) { pushArg(arg1); pushArg(arg2); } template <typename T1, typename T2, typename T3> void pushArgs(const T1& arg1, const T2& arg2, const T3& arg3) { pushArg(arg1); pushArg(arg2); pushArg(arg3); } template <typename T1, typename T2, typename T3, typename T4> void pushArgs(const T1& arg1, const T2& arg2, const T3& arg3, const T4& arg4) { pushArg(arg1); pushArg(arg2); pushArg(arg3); pushArg(arg4); }
inline auto _lunactr_VkExtent2D(nv::U32 width = 0, nv::U32 height = 0) -> VkExtent2D* { // logDEBUG("Should create a new extent2D here with witdh={}, height={}", // width, height); return new VkExtent2D{width, height}; }
luna::setLogFunctions(luna_debug_log, luna_error_log); // Also prepare here the registration of the void type: luna::pushGlobalNamespace(L); luna::Luna<void>::Register(L); luna::popNamespace(L);
$ nv_ytdl -v PL8327DO66nu9qYVKLDmdLW_84-yE4auCR -p vulkan_tutorial_series
#version 450 #ifdef __VERTEX__ vec2 positions[3] = vec2[] { vec2(0.0, -0.5), vec2(0.5, 0.5), vec2(-0.5, 0.5) }; void main() { gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0); } #endif #ifdef __FRAGMENT__ layout(location=0) out vec4 outColor; void main() { outColor = vec4(1.0, 0.0, 0.0, 1.0); } #endif
glslang::DefaultTBuiltInResource
is not available anymore. ⇒ replacement solution found at https://github.com/KhronosGroup/glslang/issues/2207/* Helper method used to compile GLSL code to SPIRV */ auto compile_glsl_to_spirv(ShaderStage stage, const char* shader_code, const char* code_name) -> nv::String;
logDEBUG("Loading Vulkan bindings...") bm:loadBindings("Vulkan", "luaVulkan") -- Create the Library: local lib = nvk.VulkanLibrary() local app = nv.NervApp.instance() app:register_component(lib) lib:init() -- Here we should be able to load a GLSL source file: local code = lib:get_glsl_source("tests/test_simple.glsl") logDEBUG("Loaded code is: ", code) -- Now we request the compilation: vert_code = "#define __VERTEX__\n"..code frag_code = "#define __FRAGMENT__\n"..code vert_spirv = lib:compile_glsl_to_spirv(nvk.ShaderStage.VERTEX, vert_code, "test_simple_vert") logDEBUG("Compiled vertex shader spirv code length: ", #vert_spirv) frag_spirv = lib:compile_glsl_to_spirv(nvk.ShaderStage.FRAGMENT, frag_code, "test_simple_frag") logDEBUG("Compiled fragment shader spirv code length: ", #frag_spirv)
2022-10-14 08:15:33.371281 [ERROR] GLSL preprocessing failed in test_simple_vert: 2022-10-14 08:15:33.371312 [ERROR] Info log: WARNING: 0:1: '#define' : names containing consecutive underscores are reserved: __VERTEX__ ERROR: 0:2: '#version' : must occur first in shader ERROR: 0:2: '#version' : bad profile name; use es, core, or compatibility ERROR: 0:2: '#version' : bad tokens following profile -- expected newline ERROR: 3 compilation errors. No code generated. 2022-10-14 08:15:33.371322 [ERROR] Debug log: 2022-10-14 08:15:33.371375 [DEBUG] Compiled vertex shader spirv code length: 0 2022-10-14 08:15:33.372532 [ERROR] GLSL preprocessing failed in test_simple_frag: 2022-10-14 08:15:33.372544 [ERROR] Info log: WARNING: 0:1: '#define' : names containing consecutive underscores are reserved: __FRAGMENT__ ERROR: 0:2: '#version' : must occur first in shader ERROR: 0:2: '#version' : bad profile name; use es, core, or compatibility ERROR: 0:2: '#version' : bad tokens following profile -- expected newline ERROR: 3 compilation errors. No code generated. 2022-10-14 08:15:33.372554 [ERROR] Debug log: 2022-10-14 08:15:33.372577 [DEBUG] Compiled fragment shader spirv code length: 0
2022-10-14 08:27:22.758819 [ERROR] GLSL parsing failed in test_simple_vert: 2022-10-14 08:27:22.758845 [ERROR] Info log: ERROR: 0:13: 'limitations' : Non-constant-index-expression ERROR: 1 compilation errors. No code generated.
gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
limits.generalUniformIndexing = true;
⇒ But we have that already 😲# link_directories(${VULKAN_DIR}/lib)
in my cmake configs, then everything is still compiling just fine (⇒ we are not linking to any vulkan library actually 😅) and I will link to the glslang library version 11.11.0 that I'm providing separately, and the vertex code will now compile!SPIR-V module not valid: Invalid SPIR-V binary version 1.6 for target environment SPIR-V 1.0 (under Vulkan 1.0 semantics)
// We prepare the application info: VkApplicationInfo application_info = {VK_STRUCTURE_TYPE_APPLICATION_INFO, nullptr, lib->get_application_name().c_str(), VK_MAKE_VERSION(1, 0, 0), lib->get_engine_name().c_str(), VK_MAKE_VERSION(1, 0, 0), VK_MAKE_VERSION(1, 3, 0)};
function Class:createCommandBuffers() local queue = self.vkdev:get_queue(0) local famIdx = queue:get_queue_family_index() logDEBUG("Queue 0 family index: ", famIdx) -- Now we create a Command Pool on that family index: self.cmdpool = self.vkdev:create_command_pool(famIdx, VkCommandPoolCreateFlagBits.RESET_COMMAND_BUFFER_BIT); logDEBUG("Created command pool"); -- Then we create a command buffer: -- We create as many buffers as we have images in our swapchain local num = self.swapchain:get_num_images() self.cmdbufs = self.cmdpool:create_command_buffers(num, VkCommandBufferLevel.PRIMARY); logDEBUG("Created command buffers"); end
cfg.defaultNamespaceName = "vk"
local preprocessEnums = function(ent) local name = ent:getFullName() -- rename vulkan enums: if name:startsWith("Vk") then ent:setLuaAlias(name:sub(3)) end for _,p in ipairs(allowedEnums) do if name:find(p) then return end end -- Ignore this entity: ent:setIgnored(true) -- logDEBUG("=> Ignoring entity ", name) return end
"Lua.diagnostics.globals": [ "vk", "nvk", "nv", "clang", "nerv", "lfs", "nvLogTRACE", "nvLogDEBUG", "nvLogINFO", "nvLogWARN", "nvLogERROR", "nvLogFATAL", "nvCHECK", "nvTHROW" ], "Lua.runtime.version": "LuaJIT", // "Lua.workspace.library": ["${workspaceFolder}/dist/assets/lua/external"], "Lua.workspace.library": ["dist/assets/lua_defs"], "Lua.workspace.ignoreDir": [ ".cache", ".vscode", "cmake", "sources", "temp", "tests", "dist/modules", "dist/assets/lua_defs", "dist/assets/lua/external", "dist/assets/lua/pl" ], "Lua.workspace.checkThirdParty": false
---@enum vk.MemoryAllocateFlagBits vk.MemoryAllocateFlagBits = { DEVICE_MASK_BIT = 0, DEVICE_ADDRESS_BIT = 1, DEVICE_ADDRESS_CAPTURE_REPLAY_BIT = 2, DEVICE_MASK_BIT_KHR = 3, DEVICE_ADDRESS_BIT_KHR = 4, DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR = 5, FLAG_BITS_MAX_ENUM = 6, }
---@class vk.SurfaceCapabilitiesKHR ---@field minImageCount integer ---@field maxImageCount integer ---@field currentExtent vk.Extent2D ---@field minImageExtent vk.Extent2D ---@field maxImageExtent vk.Extent2D ---@field maxImageArrayLayers integer ---@field supportedTransforms integer ---@field currentTransform vk.SurfaceTransformFlagBitsKHR ---@field supportedCompositeAlpha integer ---@field supportedUsageFlags integer vk.SurfaceCapabilitiesKHR = {}
---@class nvk.VulkanSubpassDescription ---@field objects nvk.VkSubpassDescriptionList ---@field pInputAttachments nv.Vector_nvk_VkAttachmentReferenceList ---@field pColorAttachments nv.Vector_nvk_VkAttachmentReferenceList ---@field pResolveAttachments nv.Vector_nvk_VkAttachmentReferenceList ---@field pDepthStencilAttachment nvk.VkAttachmentReferenceList ---@field pPreserveAttachments nv.Vector_nv_U32List local class = {} ---@param rhs nvk.VulkanSubpassDescription ---@return nvk.VulkanSubpassDescription function class:op_assign(rhs) end ---@return nvk.VkSubpassDescriptionList function class:getVkList() end ---@return vk.SubpassDescription function class:getVk() end ---@return boolean function class:empty() end ---@return integer function class:size() end ---@param item vk.SubpassDescription ---@return nvk.VulkanSubpassDescription ---@overload fun(bpoint: vk.PipelineBindPoint): nvk.VulkanSubpassDescription function class:addItem(item) end ---@return vk.SubpassDescription function class:getCurrent() end ---@param flags_ integer ---@return nvk.VulkanSubpassDescription function class:setFlags(flags_) end ---@param pipelineBindPoint_ vk.PipelineBindPoint ---@return nvk.VulkanSubpassDescription function class:setBindPoint(pipelineBindPoint_) end ---@return nvk.VkAttachmentReferenceList function class:getCurrentInputAttachmentList() end ---@param list nvk.VkAttachmentReferenceList ---@return nvk.VulkanSubpassDescription function class:setInputAttachments(list) end ---@param obj vk.AttachmentReference ---@return nvk.VulkanSubpassDescription ---@overload fun(attachment: integer, layout: vk.ImageLayout): nvk.VulkanSubpassDescription function class:addInputAttachment(obj) end ---@return vk.AttachmentReference function class:addNewInputAttachment() end ---@return nvk.VulkanSubpassDescription function class:syncInputAttachments() end ---@return nvk.VkAttachmentReferenceList function class:getCurrentColorAttachmentList() end ---@param list nvk.VkAttachmentReferenceList ---@return nvk.VulkanSubpassDescription function class:setColorAttachments(list) end ---@param obj vk.AttachmentReference ---@return nvk.VulkanSubpassDescription ---@overload fun(attachment: integer, layout: vk.ImageLayout): nvk.VulkanSubpassDescription function class:addColorAttachment(obj) end ---@return vk.AttachmentReference function class:addNewColorAttachment() end ---@return nvk.VulkanSubpassDescription function class:syncColorAttachments() end ---@return nvk.VkAttachmentReferenceList function class:getCurrentResolveAttachmentList() end ---@param list nvk.VkAttachmentReferenceList ---@return nvk.VulkanSubpassDescription function class:setResolveAttachments(list) end ---@param obj vk.AttachmentReference ---@return nvk.VulkanSubpassDescription ---@overload fun(attachment: integer, layout: vk.ImageLayout): nvk.VulkanSubpassDescription function class:addResolveAttachment(obj) end ---@return vk.AttachmentReference function class:addNewResolveAttachment() end ---@return nvk.VulkanSubpassDescription function class:syncResolveAttachments() end ---@return vk.AttachmentReference function class:getCurrentDepthStencilAttachment() end ---@return nvk.VulkanSubpassDescription ---@overload fun(obj: vk.AttachmentReference): nvk.VulkanSubpassDescription ---@overload fun(attachment: integer, layout: vk.ImageLayout): nvk.VulkanSubpassDescription function class:setDepthStencilAttachment() end ---@return boolean function class:hasDepthStencilAttachment() end ---@return vk.AttachmentReference function class:getOrCreateDepthStencilAttachment() end ---@return nv.U32List function class:getCurrentPreserveAttachmentList() end ---@param list nv.U32List ---@return nvk.VulkanSubpassDescription function class:setPreserveAttachments(list) end ---@param obj integer ---@return nvk.VulkanSubpassDescription function class:addPreserveAttachment(obj) end
local lib = nvk.VulkanLibrary()
lib
object is not recognized as a VulkanLibrary instance: so I need to setup the constructor overloads when creating the library to provide this feature.-- Get the class constructor: local ctr = class:getConstructor() if ctr ~= nil then local sigs = ctr:getPublicSignatures(true) for _, sig in ipairs(sigs) do local args = sig:getArguments() local anames = {} for _, arg in ipairs(args) do -- Ignore the canonical lua state: if not arg:isCanonicalLuaState() then local aname = arg:getName() local atype = arg:getType():getLuaTypeName() if atype == "luna.LuaFunction" then atype = "function" end table.insert(anames, aname .. ": " .. atype) end end -- Finish the list of arguments: local elems = {} table.insert(elems, "---@overload fun(") table.insert(elems, table.concat(anames, ", ")) table.insert(elems, "): ") -- The return type should be the class itself: table.insert(elems, clname) -- Write that constructor: self:writeLine(table.concat(elems, "")) end end
nthreads = self.get_param("num_threads", None) flags = None if nthreads is not None: logger.info("Building with %d threads.", nthreads) flags = ["-j", str(nthreads)] builder.run_ninja(build_dir, outfile=outfile, flags=flags)
psr = context.build_parser("build") psr.add_str("proj_names")("List of modules to build") psr.add_str("-d", "--dir", dest="mod_install_dir")("Install folder") psr.add_flag("-r", "--rebuild", dest="rebuild")("Force rebuilding completely") psr.add_str("-c", "--compiler", dest="compiler_type", default="clang")("Select the compiler") psr.add_int("-j", "--num-threads", dest="num_threads")("Specify the number of threads to use during build.")
build_type = self.get_param("build_type", "Release") logger.info("Cmake build type: %s", build_type) builder = self.get_builder() builder.run_cmake(build_dir, install_dir, src_dir, flags, outfile=outfile, build_type=build_type)
nvp nvl_build -j 4 -t Debug
lld-link: error: could not open 'libboost_filesystem-clang14-mt-gd-x64-1_79.lib': no such file or directory lld-link: error: /failifmismatch: mismatch detected for '_ITERATOR_DEBUG_LEVEL': >>> sources/nvCore/shared/CMakeFiles/nvCore.dir/_/src/view/WindowManager.cpp.obj has value 2
cli.bat build libs boost --rebuild
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDLL")
-- Method used to record command buffers: ---@param rpassIdx integer The render pass to use. function Class:recordCommandBuffers(rpassIdx) -- Should create the framebuffers for each of the swapchain images here: -- Before we can create a framebuffer, we need to create the depth image that we will use as attachment: self.depthImg = self.vkeng:create_image_2d(self.width, self.height, vk.Format.D32_SFLOAT, vk.ImageUsageFlagBits.DEPTH_STENCIL_ATTACHMENT_BIT) -- logDEBUG("Depth image idx: ", self.depthImg) self:allocate_image_memory(self.depthImg) local depthView = self.vkeng:create_image_view(self.depthImg) local schain = self.vkeng:get_swap_chain(self.swapchain) -- Iterate on each command buffer object: local num = self.cmdbufs:size() self.framebuffers = nv.U64List() for i = 0, num - 1 do -- Create the framebuffer that will be used to render into the image (i): local imgIdx = schain:get_image(i) -- self:allocate_image_memory(imgIdx) local viewIdx = self.vkeng:create_image_view(imgIdx) local fbIdx = self.vkeng:create_framebuffer(rpassIdx, { viewIdx, depthView }, self.width, self.height) self.framebuffers:push_back(fbIdx) local cbuf = self.vkeng:get_command_buffer(self.cmdbufs:at(i)) -- cbuf:begin(vk.CommandBufferUsageFlagBits.ONE_TIME_SUBMIT_BIT) cbuf:begin(0) -- Begin rendering into the swapchain framebuffer: cbuf:begin_inline_pass(rpassIdx, fbIdx) -- End the render pass: cbuf:end_render_pass() -- Finish the command buffer: cbuf:finish() self.renderer:add_swapchain_img_cmd_buffer(cbuf, i) end logDEBUG("Done recording ", num, " command buffers.") end
-- Set the clear color of the first attachment of the framebuffer: local fbuf = self.vkeng:get_framebuffer(fbIdx) fbuf:set_clear_color(0, 1.0, 0.0, 0.0, 1.0)
cbuf:begin(0) -- Begin rendering into the swapchain framebuffer: cbuf:begin_inline_pass(rpassIdx, fbIdx) -- Bind the graphics pipeline: cbuf:bind_graphics_pipeline(pipelineIdx) -- Draw our triangle: cbuf:draw(3) -- End the render pass: cbuf:end_render_pass() -- Finish the command buffer: cbuf:finish()
for i = 0, num - 1 do -- Before we can create a framebuffer, we need to create the depth image that we will use as attachment: local depthImg = self.vkeng:create_image_2d(self.width, self.height, vk.Format.D32_SFLOAT, vk.ImageUsageFlagBits.DEPTH_STENCIL_ATTACHMENT_BIT) -- logDEBUG("Depth image idx: ", depthImg) self:allocate_image_memory(depthImg) local depthView = self.vkeng:create_image_view(depthImg) -- Alos get the view for the swapchain image: local imgIdx = schain:get_image(i) -- self:allocate_image_memory(imgIdx) local viewIdx = self.vkeng:create_image_view(imgIdx) -- Create the framebuffer that will be used to render into the image (i): local fbIdx = self.vkeng:create_framebuffer(rpassIdx, { viewIdx, depthView }, self.width, self.height) self.framebuffers:push_back(fbIdx) end
local ddesc = nvk.VulkanSubpassDependency() ddesc:setSrcStageMask(vk.PipelineStageFlagBits.COLOR_ATTACHMENT_OUTPUT_BIT + vk.PipelineStageFlagBits.EARLY_FRAGMENT_TESTS_BIT) ddesc:setDstStageMask(vk.PipelineStageFlagBits.COLOR_ATTACHMENT_OUTPUT_BIT + vk.PipelineStageFlagBits.EARLY_FRAGMENT_TESTS_BIT) ddesc:setSrcAccessMask(0) ddesc:setDstAccessMask(vk.AccessFlagBits.COLOR_ATTACHMENT_WRITE_BIT + vk.AccessFlagBits.DEPTH_STENCIL_ATTACHMENT_WRITE_BIT)
VUID-VkGraphicsPipelineCreateInfo-renderPass-06044(ERROR / SPEC): msgNum: -1526981024 - Validation Error: [ VUID-VkGraphicsPipelineCreateInfo-renderPass-06044 ] Object 0: handle = 0x27a7263ab50, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0xa4fc1e60 | Invalid Pipeline CreateInfo[0] State: pColorBlendState is NULL when rasterization is enabled and subpass uses color attachments. The Vulkan spec states: If renderPass is not VK_NULL_HANDLE, the pipeline is being created with fragment output interface state, and subpass uses color attachments, pColorBlendState must be a valid pointer to a valid VkPipelineColorBlendStateCreateInfo structure (https://vulkan.lunarg.com/doc/view/1.3.224.1/windows/1.3-extensions/vkspec.html#VUID-VkGraphicsPipelineCreateInfo-renderPass-06044)
auto VulkanDevice::create_graphics_pipelines( const VkGraphicsPipelineCreateInfoList& infos, VkPipelineCache cache) -> VulkanPipelineList { VulkanPipelineList list; if (infos.empty()) return list; // override the ColorBlendState config here: VkPipelineColorBlendAttachmentState attachment{}; attachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; attachment.blendEnable = VK_FALSE; attachment.srcColorBlendFactor = VK_BLEND_FACTOR_ONE; // Optional attachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; // Optional attachment.colorBlendOp = VK_BLEND_OP_ADD; // Optional attachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; // Optional attachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; // Optional attachment.alphaBlendOp = VK_BLEND_OP_ADD; // Optional VkPipelineColorBlendStateCreateInfo blendInfo{}; blendInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; blendInfo.logicOpEnable = VK_FALSE; blendInfo.logicOp = VK_LOGIC_OP_COPY; // Optional blendInfo.attachmentCount = 1; blendInfo.pAttachments = &attachment; blendInfo.blendConstants[0] = 0.0F; // Optional blendInfo.blendConstants[1] = 0.0F; // Optional blendInfo.blendConstants[2] = 0.0F; // Optional blendInfo.blendConstants[3] = 0.0F; // Optional const_cast<VkGraphicsPipelineCreateInfoList&>(infos)[0].pColorBlendState = &blendInfo; VkPipelineList pipelines; pipelines.resize(infos.size()); CHECK_VK_MSG(vkCreateGraphicsPipelines(_device, cache, (uint32_t)infos.size(), infos.data(), nullptr, pipelines.data()), "Cannot create graphic pipelines"); for (auto& p : pipelines) { list.push_back(new VulkanPipeline(this, p)); } return list; }
local blend = cfg:getCurrentColorBlendState() -- blend:setLogicOpEnabled(vk.FALSE) blend:setLogicOp(vk.LogicOp.COPY) -- blend:setBlendConstants(0.0, 0.0, 0.0, 0.0) blend:addAttachment(vk.FALSE, -- blendEnabled vk.BlendFactor.ONE, -- srcColor vk.BlendFactor.ZERO, -- dstColor vk.BlendOp.ADD, -- colorBlendOp, vk.BlendFactor.ONE, -- srcAlphaBlendFactor, vk.BlendFactor.ZERO, -- dstAlphaBlendFactor, vk.BlendOp.ADD, -- alphaBlendOp, vk.ColorComponentFlagBits.R_BIT + vk.ColorComponentFlagBits.G_BIT + vk.ColorComponentFlagBits.B_BIT + vk.ColorComponentFlagBits.A_BIT )
inline auto addAttachment(VkBool32 blendEnable, VkBlendFactor srcColorBlendFactor, VkBlendFactor dstColorBlendFactor, VkBlendOp colorBlendOp, VkBlendFactor srcAlphaBlendFactor, VkBlendFactor dstAlphaBlendFactor, VkBlendOp alphaBlendOp, VkColorComponentFlags colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT) -> class_type& { return addAttachment({blendEnable, srcColorBlendFactor, dstColorBlendFactor, colorBlendOp, srcAlphaBlendFactor, dstAlphaBlendFactor, alphaBlendOp, colorWriteMask}); }
static auto _bind_addAttachment_sig2(lua_State* L) -> int { int luatop = lua_gettop(L); nvk::VulkanPipelineColorBlendStateCreateInfo* self = Luna< nvk::VulkanPipelineColorBlendStateCreateInfo >::get(L,1); LUNA_ASSERT(self!=nullptr); auto blendEnable = (uint32_t)lua_tointeger(L,2); auto srcColorBlendFactor = (VkBlendFactor)lua_tointeger(L,3); auto dstColorBlendFactor = (VkBlendFactor)lua_tointeger(L,4); auto colorBlendOp = (VkBlendOp)lua_tointeger(L,5); auto srcAlphaBlendFactor = (VkBlendFactor)lua_tointeger(L,6); auto dstAlphaBlendFactor = (VkBlendFactor)lua_tointeger(L,7); auto alphaBlendOp = (VkBlendOp)lua_tointeger(L,8); uint32_t colorWriteMask = luatop>=9? (uint32_t)lua_tointeger(L,9) : (uint32_t)VK_COLOR_COMPONENT_R_BIT; nvk::VulkanPipelineColorBlendStateCreateInfo& res = self->addAttachment(blendEnable, srcColorBlendFactor, dstColorBlendFactor, colorBlendOp, srcAlphaBlendFactor, dstAlphaBlendFactor, alphaBlendOp, colorWriteMask); Luna< nvk::VulkanPipelineColorBlendStateCreateInfo >::push(L, &res, false); return 1; }
2022-11-04 12:24:20.491163 [DEBUG] cursor AST: 2022-11-04 12:24:20.491199 [DEBUG] level 1: 'VkColorComponentFlags' of kind 'TypeRef', type: 'VkColorComponentFlags' 2022-11-04 12:24:20.491236 [DEBUG] level 1: '' of kind 'UnexposedExpr', type: 'VkColorComponentFlags' 2022-11-04 12:24:20.491273 [DEBUG] level 2: '' of kind 'BinaryOperator', type: 'int' 2022-11-04 12:24:20.491308 [DEBUG] level 3: '' of kind 'BinaryOperator', type: 'int' 2022-11-04 12:24:20.491345 [DEBUG] level 4: '' of kind 'BinaryOperator', type: 'int' 2022-11-04 12:24:20.491383 [DEBUG] level 5: 'VK_COLOR_COMPONENT_R_BIT' of kind 'UnexposedExpr', type: 'int' 2022-11-04 12:24:20.491444 [DEBUG] level 6: 'VK_COLOR_COMPONENT_R_BIT' of kind 'DeclRefExpr', type: 'VkColorComponentFlagBits' 2022-11-04 12:24:20.491488 [DEBUG] level 5: 'VK_COLOR_COMPONENT_G_BIT' of kind 'UnexposedExpr', type: 'int' 2022-11-04 12:24:20.491528 [DEBUG] level 6: 'VK_COLOR_COMPONENT_G_BIT' of kind 'DeclRefExpr', type: 'VkColorComponentFlagBits' 2022-11-04 12:24:20.491570 [DEBUG] level 4: 'VK_COLOR_COMPONENT_B_BIT' of kind 'UnexposedExpr', type: 'int' 2022-11-04 12:24:20.491610 [DEBUG] level 5: 'VK_COLOR_COMPONENT_B_BIT' of kind 'DeclRefExpr', type: 'VkColorComponentFlagBits' 2022-11-04 12:24:20.491696 [DEBUG] level 3: 'VK_COLOR_COMPONENT_A_BIT' of kind 'UnexposedExpr', type: 'int' 2022-11-04 12:24:20.491746 [DEBUG] level 4: 'VK_COLOR_COMPONENT_A_BIT' of kind 'DeclRefExpr', type: 'VkColorComponentFlagBits
static auto _bind_addAttachment_sig2(lua_State* L) -> int { int luatop = lua_gettop(L); nvk::VulkanPipelineColorBlendStateCreateInfo* self = Luna< nvk::VulkanPipelineColorBlendStateCreateInfo >::get(L,1); LUNA_ASSERT(self!=nullptr); auto blendEnable = (uint32_t)lua_tointeger(L,2); auto srcColorBlendFactor = (VkBlendFactor)lua_tointeger(L,3); auto dstColorBlendFactor = (VkBlendFactor)lua_tointeger(L,4); auto colorBlendOp = (VkBlendOp)lua_tointeger(L,5); auto srcAlphaBlendFactor = (VkBlendFactor)lua_tointeger(L,6); auto dstAlphaBlendFactor = (VkBlendFactor)lua_tointeger(L,7); auto alphaBlendOp = (VkBlendOp)lua_tointeger(L,8); uint32_t colorWriteMask = luatop>=9? (uint32_t)lua_tointeger(L,9) : (uint32_t)VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT; nvk::VulkanPipelineColorBlendStateCreateInfo& res = self->addAttachment(blendEnable, srcColorBlendFactor, dstColorBlendFactor, colorBlendOp, srcAlphaBlendFactor, dstAlphaBlendFactor, alphaBlendOp, colorWriteMask); Luna< nvk::VulkanPipelineColorBlendStateCreateInfo >::push(L, &res, false); return 1; }