Author Topic: Let's talk about bmpman  (Read 14011 times)

0 Members and 1 Guest are viewing this topic.

Offline mjn.mixael

  • Cutscene Master
  • 212
  • Chopped liver
    • Steam
    • Twitter
Re: Let's talk about bmpman
Re Atlasing: Would the modder have to create the texutre atlas manually and then just tell FSO the layout or should FSO generate the atlas by itself?
Considering I don't even have the vaguest of clues what that even means, and considering the sheer list of stuff we already have to deal with during modding, my initial response to this is "Dear FRED, not more **** to deal with, please let FSO do everything for us!"

Yeah.. this.
Cutscene Upgrade Project - Mainhall Remakes - Between the Ashes
Youtube Channel - P3D Model Box
Between the Ashes is looking for committed testers, PM me for details.
Freespace Upgrade Project See what's happening.

 

Offline m!m

  • 211
Re: Let's talk about bmpman
That would favor using texture arrays which I also prefer but that will probably not happen until we have a Vulkan rendering engine because I'm not going near the OpenGL code :p

 

Offline z64555

  • 210
  • Self-proclaimed controls expert
    • Minecraft
    • Steam
Re: Let's talk about bmpman
Texture atlassing involves taking all the textures used by the engine and saving them as one big texture, thereby making it easy for the GPU to load because it doesn't have to hunt through the OS's filesystem to find every frame.

In regards to .EFF's, this would most likely mean having FSO or an external tool assemble the involved frames into a new texture no larger than 4096x4096, or whatever the maximum texture size the GPU supports. Although that's likely to cause issues with memory hogging if you did the maximum. That said, if speed and efficiency is the goal for animated textures, then an animation format such as .APNG, .ANI, .GIF would be better than trying to load individual textures. I personally view the .EFF's as a pre-production item rather than a final product.
Secure the Source, Contain the Code, Protect the Project
chief1983

------------
funtapaz: Hunchon University biologists prove mankind is evolving to new, higher form of life, known as Homopithecus Juche.
z64555: s/J/Do
BotenAlfred: <funtapaz> Hunchon University biologists prove mankind is evolving to new, higher form of life, known as Homopithecus Douche.

 

Offline The E

  • He's Ebeneezer Goode
  • Moderator
  • 213
  • Nothing personal, just tech support.
    • Steam
    • Twitter
Re: Let's talk about bmpman
Both solutions would have to be implemented engine-side, because there's no way in hell to get all the old animations converted.

Personally, I would much rather prefer using texture arrays, as they are a bit easier to implement (and do not involve the creation of massive intermediate textures with god knows how many pixels wasted).
If I'm just aching this can't go on
I came from chasing dreams to feel alone
There must be changes, miss to feel strong
I really need lifе to touch me
--Evergrey, Where August Mourns

 

Offline m!m

  • 211
Re: Let's talk about bmpman
Texture arrays can also be used to render submodels using multiple textures with only one draw call.

Also, exactly what problem should the texture atlases solve? As far as I can tell they are only really useful if different textures are used together which is pretty much the opposite to how head anis work where we only need one animation frame each frame. I guess they could be useful for particle effects as multiple frames of the same animation are typically used together.

 

Offline niffiwan

  • 211
  • Eluder Class
Re: Let's talk about bmpman
yeah, atlasing / arrays would be most useful for effects where there's the potential to have multiple instances displaying at the same time; e.g. impact anims, explosions, particles, etc.  Head ani's less so since as you say there's only one playing at a time (once you eliminate the issue of them using too many bmpman slots, or remove the slot limit)
Creating a fs2_open.log | Red Alert Bug = Hex Edit | MediaVPs 2014: Bigger HUD gauges | 32bit libs for 64bit Ubuntu
----
Debian Packages (testing/unstable): Freespace2 | wxLauncher
----
m|m: I think I'm suffering from Stockholm syndrome. Bmpman is starting to make sense and it's actually written reasonably well...

 

Offline niffiwan

  • 211
  • Eluder Class
