Crashing while trying to load a sampler2DArray (Resolved)

vertexShader

#version 450


layout(set = 1, binding = 0) uniform UBO {
    mat4 mvp;
};
//first attribute (location -> 0)
layout(location = 0) in vec3 position;
layout(location = 1) in vec4 color;
layout(location = 2) in vec3 uv;
//first output attribute
layout(location = 0) out vec4 out_color;
layout(location = 1) out vec3 out_uv;
void main() {
    gl_Position = mvp * vec4(position, 1) ;
    out_color = color;
    out_uv = uv;
}

frag shader

#version 450

layout(location = 0) in vec4 color;
layout(location = 1) in vec3 uv;

layout(location = 0) out vec4 frag_color;

uniform layout(set = 2, binding = 0)sampler2DArray texsampler;
void main() {
    frag_color = texture(texsampler, uv)*color;
}

I have these two shaders causing a crash when I’m trying to load them with the following code

load_shader :: proc(code : []u8, shaderStage : sdl.GPUShaderStage, numUniformBuffers : u32, numSamplers : u32) -> ^sdl.GPUShader{
    return sdl.CreateGPUShader(gpuDevice, sdl.GPUShaderCreateInfo {
        code_size = len(code),
        code = raw_data(code),
        entrypoint = "main",
        format = {.SPIRV},
        stage = shaderStage,
        num_uniform_buffers = numUniformBuffers,
        num_samplers = numSamplers,
    })
}
vertexShader := load_shader(vertexShaderTempCode, .VERTEX, numUniformBuffers = 1, numSamplers = 0)
fragShader := load_shader(fragShaderTempCode, .FRAGMENT, numUniformBuffers = 1, numSamplers = 1)
vertexShaderTempCode := #load("Shaders/SDL_vertex_shader.spv.vert")
fragShaderTempCode := #load("Shaders/SDL_fragment_shader.spv.frag")

entire initialisation proc

