Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

AppGameKit Studio Chat / [SOLVED] vkCreateImage error -2

Author
Message
jd_zoo
5
Years of Service
User Offline
Joined: 12th May 2018
Location: Nova Scotia
Posted: 16th Jul 2023 17:42 Edited at: 16th Jul 2023 17:44
Getting this error with my game after opening and closing multiple levels: vkCreateImage error -2

This is reproducible on 2D-only sprite levels as well as 3D worlds. Really at a loss as to what else could be generating such an error. It will happen after loading approx. 11 x 2D levels, and less for 3D.

My only guess is there is a part of level load that uses GetImage() to generate an overlay graphic, maybe there is a buffer I should be clearing after doing this?


Any ideas would be greatly appreciated...


Edit - should add that the code references in the error message are random and can sometimes be pointing to empty rows of code.
Automation on Steam now!
Score Table Jr. on Google Play!

Attachments

Login to view attachments

The author of this post has marked a post as an answer.

Go to answer

SFSW
21
Years of Service
User Offline
Joined: 9th Oct 2002
Location:
Posted: 16th Jul 2023 17:56
That error typically occurs when the image just can't be loaded into memory for some reason. It can be more common on laptops that have a split display system (an integrated graphics unit and a dedicated/discreet GPU). Such systems often fail to properly enable the dedicated GPU for Vulkan and fallback on the integrated device, which typically has much more limited video memory resources and can run into image loading errors more frequently (among other limited resource related errors).

You could try testing with a much smaller image and in different formats just to explore for changes in behavior that might be memory related. If you are using a split display device system, you can also try force enabling the dedicated GPU for your project to test for changes (graphics settings in Windows is the easiest route).
blink0k
Moderator
11
Years of Service
User Offline
Joined: 22nd Feb 2013
Location: the land of oz
Posted: 16th Jul 2023 18:35
GetLastError() may shed some light on it as well
jd_zoo
5
Years of Service
User Offline
Joined: 12th May 2018
Location: Nova Scotia
Posted: 16th Jul 2023 19:49
Ok so GetLastError() is reporting "Surface Size: 1777x1000" - I'm going through graphics to see if anything matches with this. Possible a sprite sheet needs cropping I'm not sure yet.

Task Manager is showing memory usage jump by about double from ~900mb to ~1800 when the error occurs.
Automation on Steam now!
Score Table Jr. on Google Play!
SFSW
21
Years of Service
User Offline
Joined: 9th Oct 2002
Location:
Posted: 16th Jul 2023 20:14
That suggests the image is too big for the block of memory available. What are your system specs? In particular, the video card(s) specifications?
jd_zoo
5
Years of Service
User Offline
Joined: 12th May 2018
Location: Nova Scotia
Posted: 16th Jul 2023 21:37
Quote: "What are your system specs? In particular, the video card(s) specifications?"


Modest but shouldn't have problems with the small images I am using.
AMD Ryzen 5 3600
16GB RAM
NVIDIA GeForce RTX 2060
Win 10

From NVIDIA Control Panel:
NVIDIA System Information report created on: 07/16/2023 17:33:18

[Display]
DirectX version: 12.0
GPU processor: NVIDIA GeForce RTX 2060
Driver version: 535.98
Driver Type: DCH
Direct3D feature level: 12_1
CUDA Cores: 1920
Core clock: 1680 MHz
Memory data rate: 14.00 Gbps
Memory interface: 192-bit
Memory bandwidth: 336.05 GB/s
Total available graphics memory: 14291 MB
Dedicated video memory: 6144 MB GDDR6
System video memory: 0 MB
Shared system memory: 8147 MB
Video BIOS version: 90.06.3F.40.49
IRQ: Not used
Bus: PCI Express x16 Gen3
Device Id: 10DE 1F08 257119DA
Part Number: G160 0042