Re: Let's talk about bmpman
I think I've got headanis (only) using only 3 bmpman slots each; not quite finished but close.  Here's my TODO list:

Code: [Select]
[X] only look for 3 frames to hold eff-anim instead of all frames (NEEDS TESTING)
[ ] reset 3rd frame back to _0001 after finishing playing anim (so we don't keeping using up slots)
[ ] update unload/release functions to handle the 3-frame anis
[x] see if we can release headani's between missions (don't just unload them) (looks like they are already released)
[x] correctly deal with EFFs that don't have all the frames AND are streaming - cap frames to "reset" to 3 (NEEDS TESTING)
[ ] deal with someone trying to use an EFF for streaming AND non-streaming (not sure where to store the "type" data just yet...)
[ ] Test Axem's headani script
[ ] Remove all temp debug code

Note that I'm pretty sure I can't help the effects animations (at least not easily), in the new deferred rendered these are handled differently to headanis so the same easy win doesn't apply to them. Atlasing could help, but that's a far bigger & more complicated change.

I think I found a far simpler way of "fixing" this. In short, head ani's shouldn't be loading all the frames into bmpman slots because they're streamed. I still need to thoroughly test this before creating a PR, to make sure my assumptions are all correct.  Then again; there was no anim data loaded here until after EFF headani's were implemented by Valathil anyway! (see 48e05, aa463 & cb1f81)
Creating a fs2_open.log | Red Alert Bug = Hex Edit | MediaVPs 2014: Bigger HUD gauges | 32bit libs for 64bit Ubuntu
----
Debian Packages (testing/unstable): Freespace2 | wxLauncher
----
m|m: I think I'm suffering from Stockholm syndrome. Bmpman is starting to make sense and it's actually written reasonably well...

 

Offline Axem

  • 211
Re: Let's talk about bmpman
*Axem goes to test right away

Initial findings: AMAZEMENT. Missions that crashed on load before, now load. Head anis play as expected, animated textures and effects still play!

Detailed findings:
(Reference: BMPMAN limit is 4750)
MissionBefore  After 
Beta Tester Counterattack36122357
Escape from HighschoolCrash2433
...Get RevengeanceCrash2902