initSDL :: proc() {
    context.logger = log.create_console_logger()
    defaultContext = context
    sdl.SetLogPriorities(.VERBOSE)
    sdl.SetLogOutputFunction(proc "c"(userdata : rawptr, category : sdl.LogCategory, priority : sdl.LogPriority, message : cstring) {
	context = defaultContext
	log.debugf("SDL {} [{}]: {}", category, priority, message)
    }, nil)

    initFlags : sdl.InitFlags = {.VIDEO}

    if !sdl.Init(initFlags) {
	fmt.print("SDL initialization failed \n")
    }
    windowFlags : sdl.WindowFlags = {.VULKAN, .RESIZABLE}

    mainWindow = sdl.CreateWindow("Sample DirectX example", i32(renderResolution.x), i32(renderResolution.y), windowFlags)
    rendererMain = sdl.GetRenderer(mainWindow)
    if mainWindow == nil {
	// tempIsRunning = false
	isRunning = false 
	fmt.print("window creation failed : ", sdl.GetError(), "\n")
	return 
    }
    else {
	fmt.print("renderer created successfully \n")
    }
    formats : sdl.GPUShaderFormat = {.SPIRV}//shader format for different flags

    //initializing GPU device
    gpuDevice = sdl.CreateGPUDevice(formats, true, "vulkan")

    if gpuDevice == nil {
	// tempIsRunning = false
	isRunning = false 
	fmt.print("GPU device creation failed : ", sdl.GetError(), "\n")
	return 
    }
    else {
	fmt.print("GPU device creation successful \n")
    }

    claim := sdl.ClaimWindowForGPUDevice(gpuDevice, mainWindow)
    if !claim {
	fmt.print("Window can't be claimed for the GPU device - Error : ", sdl.GetError(), "\n")
	return
    }
    else {
	fmt.print("claimed window for the GPU device successfully \n")
    }

    //crashing here. 
    vertexShader := load_shader(vertexShaderTempCode, .VERTEX, numUniformBuffers = 1, numSamplers = 0)
    fragShader := load_shader(fragShaderTempCode, .FRAGMENT, numUniformBuffers = 1, numSamplers = 1)

    imagesPathList : []cstring= {
	"Assets/Animations/PlayerCharacter/#1 T Orbon/TYPE 5/Walk/Walk_SpriteSheet.png",
	"Assets/Animations/PlayerCharacter/#1 T Orbon/TYPE 1/Walk/Walk_SpriteSheet.png",

	"Assets/Objects/Level 1.png",
	"Assets/Objects/UI Main.png",
    }
    initializeLayerMap()
    mainTextureArray,ok = loadAndPackImagesAndSendToGPU(imagesPathList)
    
    if !ok {
	fmt.print("failed to create a layered texture array Error : ", sdl.GetError(), "\n")
	return
    }
    else {
	fmt.print("successfully created a layered texture array\n")
    }
    fontMain = rl.LoadFontEx("Assets/Inconsolata-SemiBold.ttf", 128, nil, 0)
    fontTextureArray,ok = loadAndSendFontAtlasToGPU(fontMain)
    if !ok {
	fmt.print("failed to create a layered texture array Error : ", sdl.GetError(), "\n")
	return
    }

    
    vertexAttributes := []sdl.GPUVertexAttribute {
	{
	    location = 0,
	    format = .FLOAT3,
	    offset = u32(offset_of(VertexData, pos))
	},
	{
	    location = 1,
	    format = .FLOAT4,
	    offset = u32(offset_of(VertexData, color))
	},
	{
	    location = 2,
	    format = .FLOAT3,
	    offset = u32(offset_of(VertexData, uv))
	},
    }//shader configuring parameters

    

    

    
    indicesByteSize := maxSprites * 6 * size_of(u16)

    indexBufferMain = sdl.CreateGPUBuffer(gpuDevice, {
	usage = {.INDEX},
	size = u32(indicesByteSize),
    })
    // vertexBuffer
    vertexByteSize := maxSprites * 4 * size_of(VertexData)
    vertexBufferMain = sdl.CreateGPUBuffer(gpuDevice, {
	usage = {.VERTEX},
	size = u32(vertexByteSize),
    })
    //to send the data to the GPU 
    transferBufferMain = sdl.CreateGPUTransferBuffer(gpuDevice, {
	usage = .UPLOAD,
	size = u32(vertexByteSize + indicesByteSize),
    })

    
    textVertexByteSize := 2000 * 4 * size_of(VertexData)
    textVertexBufferMain = sdl.CreateGPUBuffer(gpuDevice, {
	usage = {.VERTEX},
	size  = u32(textVertexByteSize),
    })
    
    textIndexByteSize := 2000 * 6 * size_of(u16)
    textIndexBufferMain = sdl.CreateGPUBuffer(gpuDevice, {
	usage = {.INDEX},
	size  = u32(textIndexByteSize),
    })

    textTransferBufferMain = sdl.CreateGPUTransferBuffer(gpuDevice, {
	usage = .UPLOAD,
	size = u32(textVertexByteSize + textIndexByteSize),
    })
    
    

    textureSamplerOne = sdl.CreateGPUSampler(gpuDevice, {})
    textSampler = sdl.CreateGPUSampler(gpuDevice,(sdl.GPUSamplerCreateInfo{
	mag_filter = .NEAREST,
	min_filter = .NEAREST,
	address_mode_u = .CLAMP_TO_EDGE,
	address_mode_v = .CLAMP_TO_EDGE,
    }))
    
    pipelineCreateInfo := sdl.GPUGraphicsPipelineCreateInfo {
	vertex_shader = vertexShader,
	fragment_shader = fragShader,
	primitive_type = .TRIANGLESTRIP,

	vertex_input_state = {
	    num_vertex_buffers = 1,
	    vertex_buffer_descriptions = &(sdl.GPUVertexBufferDescription{
		slot = 0,
		pitch = size_of(VertexData),
		//input rate is also a parameter here
	    }),
	    num_vertex_attributes = u32(len(vertexAttributes)),
	    vertex_attributes = raw_data(vertexAttributes),
	},
	target_info = {
	    num_color_targets = 1,
	    color_target_descriptions = &(sdl.GPUColorTargetDescription{
		format = sdl.GetGPUSwapchainTextureFormat(gpuDevice, mainWindow),
		blend_state = {
		    enable_blend = true,
		    src_color_blendfactor = .SRC_ALPHA,
		    dst_color_blendfactor = .ONE_MINUS_SRC_ALPHA,
		    color_blend_op       = .ADD,
		    src_alpha_blendfactor = .ONE,
		    dst_alpha_blendfactor = .ONE_MINUS_SRC_ALPHA,
		    alpha_blend_op       = .ADD,
		    color_write_mask     = {.R, .G, .B, .A},
		},
	    }),
	},
    }

    texturePipelineOne = sdl.CreateGPUGraphicsPipeline(gpuDevice, pipelineCreateInfo)
    textPipeline = sdl.CreateGPUGraphicsPipeline(gpuDevice, pipelineCreateInfo)
    

    sdl.ReleaseGPUShader(gpuDevice, vertexShader)
    sdl.ReleaseGPUShader(gpuDevice, fragShader)

    windowSize : [2]i32;
    ok = sdl.GetWindowSize(mainWindow, &windowSize.x, &windowSize.y)
    if !ok {
	fmt.print("can't fetch window size - Error : ", sdl.GetError(), "\n")
    }
    

    lastTicks = sdl.GetTicks()
    
    
}