One culprit could some of the sprite sheets are large-ish (dimension wise) so I may move to break those up (a bunch of them are 3724x1024 but that doesn't seem like it should be the problem, all are under 1MB...)
Automation on Steam now!
Score Table Jr. on Google Play!
SFSW
21
Years of Service
User Offline
Joined: 9th Oct 2002
Location:
Posted: 16th Jul 2023 21:58 Edited at: 16th Jul 2023 22:03
This post has been marked by the post author as the answer.
The file size might be 1 MB, but the space in video memory is much greater. 1 MB of video memory works for a 512X512 image (using Horizontal X Vertical X 4-bytes). But 3724X1024 images require 15 MB each. So if you have a 'bunch' of those, it can add up to a lot. The final total would depend on what other images/graphics you are loading. You have 6 GB of inherent video memory to work with using your video card (with the OS consuming some of it already). I'd recommend firing up MSI Afterburner or similar program to gauge how much video memory you are consuming. You might find you are reaching the limit right at where the error occurs.
blink0k
Moderator
11
Years of Service
User Offline
Joined: 22nd Feb 2013
Location: the land of oz
Posted: 16th Jul 2023 22:54
3724x1024 is about 30mb in graphics card memory (Which is not compressed)
jd_zoo
5
Years of Service
User Offline
Joined: 12th May 2018
Location: Nova Scotia
Posted: 16th Jul 2023 23:02
SFSW you are 100% correct:


So this whole time I have been deleting the sprites on close of a level and not deleting the image that was used to create it. I had been thinking if I try to load an image a second time that AppGameKit would recognize it already in memory.

I guess perhaps I can add all the images to an array for deletion and run through them when I am calling the DeleteAllSprites() / DeleteAllText() / DeleteAllObjects() ? Or is there a better practice when handling this?

Thank you so much for the great help here!
Automation on Steam now!
Score Table Jr. on Google Play!
SFSW
21
Years of Service
User Offline
Joined: 9th Oct 2002
Location:
Posted: 17th Jul 2023 00:24 Edited at: 17th Jul 2023 00:28
Glad that was it. Indeed, if you load an image twice in two separate indexes, AGK/S will reserve the memory twice and not consolidate them because they may be the same. So it's best to load what you need only once and reuse the image(s) as may be needed from one index.

There are a variety of ways you can work around such a limitation. Probably the best approach is to load only what you need at the time, then be sure to delete anything you don't need any more to free up the memory when finished. It may be easier to do this with smaller image sets or even individual images loaded directly into indexes. Then this could be done dynamically during runtime or when changing levels/worlds, being careful to gauge the level of memory used at any given time to stay within target limits (3-4 GB might a good target for most players, if possible).

Segment your resources into smaller sets, if possible. That is, if you know you don't have a character on one level, avoid redundantly loading a sprite sheet that has that character on it. Set up your images for either the levels themselves or by type (ie walls, characters, weapons, etc). Then extract and populate image indexes with only the entities you need. You may find it easier to use a universal small size for such entities and then just load what you need directly into indexes, rather than extracting from sprite sheets (at least ones that have no or limited animations).

Sometimes I use rather large image sets, but often individual images. I've also used saved image bitmaps that I extract pixel data from to generate individual images in indexes (which I've found to be fast and memory efficient for certain operations). So a lot comes down to how you need to use the images and then considering how many duplications there may be while eliminating any wasted/redundant image data when not needed.

Edit: Oh, I forgot to mention one thing. Never delete image indexes that have been bound to a sprite or object as this can cause instability. Be sure to always delete all sprites or objects that have images linked to them first, then delete their linked images.
Virtual Nomad
Moderator
18
Years of Service
Recently Online
Joined: 14th Dec 2005
Location: SF Bay Area, USA
Posted: 17th Jul 2023 01:15 Edited at: 17th Jul 2023 01:27
i never have a lot of media in my stuff but sometimes do keep arrays that i dump level sprites, images, text ids, etc, into and use to delete on level completion. ui, common media, gets organized somewhere else.

