# HG changeset patch # User Sam # Date 1684226143 -25200 # Node ID 7741bca03e7c65f7ee922c75179aeb27f74316d7 # Parent 6b02e108ba547be90d722f0d0bb80d15f52c2a22 add: support for struct members to be array diff -r 6b02e108ba54 -r 7741bca03e7c src/semicongine/core/gpu_data.nim --- a/src/semicongine/core/gpu_data.nim Mon May 15 23:51:21 2023 +0700 +++ b/src/semicongine/core/gpu_data.nim Tue May 16 15:35:43 2023 +0700 @@ -1020,7 +1020,7 @@ if group.len == 0: return @[] # currently only a single uniform block supported, therefore binding = 0 - result.add(&"layout(binding = {binding}) uniform T{blockName} {{") + result.add(&"layout(std430, binding = {binding}) uniform T{blockName} {{") for attribute in group: var arrayDecl = "" if attribute.arrayCount > 0: diff -r 6b02e108ba54 -r 7741bca03e7c src/semicongine/core/vulkanapi.nim --- a/src/semicongine/core/vulkanapi.nim Mon May 15 23:51:21 2023 +0700 +++ b/src/semicongine/core/vulkanapi.nim Tue May 16 15:35:43 2023 +0700 @@ -12052,7 +12052,9 @@ include ../vulkan/platform/screen EXTENSION_LOADERS["VK_QNX_screen_surface"] = loadVK_QNX_screen_surface -proc loadExtension*(instance: VkInstance, extension: string) = EXTENSION_LOADERS[extension](instance) +proc loadExtension*(instance: VkInstance, extension: string) = + if extension in EXTENSION_LOADERS: + EXTENSION_LOADERS[extension](instance) # load global functions immediately block globalFunctions: diff -r 6b02e108ba54 -r 7741bca03e7c src/semicongine/entity.nim --- a/src/semicongine/entity.nim Mon May 15 23:51:21 2023 +0700 +++ b/src/semicongine/entity.nim Tue May 16 15:35:43 2023 +0700 @@ -12,7 +12,7 @@ Scene* = object name*: string root*: Entity - shaderGlobals*: Table[string, DataValue] + shaderGlobals*: Table[string, DataList] textures*: Table[string, (seq[Image], VkFilter)] Entity* = ref object of RootObj @@ -23,15 +23,24 @@ components*: seq[Component] func addShaderGlobal*[T](scene: var Scene, name: string, data: T) = - var value = DataValue(thetype: getDataType[T]()) - value.setValue(data) - scene.shaderGlobals[name] = value + scene.shaderGlobals[name] = newDataList(thetype=getDataType[T]()) + setValues(scene.shaderGlobals[name], @[data]) + +func addShaderGlobalArray*[T](scene: var Scene, name: string, data: seq[T]) = + scene.shaderGlobals[name] = newDataList(thetype=getDataType[T]()) + setValues(scene.shaderGlobals[name], data) func getShaderGlobal*[T](scene: Scene, name: string): T = - getValue[T](scene.shaderGlobals[name]) + getValues[T](scene.shaderGlobals[name])[0] + +func getShaderGlobalArray*[T](scene: Scene, name: string): seq[T] = + getValues[T](scene.shaderGlobals[name]) func setShaderGlobal*[T](scene: var Scene, name: string, value: T) = - setValue[T](scene.shaderGlobals[name], value) + setValues[T](scene.shaderGlobals[name], @[value]) + +func setShaderGlobalArray*[T](scene: var Scene, name: string, value: seq[T]) = + setValues[T](scene.shaderGlobals[name], value) func addTextures*(scene: var Scene, name: string, texture: seq[Image], interpolation=VK_FILTER_LINEAR) = scene.textures[name] = (texture, interpolation) diff -r 6b02e108ba54 -r 7741bca03e7c src/semicongine/vulkan/descriptor.nim --- a/src/semicongine/vulkan/descriptor.nim Mon May 15 23:51:21 2023 +0700 +++ b/src/semicongine/vulkan/descriptor.nim Tue May 16 15:35:43 2023 +0700 @@ -13,7 +13,6 @@ name*: string count*: uint32 stages*: seq[VkShaderStageFlagBits] - itemsize*: uint32 case thetype*: DescriptorType of Uniform: buffer*: Buffer diff -r 6b02e108ba54 -r 7741bca03e7c src/semicongine/vulkan/device.nim --- a/src/semicongine/vulkan/device.nim Mon May 15 23:51:21 2023 +0700 +++ b/src/semicongine/vulkan/device.nim Tue May 16 15:35:43 2023 +0700 @@ -33,7 +33,7 @@ assert queueFamilies.len > 0 result.physicalDevice = physicalDevice - var allExtensions = enabledExtensions & @["VK_KHR_swapchain"] + var allExtensions = enabledExtensions & @["VK_KHR_swapchain", "VK_KHR_uniform_buffer_standard_layout"] for extension in allExtensions: instance.vk.loadExtension(extension) var @@ -49,6 +49,16 @@ pQueuePriorities: addr(priority), ) var queueList = deviceQueues.values.toSeq + + var uniformBufferLayoutFeature = VkPhysicalDeviceUniformBufferStandardLayoutFeatures( + stype:VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES, + uniformBufferStandardLayout: true, + ) + var features2 = VkPhysicalDeviceFeatures2( + stype: VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, + pnext: addr uniformBufferLayoutFeature, + features: result.enabledFeatures, + ) var createInfo = VkDeviceCreateInfo( sType: VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, queueCreateInfoCount: uint32(queueList.len), @@ -57,7 +67,8 @@ ppEnabledLayerNames: enabledLayersC, enabledExtensionCount: uint32(allExtensions.len), ppEnabledExtensionNames: enabledExtensionsC, - pEnabledFeatures: addr result.enabledFeatures, + pEnabledFeatures: nil, + pnext: addr features2, ) checkVkResult vkCreateDevice( diff -r 6b02e108ba54 -r 7741bca03e7c src/semicongine/vulkan/physicaldevice.nim --- a/src/semicongine/vulkan/physicaldevice.nim Mon May 15 23:51:21 2023 +0700 +++ b/src/semicongine/vulkan/physicaldevice.nim Tue May 16 15:35:43 2023 +0700 @@ -12,7 +12,7 @@ devicetype*: VkPhysicalDeviceType surface*: VkSurfaceKHR properties*: VkPhysicalDeviceProperties - features*: VkPhysicalDeviceFeatures + features*: VkPhysicalDeviceFeatures2 QueueFamily* = object device: PhysicalDevice properties*: VkQueueFamilyProperties @@ -32,7 +32,8 @@ for i in 0 ..< nDevices: var device = PhysicalDevice(vk: devices[i], surface: instance.surface) device.vk.vkGetPhysicalDeviceProperties(addr device.properties) - device.vk.vkGetPhysicalDeviceFeatures(addr device.features) + device.features.stype = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 + device.vk.vkGetPhysicalDeviceFeatures2(addr device.features) device.name = device.properties.deviceName.cleanString() device.devicetype = device.properties.deviceType result.add device diff -r 6b02e108ba54 -r 7741bca03e7c src/semicongine/vulkan/pipeline.nim --- a/src/semicongine/vulkan/pipeline.nim Mon May 15 23:51:21 2023 +0700 +++ b/src/semicongine/vulkan/pipeline.nim Tue May 16 15:35:43 2023 +0700 @@ -25,26 +25,26 @@ return shader.inputs func uniforms*(pipeline: Pipeline): seq[ShaderAttribute] = - var uniformList: Table[string, ShaderAttribute] + var visitedUniforms: Table[string, ShaderAttribute] for shader in pipeline.shaders: for attribute in shader.uniforms: - if attribute.name in uniformList: - assert uniformList[attribute.name] == attribute + if attribute.name in visitedUniforms: + assert visitedUniforms[attribute.name] == attribute else: - uniformList[attribute.name] = attribute - result = uniformList.values.toSeq + result.add attribute + visitedUniforms[attribute.name] = attribute proc setupDescriptors*(pipeline: var Pipeline, buffers: seq[Buffer], textures: Table[string, seq[Texture]], inFlightFrames: int) = assert pipeline.vk.valid assert buffers.len == 0 or buffers.len == inFlightFrames # need to guard against this in case we have no uniforms, then we also create no buffers assert pipeline.descriptorSets.len > 0 - + for i in 0 ..< inFlightFrames: var offset = 0'u64 # first descriptor is always uniform for globals, match should be better somehow for descriptor in pipeline.descriptorSets[i].layout.descriptors.mitems: if descriptor.thetype == Uniform and buffers.len > 0: - let size = VkDeviceSize(descriptor.itemsize * descriptor.count) + let size = VkDeviceSize(descriptor.size) descriptor.buffer = buffers[i] descriptor.offset = offset descriptor.size = size @@ -75,24 +75,20 @@ result.shaders = @[vertexShader, fragmentShader] var descriptors: seq[Descriptor] - if vertexCode.uniforms.len > 0: - for uniform in vertexCode.uniforms: - assert uniform.arrayCount == 0, "arrays not yet supported for uniforms" descriptors.add Descriptor( name: "Uniforms", thetype: Uniform, count: 1, stages: @[VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT], - itemsize: vertexShader.uniforms.size(), + size: vertexShader.uniforms.size(), ) for sampler in vertexShader.samplers: descriptors.add Descriptor( name: sampler.name, thetype: ImageSampler, - count: (if sampler.arrayCount == 0: 1 else: sampler.arrayCount), + count: (if sampler.arrayCount == 0: 1'u32 else: sampler.arrayCount), stages: @[VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT], - itemsize: 0, ) result.descriptorSetLayout = device.createDescriptorSetLayout(descriptors) diff -r 6b02e108ba54 -r 7741bca03e7c src/semicongine/vulkan/shader.nim --- a/src/semicongine/vulkan/shader.nim Mon May 15 23:51:21 2023 +0700 +++ b/src/semicongine/vulkan/shader.nim Tue May 16 15:35:43 2023 +0700 @@ -94,7 +94,7 @@ main: seq[string] ): ShaderCode {.compileTime.} = - var code = @[&"#version {version}", ""] & + var code = @[&"#version {version}", "#extension GL_EXT_scalar_block_layout : require", ""] & # var code = @[&"#version {version}", "layout(row_major) uniform;", ""] & (if inputs.len > 0: inputs.glslInput() & @[""] else: @[]) & (if uniforms.len > 0: uniforms.glslUniforms(binding=0) & @[""] else: @[]) &