# HG changeset patch # User sam # Date 1721295204 -25200 # Node ID 4e465583ea32784e735dde45071efcc305d7981c # Parent 4d97cfc4888bbb6257a21345710428979cbe793f did: rename texture to image diff -r 4d97cfc4888b -r 4e465583ea32 semiconginev2/contrib/algorithms/texture_packing.nim --- a/semiconginev2/contrib/algorithms/texture_packing.nim Wed Jul 17 23:45:43 2024 +0700 +++ b/semiconginev2/contrib/algorithms/texture_packing.nim Thu Jul 18 16:33:24 2024 +0700 @@ -42,12 +42,12 @@ return (false, newRect) -proc Pack*[T](textures: seq[Texture[T]]): tuple[atlas: Texture[T], coords: seq[tuple[x: uint32, y: uint32]]] = +proc Pack*[T: PixelType](images: seq[Image[T]]): tuple[atlas: Image[T], coords: seq[tuple[x: uint32, y: uint32]]] = const MAX_ATLAS_SIZE = 4096'u32 var areas: seq[tuple[i: int, w, h: uint32]] - for i in 0 ..< textures.len: - areas.add (i, textures[i].width, textures[i].height) + for i in 0 ..< images.len: + areas.add (i, images[i].width, images[i].height) let areasBySize = areas.sortedByIt(-(it[1] * it[2]).int64) var assignedAreas: seq[Rect] @@ -57,7 +57,7 @@ var pos = find_insertion_position(assignedAreas, area, maxDim) while not pos[0]: # this should actually never loop more than once, but weird things happen ¯\_(ツ)_/¯ maxDim = maxDim * 2 - assert maxDim <= MAX_ATLAS_SIZE, &"Atlas gets bigger than {MAX_ATLAS_SIZE}, cannot pack textures" + assert maxDim <= MAX_ATLAS_SIZE, &"Atlas gets bigger than {MAX_ATLAS_SIZE}, cannot pack images" pos = find_insertion_position(assignedAreas, area, maxDim) assignedAreas.add pos[1] @@ -67,11 +67,11 @@ for j in i + 1 ..< assignedAreas.len: assert not assignedAreas[i].advanceIfOverlap(assignedAreas[j])[0], &"{assignedAreas[i]} and {assignedAreas[j]} overlap!" - result.atlas = Texture[T](width: maxDim, height: maxDim, data: newSeq[T](maxDim * maxDim)) - result.coords.setLen(textures.len) + result.atlas = Image[T](width: maxDim, height: maxDim, data: newSeq[T](maxDim * maxDim)) + result.coords.setLen(images.len) for rect in assignedAreas: for y in 0 ..< rect.h: for x in 0 ..< rect.w: assert result.atlas[rect.x + x, rect.y + y] == 0, "Atlas texture packing encountered an overlap error" - result.atlas[rect.x + x, rect.y + y] = textures[rect.i][x, y] + result.atlas[rect.x + x, rect.y + y] = images[rect.i][x, y] result.coords[rect.i] = (x: rect.x, y: rect.y) diff -r 4d97cfc4888b -r 4e465583ea32 semiconginev2/rendering.nim --- a/semiconginev2/rendering.nim Wed Jul 17 23:45:43 2024 +0700 +++ b/semiconginev2/rendering.nim Thu Jul 18 16:33:24 2024 +0700 @@ -75,7 +75,7 @@ type # type aliases SupportedGPUType = float32 | float64 | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64 | TVec2[int32] | TVec2[int64] | TVec3[int32] | TVec3[int64] | TVec4[int32] | TVec4[int64] | TVec2[uint32] | TVec2[uint64] | TVec3[uint32] | TVec3[uint64] | TVec4[uint32] | TVec4[uint64] | TVec2[float32] | TVec2[float64] | TVec3[float32] | TVec3[float64] | TVec4[float32] | TVec4[float64] | TMat2[float32] | TMat2[float64] | TMat23[float32] | TMat23[float64] | TMat32[float32] | TMat32[float64] | TMat3[float32] | TMat3[float64] | TMat34[float32] | TMat34[float64] | TMat43[float32] | TMat43[float64] | TMat4[float32] | TMat4[float64] - TextureType = TVec1[uint8] | TVec4[uint8] + PixelType = TVec1[uint8] | TVec4[uint8] # shader related types DescriptorSet*[T: object] = object @@ -106,7 +106,7 @@ size: uint64 rawPointer: pointer # if not nil, buffer is using mapped memory offsetNextFree: uint64 - Texture*[T: TextureType] = object + Image*[T: PixelType] = object width*: uint32 height*: uint32 interpolation*: VkFilter = VK_FILTER_LINEAR @@ -136,7 +136,7 @@ template ForDescriptorFields(shader: typed, fieldname, valuename, typename, countname, bindingNumber, body: untyped): untyped = var `bindingNumber` {.inject.} = 0'u32 for theFieldname, value in fieldPairs(shader): - when typeof(value) is Texture: + when typeof(value) is Image: block: const `fieldname` {.inject.} = theFieldname const `typename` {.inject.} = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER @@ -153,7 +153,7 @@ body `bindingNumber`.inc elif typeof(value) is array: - when elementType(value) is Texture: + when elementType(value) is Image: block: const `fieldname` {.inject.} = theFieldname const `typename` {.inject.} = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER @@ -331,14 +331,14 @@ return min(max(available), maxSamples) -proc `[]`*(texture: Texture, x, y: uint32): auto = - assert x < texture.width, &"{x} < {texture.width} is not true" - assert y < texture.height, &"{y} < {texture.height} is not true" +proc `[]`*(image: Image, x, y: uint32): auto = + assert x < image.width, &"{x} < {image.width} is not true" + assert y < image.height, &"{y} < {image.height} is not true" - texture[].imagedata[y * texture.width + x] + image[].imagedata[y * image.width + x] -proc `[]=`*[T](texture: var Texture[T], x, y: uint32, value: T) = - assert x < texture.width - assert y < texture.height +proc `[]=`*[T](image: var Image[T], x, y: uint32, value: T) = + assert x < image.width + assert y < image.height - texture[].imagedata[y * texture.width + x] = value + image[].imagedata[y * image.width + x] = value diff -r 4d97cfc4888b -r 4e465583ea32 semiconginev2/rendering/renderer.nim --- a/semiconginev2/rendering/renderer.nim Wed Jul 17 23:45:43 2024 +0700 +++ b/semiconginev2/rendering/renderer.nim Thu Jul 18 16:33:24 2024 +0700 @@ -59,8 +59,8 @@ (gpuArray.data.len * sizeof(elementType(gpuArray.data))).uint64 template size(gpuValue: GPUValue): uint64 = sizeof(gpuValue.data).uint64 -func size(texture: Texture): uint64 = - texture.data.len.uint64 * sizeof(elementType(texture.data)).uint64 +func size(image: Image): uint64 = + image.data.len.uint64 * sizeof(elementType(image.data)).uint64 template rawPointer(gpuArray: GPUArray): pointer = addr(gpuArray.data[0]) @@ -83,12 +83,12 @@ for theName, value in descriptorSet.data.fieldPairs: when typeof(value) is GPUValue: assert value.buffer.vk.Valid - elif typeof(value) is Texture: + elif typeof(value) is Image: assert value.vk.Valid assert value.imageview.Valid assert value.sampler.Valid elif typeof(value) is array: - when elementType(value) is Texture: + when elementType(value) is Image: for t in value: assert t.vk.Valid assert t.imageview.Valid @@ -135,7 +135,7 @@ pImageInfo: nil, pBufferInfo: addr(bufferWrites[^1]), ) - elif typeof(fieldValue) is Texture: + elif typeof(fieldValue) is Image: imageWrites.add VkDescriptorImageInfo( sampler: fieldValue.sampler, imageView: fieldValue.imageView, @@ -152,11 +152,11 @@ pBufferInfo: nil, ) elif typeof(fieldValue) is array: - when elementType(fieldValue) is Texture: - for texture in fieldValue: + when elementType(fieldValue) is Image: + for image in fieldValue: imageWrites.add VkDescriptorImageInfo( - sampler: texture.sampler, - imageView: texture.imageView, + sampler: image.sampler, + imageView: image.imageView, imageLayout: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, ) descriptorSetWrites.add VkWriteDescriptorSet( @@ -437,19 +437,19 @@ ) checkVkResult vkCreateSampler(vulkan.device, addr(samplerInfo), nil, addr(result)) -proc createTextureImage(renderData: var RenderData, texture: var Texture) = - assert texture.vk == VkImage(0), "Texture has already been created" +proc createVulkanImage(renderData: var RenderData, image: var Image) = + assert image.vk == VkImage(0), "Image has already been created" var usage = @[VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_USAGE_SAMPLED_BIT] - if texture.isRenderTarget: + if image.isRenderTarget: usage.add VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT - let format = GetVkFormat(elementType(texture.data) is TVec1[uint8], usage = usage) + let format = GetVkFormat(elementType(image.data) is TVec1[uint8], usage = usage) - texture.vk = svkCreate2DImage(texture.width, texture.height, format, usage) - renderData.images.add texture.vk - texture.sampler = createSampler(magFilter = texture.interpolation, minFilter = texture.interpolation) - renderData.samplers.add texture.sampler + image.vk = svkCreate2DImage(image.width, image.height, format, usage) + renderData.images.add image.vk + image.sampler = createSampler(magFilter = image.interpolation, minFilter = image.interpolation) + renderData.samplers.add image.sampler - let memoryRequirements = texture.vk.svkGetImageMemoryRequirements() + let memoryRequirements = image.vk.svkGetImageMemoryRequirements() let memoryType = BestMemory(mappable = false, filter = memoryRequirements.memoryTypes) # check if there is an existing allocated memory block that is large enough to be used var selectedBlockI = -1 @@ -473,35 +473,35 @@ checkVkResult vkBindImageMemory( vulkan.device, - texture.vk, + image.vk, selectedBlock.vk, renderData.memory[memoryType][selectedBlockI].offsetNextFree, ) renderData.memory[memoryType][selectedBlockI].offsetNextFree += memoryRequirements.size # imageview can only be created after memory is bound - texture.imageview = svkCreate2DImageView(texture.vk, format) - renderData.imageViews.add texture.imageview + image.imageview = svkCreate2DImageView(image.vk, format) + renderData.imageViews.add image.imageview # data transfer and layout transition - TransitionImageLayout(texture.vk, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) + TransitionImageLayout(image.vk, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) WithStagingBuffer( - (texture.vk, texture.width, texture.height), + (image.vk, image.width, image.height), memoryRequirements.size, stagingPtr ): - copyMem(stagingPtr, texture.data.ToCPointer, texture.size) - TransitionImageLayout(texture.vk, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) + copyMem(stagingPtr, image.data.ToCPointer, image.size) + TransitionImageLayout(image.vk, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) -proc UploadTextures*(renderdata: var RenderData, descriptorSet: var DescriptorSet) = +proc UploadImages*(renderdata: var RenderData, descriptorSet: var DescriptorSet) = for name, value in fieldPairs(descriptorSet.data): - when typeof(value) is Texture: - renderdata.createTextureImage(value) + when typeof(value) is Image: + renderdata.createVulkanImage(value) elif typeof(value) is array: - when elementType(value) is Texture: - for texture in value.mitems: - renderdata.createTextureImage(texture) + when elementType(value) is Image: + for image in value.mitems: + renderdata.createVulkanImage(image) proc HasGPUValueField[T](name: static string): bool {.compileTime.} = for fieldname, value in default(T).fieldPairs(): diff -r 4d97cfc4888b -r 4e465583ea32 semiconginev2/rendering/shaders.nim --- a/semiconginev2/rendering/shaders.nim Wed Jul 17 23:45:43 2024 +0700 +++ b/semiconginev2/rendering/shaders.nim Thu Jul 18 16:33:24 2024 +0700 @@ -1,4 +1,4 @@ -func GlslType[T: SupportedGPUType|Texture](value: T): string = +func GlslType[T: SupportedGPUType|Image](value: T): string = when T is float32: "float" elif T is float64: "double" elif T is int8 or T is int16 or T is int32 or T is int64: "int" @@ -35,7 +35,7 @@ elif T is TMat43[float64]: "dmat43" elif T is TMat4[float32]: "mat4" elif T is TMat4[float64]: "dmat4" - elif T is Texture: "sampler2D" + elif T is Image: "sampler2D" else: {.error: "Unsupported data type on GPU".} func VkType[T: SupportedGPUType](value: T): VkFormat = @@ -84,7 +84,7 @@ else: {.error: "Unsupported data type on GPU".} -func NumberOfVertexInputAttributeDescriptors[T: SupportedGPUType|Texture](value: T): uint32 = +func NumberOfVertexInputAttributeDescriptors[T: SupportedGPUType|Image](value: T): uint32 = when T is TMat2[float32] or T is TMat2[float64] or T is TMat23[float32] or T is TMat23[float64]: 2 elif T is TMat32[float32] or T is TMat32[float64] or T is TMat3[float32] or T is TMat3[float64] or T is TMat34[float32] or T is TMat34[float64]: @@ -94,7 +94,7 @@ else: 1 -func NLocationSlots[T: SupportedGPUType|Texture](value: T): uint32 = +func NLocationSlots[T: SupportedGPUType|Image](value: T): uint32 = #[ single location: - any scalar @@ -169,7 +169,7 @@ for descriptorName, descriptorValue in fieldPairs(descriptor): - when typeof(descriptorValue) is Texture: + when typeof(descriptorValue) is Image: samplers.add "layout(set=" & $descriptorSetIndex & ", binding = " & $descriptorBinding & ") uniform " & GlslType(descriptorValue) & " " & descriptorName & ";" descriptorBinding.inc @@ -189,7 +189,7 @@ elif typeof(descriptorValue) is array: - when elementType(descriptorValue) is Texture: + when elementType(descriptorValue) is Image: let arrayDecl = "[" & $typeof(descriptorValue).len & "]" samplers.add "layout(set=" & $descriptorSetIndex & ", binding = " & $descriptorBinding & ") uniform " & GlslType(default(elementType(descriptorValue))) & " " & descriptorName & "" & arrayDecl & ";" diff -r 4d97cfc4888b -r 4e465583ea32 tests/test_rendering.nim --- a/tests/test_rendering.nim Wed Jul 17 23:45:43 2024 +0700 +++ b/tests/test_rendering.nim Thu Jul 18 16:33:24 2024 +0700 @@ -128,7 +128,7 @@ Uniforms = object material: GPUValue[Material, UniformBuffer] - texture1: Texture[TVec4[uint8]] + texture1: Image[TVec4[uint8]] QuadShader = object position {.VertexAttribute.}: Vec3f @@ -161,21 +161,21 @@ uniforms1 = asDescriptorSet( Uniforms( material: asGPUValue(Material(baseColor: NewVec3f(1, 1, 1)), UniformBuffer), - texture1: Texture[TVec4[uint8]](width: 3, height: 3, data: @[R, G, B, G, B, R, B, R, G], interpolation: VK_FILTER_NEAREST), + texture1: Image[TVec4[uint8]](width: 3, height: 3, data: @[R, G, B, G, B, R, B, R, G], interpolation: VK_FILTER_NEAREST), ) ) uniforms2 = asDescriptorSet( Uniforms( material: asGPUValue(Material(baseColor: NewVec3f(0.5, 0.5, 0.5)), UniformBuffer), - texture1: Texture[TVec4[uint8]](width: 2, height: 2, data: @[R, G, B, W]), + texture1: Image[TVec4[uint8]](width: 2, height: 2, data: @[R, G, B, W]), ) ) AssignBuffers(renderdata, quad) AssignBuffers(renderdata, uniforms1) AssignBuffers(renderdata, uniforms2) - UploadTextures(renderdata, uniforms1) - UploadTextures(renderdata, uniforms2) + UploadImages(renderdata, uniforms1) + UploadImages(renderdata, uniforms2) renderdata.FlushAllMemory() var pipeline = CreatePipeline[QuadShader](renderPass = renderPass, samples = samples) @@ -218,7 +218,7 @@ MainSet = object renderSettings: GPUValue[RenderSettings, UniformBufferMapped] material: array[2, GPUValue[Material, UniformBuffer]] - texture1: array[2, Texture[TVec1[uint8]]] + texture1: array[2, Image[TVec1[uint8]]] OtherSet = object objectSettings: GPUValue[ObjectSettings, UniformBufferMapped] @@ -262,8 +262,8 @@ asGPUValue(Material(baseColor: NewVec3f(1, 0, 1)), UniformBuffer), ], texture1: [ - Texture[TVec1[uint8]](width: 2, height: 2, data: @[W, G, G, W], interpolation: VK_FILTER_NEAREST), - Texture[TVec1[uint8]](width: 3, height: 3, data: @[W, G, W, G, W, G, W, G, W], interpolation: VK_FILTER_NEAREST), + Image[TVec1[uint8]](width: 2, height: 2, data: @[W, G, G, W], interpolation: VK_FILTER_NEAREST), + Image[TVec1[uint8]](width: 3, height: 3, data: @[W, G, W, G, W, G, W, G, W], interpolation: VK_FILTER_NEAREST), ], ), ) @@ -283,7 +283,7 @@ AssignBuffers(renderdata, mainset) AssignBuffers(renderdata, otherset1) AssignBuffers(renderdata, otherset2) - UploadTextures(renderdata, mainset) + UploadImages(renderdata, mainset) renderdata.FlushAllMemory() var pipeline = CreatePipeline[QuadShader](renderPass = renderPass, samples = samples) @@ -324,7 +324,7 @@ type Uniforms = object - frameTexture: Texture[TVec4[uint8]] + frameTexture: Image[TVec4[uint8]] TriangleShader = object position {.VertexAttribute.}: Vec3f color {.VertexAttribute.}: Vec3f @@ -373,18 +373,18 @@ ) var uniforms1 = asDescriptorSet( Uniforms( - frameTexture: Texture[TVec4[uint8]](width: swapchain.width, height: swapchain.height, isRenderTarget: true), + frameTexture: Image[TVec4[uint8]](width: swapchain.width, height: swapchain.height, isRenderTarget: true), ) ) var uniforms2 = asDescriptorSet( Uniforms( - frameTexture: Texture[TVec4[uint8]](width: swapchain.width, height: swapchain.height, isRenderTarget: true), + frameTexture: Image[TVec4[uint8]](width: swapchain.width, height: swapchain.height, isRenderTarget: true), ) ) AssignBuffers(renderdata, mesh) AssignBuffers(renderdata, quad) - UploadTextures(renderdata, uniforms1) - UploadTextures(renderdata, uniforms2) + UploadImages(renderdata, uniforms1) + UploadImages(renderdata, uniforms2) renderdata.FlushAllMemory() var