there are a few commands to look at like GetUnassignedImages() (note the user-help HERE - and i see no way to retrieve those IDs?) if you haven't already and don't forget that we can retrieve the image ID of a given sprite via GetSpriteImageID() and other handy commands.

you also mentioned 3d early on so i'll mention a known memory leak with the bullet system in case you're using that, as well. i can't recall any other similar "leak" issues off the top of my head.
jd_zoo
5
Years of Service
User Offline
Joined: 12th May 2018
Location: Nova Scotia
Posted: 17th Jul 2023 22:17 Edited at: 17th Jul 2023 22:19
As I don't want to use the DeleteAllImages(), I am now rocking a couple new functions for loading images and sounds I want to delete on level close.




However the memory savings are not showing:



VN - thank you for that GetUnassignedImages(). Still counting 12 right now to track down on closing 3D World #1 but the big textures are all accounted for so not sure why memory is hanging around there...
Automation on Steam now!
Score Table Jr. on Google Play!
Virtual Nomad
Moderator
18
Years of Service
Recently Online
Joined: 14th Dec 2005
Location: SF Bay Area, USA
Posted: 17th Jul 2023 23:09 Edited at: 17th Jul 2023 23:15
i'm note sure that GetUnassignedImages() would include 3d object textures where they were not referenced in the help while sprite and text objects were explicitly?
Quote: "Returns the number of images currently loaded into the app but are not assigned to a sprite or text object"

it could be just be "sloppy" documentation but could easily be tested and worth looking at.

when i was contending with a (probably completely unrelated) issue, someone advised that windows may still allocate memory in anticipation of re-use? perhaps SFSW or someone else could advise but windows "management" may also be at play. as it stands now, are you experiencing negative results? crash, stutter, HDD/"memory paging" issues (i think that's what it's called ), etc?

note, my issue seemed to be RAM but this laptop's vid shares memory? i'm ignorant to all of this stuff but isn't RAM also in play in some way when it comes to graphics?
jd_zoo
5
Years of Service
User Offline
Joined: 12th May 2018
Location: Nova Scotia
Posted: 17th Jul 2023 23:57
This error has been on my radar for a while, but was one of those things I was kinda hoping would go away when fixing other bugs. But it's still here and I have a big update I want to release (which will likely happen anyway and I'll look to release a follow-up fix for this.)

The 3D Textures (albedo/normal/light) are all loaded and handled through one loader so easy to catch with my image_delete array. The bright idea was that any textures which got used in multiple levels would only need to be loaded once (saving microseconds of level loading time...) I am totally ok with abandoning that idea and freeing up RAM.

Currently the sprite images which are "common graphics" (menus / common game elements) get loaded on program launch, and I am attempting to swap in/out the level media. Hence me wanting to avoid the DeleteAllImages() on closing a level if possible.

As for the shared memory that doesn't seem to get touched, the crash is occurring when the GPU RAM fills and before it starts spilling over to shared RAM. I am going to run some tests on my old laptop with shared memory and see what kind of results I get.
Automation on Steam now!
Score Table Jr. on Google Play!
SFSW
21
Years of Service
User Offline
Joined: 9th Oct 2002
Location:
Posted: 18th Jul 2023 04:53 Edited at: 18th Jul 2023 04:55
I like to keep my media in grouped indexes for easier management and clearing when the time comes. Then it's just a matter of a 'for i' loop to clear things out when needed and in preparation for new media of the same type in the same indexes. Not saying anyone has to do it that way, but it's just something that helps me keep track of what resources I'm using and provides easy selective clean up when the time comes.