image loader

loadAndPackImagesAndSendToGPU :: proc(filePathList : []cstring) -> (textureArray : TextureArrayMain, ok : bool) {

    if len(filePathList) == 0 do return
    //2 separately maintained hash maps for the bigger atlas to fetch the source rectangle.
    imagePixels := make([dynamic][^]byte, context.temp_allocator)
    defer {
	for &img in imagePixels {
	    stb.image_free(img)
	}
	delete(imagePixels)
    }

    baseWidth : i32 
    baseHeight : i32 

    for &path,idx in filePathList {
	imageWidth : i32
	imageHeight : i32
	channels : i32 = 4
	imageData := stb.load(path, &imageWidth, &imageHeight, nil, channels)
	if imageData == nil {
	    fmt.print("failed to load image error \n")
	    return
	}
	if idx == 0 {
	    baseWidth = imageWidth
	    baseHeight = imageHeight
	}
	else if baseWidth != imageWidth || baseHeight != imageHeight {
	    fmt.print("dimension mismatch, all images must be of same height \n ")
	    stb.image_free(imageData)
	    return 
	}

	append(&imagePixels, imageData)
    }
    imageMaxWidth = baseWidth
    imageMaxHeight = baseHeight
    numLayers := u32(len(imagePixels))
    
    bytesPerLayer := u32(baseWidth * baseHeight * 4) //RGB alpha channels each.
    textureArray.texture = sdl.CreateGPUTexture(gpuDevice,{
	    type                 = .D2_ARRAY,
	    format               = .R8G8B8A8_UNORM,
            usage                = {.SAMPLER},
            width                = u32(baseWidth),
            height               = u32(baseHeight),
            layer_count_or_depth = numLayers,
            num_levels           = 1,
            sample_count         = ._1,
    })

    if textureArray.texture == nil {
	fmt.print(" unable to create GPU texture Error : ", sdl.GetError(), "\n")
	return 
    }

    transferBufferTemp := sdl.CreateGPUTransferBuffer(gpuDevice, {
	usage = .UPLOAD,
	size = bytesPerLayer * numLayers,
    })

    if transferBufferTemp == nil {
	fmt.print("failed to create a transfer buffer \n")
	
	return 
    }
    defer sdl.ReleaseGPUTransferBuffer(gpuDevice, transferBufferTemp)

    mappedObject := sdl.MapGPUTransferBuffer(gpuDevice, transferBufferTemp, false)

    for layer,idx in imagePixels {
	dest := rawptr(uintptr(mappedObject) * uintptr(idx) * uintptr(bytesPerLayer))
	mem.copy(dest, layer, int(bytesPerLayer)) //one by one copying the image 
    }
    sdl.UnmapGPUTransferBuffer(gpuDevice, transferBufferTemp)

    commandBuffer := sdl.AcquireGPUCommandBuffer(gpuDevice)
    copyPass := sdl.BeginGPUCopyPass(commandBuffer)

    id := 0
    for i in 0..<numLayers {
	
	sdl.UploadToGPUTexture(copyPass,
	    {transfer_buffer = transferBufferTemp, offset = u32(id) * bytesPerLayer},
	    {
		texture = textureArray.texture,
		layer = u32(id),
		w = u32(baseWidth),
		h = u32(baseHeight),
		d = 1,//depth
	    },
	    false
	)
	id += 1
    }
    sdl.EndGPUCopyPass(copyPass)
    _ = sdl.SubmitGPUCommandBuffer(commandBuffer)

    //setting sampler config configures the texture filtering from surface here including anisotropic and addressing mode
    textureArray.sampler = sdl.CreateGPUSampler(gpuDevice, {
	min_filter = .NEAREST,
	mag_filter = .NEAREST,
	mipmap_mode = .NEAREST,
	address_mode_u = .CLAMP_TO_EDGE,//for 0-1 UV,
	address_mode_v = .CLAMP_TO_EDGE,
	address_mode_w = .CLAMP_TO_EDGE,
    })

    textureArray.width = baseWidth
    textureArray.height = baseHeight
    textureArray.layers = numLayers

    fmt.print("uploaded the texture array successfully \n")
    return textureArray, true
}

I want to know why it’s crashing

Figured the crash out, it’s due to inaccurate loading in the memory, same issue with the font atlas present right below that.
is there a way to convert raylib’s image into a [^]byte buffer ? so it can be used more directly ? I think that’s causing crashes when I’m trying to use mem.copy on it. only reason I’m using that is to generate a font atlas to draw text.

UPDATE:
all the crashes have been fixed and textures are working, I just need to figure out a solution for text rendering which is consistent and works, if it means making font atlas by hand then I might as well do it