The first mission is a "low weight" mission in head anis, its mostly just Holley (animated) taunting talking to a Beta Tester (static)
The other two are "heavy weight" missions. "Escape..." is head ani heavy (and still doesn't have all the art done) and it goes from crashing to 50% of the slots used!
"...Get Revengeance" is a long mission with tons of weapons and effects and talking and even then its just 61% filled.

Conclusion: Amazing results.
« Last Edit: September 15, 2015, 08:55:26 am by Axem »

 

Offline Spoon

  • 212
  • ヾ(´︶`♡)ノ
Re: Let's talk about bmpman
Urutorahappī!!

[02:42] <@Axem> spoon somethings wrong
[02:42] <@Axem> critically wrong
[02:42] <@Axem> im happy with these missions now
[02:44] <@Axem> well
[02:44] <@Axem> with 2 of them

 

Offline AdmiralRalwood

  • 211
  • The Cthulhu programmer himself!
    • Skype
    • Steam
    • Twitter
Re: Let's talk about bmpman
I wonder if this change alone would allow nuWoD missions to load.
Ph'nglui mglw'nafh Codethulhu GitHub wgah'nagl fhtagn.

schrödinbug (noun) - a bug that manifests itself in running software after a programmer notices that the code should never have worked in the first place.

When you gaze long into BMPMAN, BMPMAN also gazes into you.

"I am one of the best FREDders on Earth" -General Battuta

<Aesaar> literary criticism is vladimir putin

<MageKing17> "There's probably a reason the code is the way it is" is a very dangerous line of thought. :P
<MageKing17> Because the "reason" often turns out to be "nobody noticed it was wrong".
(the very next day)
<MageKing17> this ****ing code did it to me again
<MageKing17> "That doesn't really make sense to me, but I'll assume it was being done for a reason."
<MageKing17> **** ME
<MageKing17> THE REASON IS PEOPLE ARE STUPID
<MageKing17> ESPECIALLY ME

<MageKing17> God damn, I do not understand how this is breaking.
<MageKing17> Everything points to "this should work fine", and yet it's clearly not working.
<MjnMixael> 2 hours later... "God damn, how did this ever work at all?!"
(...)
<MageKing17> so
<MageKing17> more than two hours
<MageKing17> but once again we have reached the inevitable conclusion
<MageKing17> How did this code ever work in the first place!?

<@The_E> Welcome to OpenGL, where standards compliance is optional, and error reporting inconsistent

<MageKing17> It was all working perfectly until I actually tried it on an actual mission.

<IronWorks> I am useful for FSO stuff again. This is a red-letter day!
* z64555 erases "Thursday" and rewrites it in red ink

<MageKing17> TIL the entire homing code is held up by shoestrings and duct tape, basically.

 

Offline Spoon

  • 212
  • ヾ(´︶`♡)ノ
Re: Let's talk about bmpman
I was wondering about that too, nuWoD's headani's are between 30 to 45 frames. So it'd save like roughly 250-350 slots on the average mission.
I don't know if that would be enough or not, the majority of slots are probably eaten up by explosion effects and the like.
Urutorahappī!!

[02:42] <@Axem> spoon somethings wrong
[02:42] <@Axem> critically wrong
[02:42] <@Axem> im happy with these missions now
[02:44] <@Axem> well
[02:44] <@Axem> with 2 of them

 

Offline niffiwan

  • 211
  • Eluder Class
Re: Let's talk about bmpman
I thought the issues with nuWod occurred after multiple missions were played, one of the changes I made was to fix the streaming headani's from "leaking" slots.  i.e. each time an ani played it left a slot "in-use" that I don't think was ever cleaned up. Anyway, I thought a good acid test of the change would be to play through nuWod & see what happens, IIRC you have EFF mainhall anis, lots of effects and Axems headani script?
Creating a fs2_open.log | Red Alert Bug = Hex Edit | MediaVPs 2014: Bigger HUD gauges | 32bit libs for 64bit Ubuntu
----
Debian Packages (testing/unstable): Freespace2 | wxLauncher
----
m|m: I think I'm suffering from Stockholm syndrome. Bmpman is starting to make sense and it's actually written reasonably well...

 

Offline niffiwan

  • 211
  • Eluder Class
Re: Let's talk about bmpman
So, I managed to play through nuWoD last night with my latest change (now a PR) and MAX_BITMAPS set back to 4750. I had several crashes which reset bmpman usage but I didn't have any issues with missing textures or similar. Cautiously optimistic?

Here's a record of the bitmap usage at each mission load (yes, I had to repeat a few missions quite a few times before completing them, Contravention I & II, plus those pesky Cyrvans :))
Code: [Select]
Bmpman: 3814/4750 bitmap slots in use.
Bmpman: 3545/4750 bitmap slots in use.
Bmpman: 3413/4750 bitmap slots in use.
Bmpman: 3929/4750 bitmap slots in use.
Bmpman: 3848/4750 bitmap slots in use.
Bmpman: 3750/4750 bitmap slots in use.
Bmpman: 4051/4750 bitmap slots in use.
Bmpman: 3917/4750 bitmap slots in use.
Bmpman: 3949/4750 bitmap slots in use.
Bmpman: 3849/4750 bitmap slots in use.
Bmpman: 3864/4750 bitmap slots in use.
Bmpman: 3864/4750 bitmap slots in use.
Bmpman: 3877/4750 bitmap slots in use.
Bmpman: 3878/4750 bitmap slots in use.
Bmpman: 3879/4750 bitmap slots in use.
Bmpman: 4091/4750 bitmap slots in use.
(contravention II crash)
Bmpman: 3528/4750 bitmap slots in use.
Bmpman: 3639/4750 bitmap slots in use.
Bmpman: 3791/4750 bitmap slots in use.
Bmpman: 3868/4750 bitmap slots in use.
Bmpman: 3680/4750 bitmap slots in use.
Bmpman: 3844/4750 bitmap slots in use.
Bmpman: 3891/4750 bitmap slots in use.
Bmpman: 4188/4750 bitmap slots in use.
(battle cutscene crash, skipped watching it)
Bmpman: 3752/4750 bitmap slots in use.
Bmpman: 3774/4750 bitmap slots in use.
Bmpman: 3808/4750 bitmap slots in use.
Bmpman: 3822/4750 bitmap slots in use.
Bmpman: 3825/4750 bitmap slots in use.
Bmpman: 3826/4750 bitmap slots in use.
Bmpman: 3826/4750 bitmap slots in use.
Bmpman: 3826/4750 bitmap slots in use.
Bmpman: 3826/4750 bitmap slots in use.
Bmpman: 3826/4750 bitmap slots in use.
Bmpman: 3826/4750 bitmap slots in use.
Bmpman: 3826/4750 bitmap slots in use.
Bmpman: 3826/4750 bitmap slots in use.
Bmpman: 3826/4750 bitmap slots in use.
Bmpman: 3838/4750 bitmap slots in use.
Bmpman: 3838/4750 bitmap slots in use.
Bmpman: 3839/4750 bitmap slots in use.
Bmpman: 3839/4750 bitmap slots in use.
Bmpman: 3839/4750 bitmap slots in use.
Bmpman: 3839/4750 bitmap slots in use.
Bmpman: 3839/4750 bitmap slots in use.
Bmpman: 3628/4750 bitmap slots in use.
Bmpman: 3759/4750 bitmap slots in use.

(actually, reviewing this more closely there may be some other type of slot leaking, since the load counts for Contravention II before & after the crash were significantly different... so maybe that optimism is misplaced)
Creating a fs2_open.log | Red Alert Bug = Hex Edit | MediaVPs 2014: Bigger HUD gauges | 32bit libs for 64bit Ubuntu
----
Debian Packages (testing/unstable): Freespace2 | wxLauncher
----
m|m: I think I'm suffering from Stockholm syndrome. Bmpman is starting to make sense and it's actually written reasonably well...

 

Offline Spoon

  • 212
  • ヾ(´︶`♡)ノ
Re: Let's talk about bmpman
Hey, that's still below the limit, so definitely a success there! (As long as I don't add any new explosion effects :p )
Urutorahappī!!

[02:42] <@Axem> spoon somethings wrong
[02:42] <@Axem> critically wrong
[02:42] <@Axem> im happy with these missions now
[02:44] <@Axem> well
[02:44] <@Axem> with 2 of them

 

Offline Axem

  • 211
Re: Let's talk about bmpman
I might have mentioned this before, but I'll throw it out again:

Swifty mentioned awhile ago that the scripting system's bitmap unloading wasn't using the right method to permanently unload bitmaps between state changes or something. So bitmaps used in screens like the journal or visual novel scripts were still using bmpman slots when they're not supposed to. Maybe that is causing some of the slot leakage?

 

Offline niffiwan

  • 211
  • Eluder Class
Re: Let's talk about bmpman
Well, the texture.unload() LUA function calls bm_release; which is the correct function to completely free a bmp slot.

Code: [Select]
ADE_FUNC(unload, l_Texture, NULL, "Unloads a texture from memory", NULL, NULL)
{
int *idx;

if(!ade_get_args(L, "o", l_Texture.GetPtr(&idx)))
return ADE_RETURN_NIL;

if(!bm_is_valid(*idx))
return ADE_RETURN_NIL;

bm_release(*idx);

//WMC - invalidate this handle
*idx = -1;

return ADE_RETURN_NIL;
}

Also, these seems to be a garbage collection function for textures which will also bm_release them? I'm not sure if this is called at mission end or game end though.

Code: [Select]
ADE_FUNC(__gc, l_Texture, NULL, "Auto-deletes texture", NULL, NULL)
{
int idx;

if(!ade_get_args(L, "o", l_Texture.Get(&idx)))
return ADE_RETURN_NIL;

// Note: due to some unknown reason, in some circumstances this function
// might get called even for handles to bitmaps which are actually still in
// use, and in order to prevent that we want to double-check the load count
// here before unloading the bitmap. -zookeeper
if(idx > -1 && bm_is_valid(idx) && bm_bitmaps[bm_get_cache_slot(idx, 0)].load_count < 1)
bm_release(idx);

return ADE_RETURN_NIL;
}

Having said that, I can't see anywhere in the nuWoD VN/Journal scripts where the lua unload function is being called?

Code: [Select]
$ grep -iR unload Tables/ Scripts/
Tables/mv_exp-sct.tbm:   arr_D_eff[j]:unload()
Tables/proBox-sct.tbm: self.Head.Filename:unload()
Creating a fs2_open.log | Red Alert Bug = Hex Edit | MediaVPs 2014: Bigger HUD gauges | 32bit libs for 64bit Ubuntu
----
Debian Packages (testing/unstable): Freespace2 | wxLauncher
----
m|m: I think I'm suffering from Stockholm syndrome. Bmpman is starting to make sense and it's actually written reasonably well...

 

Offline Axem

  • 211
Re: Let's talk about bmpman
Right, I should be more clear. That setup works fine, 100%! (I've even done it that way on some new stuff and confirmed the BMPMAN slots get released properly)

The issue is with gr.drawBitmap() using a filename (which is what I was using 99% of the time) instead of a texture loaded with gr.loadTexture(). When gr.drawBitmap() with a filename gets called, the bitmap gets thrown into bmpman as expected (and also a ScriptImages vector). But then in game_leave_state() (freespace.cpp around line 5617), Script_system.UnloadImages() gets called to bm_unload() all of the images that were called with the scripting system. (Not bm_release() which seems to be the more correct way to do it?)

That's what I had sort of picked up anyway as a semi-literate coder reader. ;)

 

Offline AdmiralRalwood

  • 211
  • The Cthulhu programmer himself!
    • Skype
    • Steam
    • Twitter
Re: Let's talk about bmpman
Right, I should be more clear. That setup works fine, 100%! (I've even done it that way on some new stuff and confirmed the BMPMAN slots get released properly)

The issue is with gr.drawBitmap() using a filename (which is what I was using 99% of the time) instead of a texture loaded with gr.loadTexture(). When gr.drawBitmap() with a filename gets called, the bitmap gets thrown into bmpman as expected (and also a ScriptImages vector). But then in game_leave_state() (freespace.cpp around line 5617), Script_system.UnloadImages() gets called to bm_unload() all of the images that were called with the scripting system. (Not bm_release() which seems to be the more correct way to do it?)

That's what I had sort of picked up anyway as a semi-literate coder reader. ;)
Well, that should be as trivial as replacing the bm_unload() call with a bm_release() call.
Ph'nglui mglw'nafh Codethulhu GitHub wgah'nagl fhtagn.

schrödinbug (noun) - a bug that manifests itself in running software after a programmer notices that the code should never have worked in the first place.

When you gaze long into BMPMAN, BMPMAN also gazes into you.

"I am one of the best FREDders on Earth" -General Battuta

<Aesaar> literary criticism is vladimir putin

<MageKing17> "There's probably a reason the code is the way it is" is a very dangerous line of thought. :P
<MageKing17> Because the "reason" often turns out to be "nobody noticed it was wrong".
(the very next day)
<MageKing17> this ****ing code did it to me again
<MageKing17> "That doesn't really make sense to me, but I'll assume it was being done for a reason."
<MageKing17> **** ME
<MageKing17> THE REASON IS PEOPLE ARE STUPID
<MageKing17> ESPECIALLY ME

<MageKing17> God damn, I do not understand how this is breaking.
<MageKing17> Everything points to "this should work fine", and yet it's clearly not working.
<MjnMixael> 2 hours later... "God damn, how did this ever work at all?!"
(...)
<MageKing17> so
<MageKing17> more than two hours
<MageKing17> but once again we have reached the inevitable conclusion
<MageKing17> How did this code ever work in the first place!?

<@The_E> Welcome to OpenGL, where standards compliance is optional, and error reporting inconsistent

<MageKing17> It was all working perfectly until I actually tried it on an actual mission.

<IronWorks> I am useful for FSO stuff again. This is a red-letter day!
* z64555 erases "Thursday" and rewrites it in red ink

<MageKing17> TIL the entire homing code is held up by shoestrings and duct tape, basically.

 

Offline Bryan See

  • Has anyone really been far as decided to use even go want to do look more like?
  • 210
  • Trying to redeem, but under Tiger Parents
    • Skype
    • Steam
    • Twitter
Re: Let's talk about bmpman
I've tested this 64-bit build against the eleventh mission of the mod Shattered Stars, and I've got the BMPMAN assertion:

Code: [Select]
Assert: bm_bitmaps[bitmapnum].handle == handle
File: bmpman.cpp
Line: 683
Invalid bitmap handle 561502 passed to bm_get_info().
This might be due to an invalid animation somewhere else.


ntdll.dll! ZwWaitForSingleObject + 12 bytes
KERNELBASE.dll! WaitForSingleObject + 18 bytes
fs2_open_3_7_3_SSE2-DEBUG.exe! SCP_DumpStack + 354 bytes
fs2_open_3_7_3_SSE2-DEBUG.exe! WinAssert + 293 bytes
fs2_open_3_7_3_SSE2-DEBUG.exe! bm_get_info + 180 bytes
fs2_open_3_7_3_SSE2-DEBUG.exe! HudGaugeWeaponEnergy::render + 2820 bytes
fs2_open_3_7_3_SSE2-DEBUG.exe! hud_render_gauges + 555 bytes
fs2_open_3_7_3_SSE2-DEBUG.exe! hud_render_all + 37 bytes
fs2_open_3_7_3_SSE2-DEBUG.exe! game_render_hud + 150 bytes
fs2_open_3_7_3_SSE2-DEBUG.exe! game_frame + 957 bytes
fs2_open_3_7_3_SSE2-DEBUG.exe! game_do_frame + 231 bytes
fs2_open_3_7_3_SSE2-DEBUG.exe! game_do_state + 403 bytes
fs2_open_3_7_3_SSE2-DEBUG.exe! gameseq_process_events + 232 bytes
fs2_open_3_7_3_SSE2-DEBUG.exe! game_main + 787 bytes
fs2_open_3_7_3_SSE2-DEBUG.exe! WinMain + 328 bytes
fs2_open_3_7_3_SSE2-DEBUG.exe! invoke_main + 30 bytes
fs2_open_3_7_3_SSE2-DEBUG.exe! __scrt_common_main_seh + 346 bytes
fs2_open_3_7_3_SSE2-DEBUG.exe! __scrt_common_main + 13 bytes
fs2_open_3_7_3_SSE2-DEBUG.exe! WinMainCRTStartup + 8 bytes
KERNEL32.DLL! BaseThreadInitThunk + 36 bytes
ntdll.dll! RtlUnicodeStringToInteger + 595 bytes
ntdll.dll! RtlUnicodeStringToInteger + 542 bytes

I think BMPMAN should use only one same bitmap, instead of multiple same bitmaps. The same thing goes for animations.

And on-the-fly file/cache streaming should be implemented as well.
Bryan See - My FreeSpace Wiki User Page (Talk, Contributions)

Full Projects:
Shattered Stars

Campaigns:
Lost in the Mist - Cyrene vs. Psamtik
FreeSpace: Reunited

Ships:
GTS Hygeia, GTT Argo, SC Raguel

Tools:
FSO TC/Game template

I've been under attack by Tiger Parents like Jennifer Pan...

 

Offline The E

  • He's Ebeneezer Goode
  • Moderator
  • 213
  • Nothing personal, just tech support.
    • Steam
    • Twitter
Re: Let's talk about bmpman
Go do that then.

Seriously, Bryan, at this point you should know that we are aware of the problems and know the possible solutions; Unless you have actual contributions to make, your sort of "This feature/thing/whatever should be used" posts are somewhere between useless and irritating.
If I'm just aching this can't go on
I came from chasing dreams to feel alone
There must be changes, miss to feel strong
I really need lifе to touch me
--Evergrey, Where August Mourns