There can be some longer-term reserving of memory (whether more Windows related or AGK/S related, or both, I don't know). But I've usually found that to be limited to system memory when/if it does occur. Most of the time, video memory cleans up nicely when related resources are deleted. It may take a few 'sync()' cycles before the reduction in memory is noticeable after deletion, but eventually it falls back to free space. Also, if you leave anything image/sprite/mesh related behind that is still bound to a used image resource, plan on that memory to continue to be reserved. To free things up, any objects/sprites need to be deleted first, then the images that were bound to them, then reloading can begin with the images first, then the objects/meshes and reapplication of needed image data.

You shouldn't need to clear out all images when closing a level, just the ones you need to replace or remove entirely. And be sure to clear out any sprites/objects that they may be bound to first, then clear out the images. I've found that if I strictly follow that pattern, memory tends to free up nicely as needed. That's where group index sorting or a similar approach can come in handy to allow for quick removal and replacement during runtime or when loading.
jd_zoo
5
Years of Service
User Offline
Joined: 12th May 2018
Location: Nova Scotia
Posted: 19th Jul 2023 02:42
SFSW - Everything you are mentioning I thought I had been following so I feel good that my mindset is now in the right spot. I must have something in my program that is hanging on and I will need to re-visit how I am handling some of the loading.



Really appreciate all the great feedback here everyone, I will mark as solved as that error is absolutely a result of running out of GPU ram.
Automation on Steam now!
Score Table Jr. on Google Play!
blink0k
Moderator
11
Years of Service
User Offline
Joined: 22nd Feb 2013
Location: the land of oz
SFSW
21
Years of Service
User Offline
Joined: 9th Oct 2002
Location:
Posted: 19th Jul 2023 20:25
@jd_zoo - I'm sure you'll figure out a system that works well for your project. Your screenshot reminded me of another detail I wanted to mention. At times, it appears the deletion of a small set of objects/sprites and images may not see a significant drop in overall video memory use. AGK/S seems to reserve memory in fairly large chunks at a time (which might just be related to the size and type of media loaded at certain times). As a result, smaller deletions sometimes seem to not cross the threshold of the next block for clearing, resulting in little to no reduction in displayed video memory usage. However, when you reload new images and then sprites/objects of the same size, the memory may not increase significantly either. It's as though the memory is reserved, but still available for retasking with new media in the same address space. I've run into this a few times, but things always seem to eventually settle down after a while.

One step that helped me a while back was to print all of the used image indexes to the screen (also did the same with objects). That revealed a few surprises where image indexes I thought had been cleared weren't and some I didn't even recall loading were present. That help guide me to narrow down where some excess memory usage was and where I needed to clear out more indexes at certain points.
jd_zoo
5
Years of Service
User Offline
Joined: 12th May 2018
Location: Nova Scotia
Posted: 19th Jul 2023 23:06
Quote: "At times, it appears the deletion of a small set of objects/sprites and images may not see a significant drop in overall video memory use. AGK/S seems to reserve memory in fairly large chunks at a time (which might just be related to the size and type of media loaded at certain times). As a result, smaller deletions sometimes seem to not cross the threshold of the next block for clearing, resulting in little to no reduction in displayed video memory usage. However, when you reload new images and then sprites/objects of the same size, the memory may not increase significantly either. It's as though the memory is reserved, but still available for retasking with new media in the same address space. I've run into this a few times, but things always seem to eventually settle down after a while."


Again you are spot on @SFSW, I can now clearly see a pattern of loading new levels and the memory usage not changing for a time until that last chunk gets filled up. Also some of the levels cross must have the right balance and I can see it dump back down to almost the original program launch amount.

@blink thank you those are great, I can't believe I've overlooked this benchmarking command set... GetLoadedImages() / GetUnassignedImages() are extremely helpful to make sure everything gets cleared out ok I have made some serious progress here just last short while. Turns out I was in better shape than I had thought, just need to fix up the local level loading areas and my general graphics get to stay as-is.


Automation on Steam now!
Score Table Jr. on Google Play!

Login to post a reply

Server time is: 2024-05-02 21:28:01
Your offset time is: 2024-05-02 21:28:01