# HG changeset patch # User sam # Date 1720053008 -25200 # Node ID 850450bfe2a26f177c24d3f4d09b9daa0e390d63 # Parent e9a212e9cdf74ae45cc4ed5118b5f06b84f02634 sync from bedroom to office diff -r e9a212e9cdf7 -r 850450bfe2a2 static_utils.nim --- a/static_utils.nim Wed Jul 03 00:08:19 2024 +0700 +++ b/static_utils.nim Thu Jul 04 07:30:08 2024 +0700 @@ -8,7 +8,6 @@ import std/typetraits as tt import semicongine/core/utils -import semicongine/core/imagetypes import semicongine/core/vector import semicongine/core/matrix import semicongine/core/vulkanapi @@ -58,6 +57,15 @@ vk: VkBuffer offset: uint64 size: uint64 + Texture[Channels: static int, TMemory: GPUMemory] = object + memory: TMemory + vk: VkImage + imageview: VkImageView + sampler: VkSampler + offset: uint64 + size: uint64 + width: int + data: seq[array[Channels, uint8]] GPUArray[T: SupportedGPUType, TMemory: GPUMemory] = object data: seq[T] @@ -74,7 +82,7 @@ MaterialSet DescriptorSet[T: object, sType: static DescriptorSetType] = object data: T - vk: array[INFLIGHTFRAMES, VkDescriptorSet] + vk: array[INFLIGHTFRAMES.int, VkDescriptorSet] Pipeline[TShader] = object vk: VkPipeline @@ -197,7 +205,7 @@ const `isinstancename` {.inject.} = hasCustomPragma(value, InstanceAttribute) body -template ForDescriptorFields(shader: typed, fieldname, typename, countname, bindingNumber, body: untyped): untyped = +template ForDescriptorFields(shader: typed, fieldname, valuename, typename, countname, bindingNumber, body: untyped): untyped = var `bindingNumber` {.inject.} = 1'u32 for theFieldname, value in fieldPairs(shader): when typeof(value) is Texture: @@ -205,6 +213,7 @@ const `fieldname` {.inject.} = theFieldname const `typename` {.inject.} = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER const `countname` {.inject.} = 1'u32 + let `valuename` {.inject.} = value body `bindingNumber`.inc elif typeof(value) is object: @@ -212,6 +221,7 @@ const `fieldname` {.inject.} = theFieldname const `typename` {.inject.} = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER const `countname` {.inject.} = 1'u32 + let `valuename` {.inject.} = value body `bindingNumber`.inc elif typeof(value) is array: @@ -220,6 +230,7 @@ const `fieldname` {.inject.} = theFieldname const `typename` {.inject.} = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER const `countname` {.inject.} = uint32(typeof(value).len) + let `valuename` {.inject.} = value body `bindingNumber`.inc elif elementType(value) is object: @@ -227,8 +238,11 @@ const `fieldname` {.inject.} = theFieldname const `typename` {.inject.} = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER const `countname` {.inject.} = uint32(typeof(value).len) + let `valuename` {.inject.} = value body `bindingNumber`.inc + else: + {.error: "Unsupported descriptor type: " & tt.name(typeof(value)).} func NumberOfVertexInputAttributeDescriptors[T: SupportedGPUType|Texture](value: T): uint32 = when T is TMat2[float32] or T is TMat2[float64] or T is TMat23[float32] or T is TMat23[float64]: @@ -469,12 +483,13 @@ layout: VkDescriptorSetLayout, descriptorSet: var DescriptorSet, ) = + # santization checks for name, value in descriptorSet.data.fieldPairs: when typeof(value) is GPUValue: - assert value.buffer.vk.valid + assert value.buffer.vk.Valid # TODO: # when typeof(value) is Texture: - # assert value.texture.vk.valid + # assert value.texture.vk.Valid # allocate var layouts = newSeqWith(descriptorSet.vk.len, layout) @@ -487,9 +502,45 @@ checkVkResult vkAllocateDescriptorSets(vulkan.device, addr(allocInfo), descriptorSet.vk.ToCPointer) # write - var descriptorSetWrites: newSeq[VkWriteDescriptorSet](descriptorSet.vk.len) - for i in 0 ..< descriptorSet.vk.len: - descriptorSetWrites.add + var descriptorSetWrites = newSeq[VkWriteDescriptorSet](descriptorSet.vk.len) + + var descriptorBinding = 0 + ForDescriptorFields(descriptorSet.data, fieldName, fieldValue, descriptorType, descriptorCount, descriptorBindingNumber): + for i in 0 ..< descriptorSet.vk.len: + when typeof(fieldValue) is GPUValue: + let bufferInfo = VkDescriptorBufferInfo( + buffer: fieldValue.buffer.vk, + offset: fieldValue.buffer.offset, + range: fieldValue.buffer.size, + ) + descriptorSetWrites[i] = VkWriteDescriptorSet( + sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + dstSet: descriptorSet.vk[i], + dstBinding: descriptorBindingNumber, + dstArrayElement: uint32(0), + descriptorType: descriptorType, + descriptorCount: descriptorCount, + pImageInfo: nil, + pBufferInfo: addr(bufferInfo), + ) + elif typeof(fieldValue) is Texture: + let imageInfo = VkDescriptorImageInfo( + sampler: fieldValue.sampler, + imageView: fieldValue.imageView, + imageLayout: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + ) + descriptorSetWrites[i] = VkWriteDescriptorSet( + sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + dstSet: descriptorSet.vk[i], + dstBinding: descriptorBindingNumber, + dstArrayElement: uint32(0), + descriptorType: descriptorType, + descriptorCount: descriptorCount, + pImageInfo: addr(imageInfo), + pBufferInfo: nil, + ) + else: + {.error: "Unsupported descriptor type: " & tt.name(typeof(fieldValue)).} vkUpdateDescriptorSets(vulkan.device, descriptorSetWrites.len.uint32, descriptorSetWrites.ToCPointer, 0, nil) @@ -789,7 +840,7 @@ for theFieldname, value in fieldPairs(default(TShader)): when typeof(value) is DescriptorSet: var layoutbindings: seq[VkDescriptorSetLayoutBinding] - ForDescriptorFields(value.data, fieldName, descriptorType, descriptorCount, descriptorBindingNumber): + ForDescriptorFields(value.data, fieldName, fieldValue, descriptorType, descriptorCount, descriptorBindingNumber): layoutbindings.add VkDescriptorSetLayoutBinding( binding: descriptorBindingNumber, descriptorType: descriptorType, @@ -1329,14 +1380,14 @@ reflection: float32 baseColor: Vec3f UniformsA = object - defaultTexture: Texture + defaultTexture: Texture[3, IndirectGPUMemory] defaultMaterial: GPUValue[MaterialA, IndirectGPUMemory] materials: GPUValue[array[3, MaterialA], IndirectGPUMemory] - materialTextures: array[3, Texture] + materialTextures: array[3, Texture[3, IndirectGPUMemory]] ShaderSettings = object gamma: float32 GlobalsA = object - fontAtlas: Texture + fontAtlas: Texture[1, IndirectGPUMemory] settings: GPUValue[ShaderSettings, IndirectGPUMemory] ShaderA = object @@ -1396,9 +1447,9 @@ MaterialA(reflection: 0.5, baseColor: NewVec3f(0, 0, 1)), ]), materialTextures: [ - Texture(isGrayscale: false, colorImage: Image[RGBAPixel](width: 1, height: 1, imagedata: @[[255'u8, 0'u8, 0'u8, 255'u8]])), - Texture(isGrayscale: false, colorImage: Image[RGBAPixel](width: 1, height: 1, imagedata: @[[0'u8, 255'u8, 0'u8, 255'u8]])), - Texture(isGrayscale: false, colorImage: Image[RGBAPixel](width: 1, height: 1, imagedata: @[[0'u8, 0'u8, 255'u8, 255'u8]])), + Texture[3, IndirectGPUMemory](), + Texture[3, IndirectGPUMemory](), + Texture[3, IndirectGPUMemory](), ] ) )