#Phobos - Vulkan abstraction library in Rust

1 messages · Page 3 of 1

night charm
#

Hopefully not

languid fern
#

Also, when does recreating happen? After the desc dies (due to the lifetime limit) or when its resources are dropped/changed?

limber rapids
#

on change (I stole penguin's design for my thing bleakekw)

night charm
#

When a draw is recorded it looks for and creates any descriptor sets it needs

languid fern
#

So lets say I bind buffer1 a single time per frame, does it re-create the desc set that contains buffer1 periodically or does it keep alive as long as the buffer1 resource is alive?

night charm
#

It keeps it alive

#

Every use resets the death clock

limber rapids
#

as long as you bind the exact same resource to the exact same binding it'll live

languid fern
#

Aight sweet exactly like my wgpu renderer as well

languid fern
#

So the desc set doesn't immediatly get deleted, only after N frames (where N is the desc set lifetime limit I assume?)

night charm
#

Yeah

#

And if you use it somewhere in that timeframe it’s kept alive for another N frames

languid fern
#

Awesome

hybrid pilot
languid fern
#

Les gooo

#

Ooh you have Rust reflection for ECS components*

#

Awesome

#

I always tell myself I'll implement it but I never do

hybrid pilot
hybrid pilot
#

It's a bit messy

#

Because it started out very simple

#

Hopefully I can clean that up eventually

languid fern
#

Holy shit even a scripting language

hybrid pilot
#

Didn't make that myself

#

It's wren

#

But yeah with reflection I was able to generate bindings on the fly

languid fern
#

That is super impressive

#

Starred it. Awesome work!

hybrid pilot
languid fern
#

Yep hopefully it goes well

#

Yea if you don't mind me imma just yoink most of your reflection code lol

hybrid pilot
#

No problem! Feel free to relicense it as well

#

Maybe I could turn that into a separate crate

languid fern
#

Heheheha time to work on phobos at 4 am in the morning

night charm
#

Lmao

languid fern
#

@night charm I submitted PR for exposing 3D texture stuff

night charm
#

Epic

#

Will take a look in a bit

languid fern
#

Thamks

iron shadow
#

we did it

#

idk how to fix the upside down bit KEKW

#

but its works

#

this is normalizing the world coordinates thank to getting the vertices

#

so ug

#

how do you generate normals

limber rapids
#

You don't

#

I mean you could

#

but why would you, just get them form the gltf

iron shadow
#

yeah but what if my model doesn't have normals

#

🤔

#

oh wait this is a bunch of cross products

#

i think?

languid fern
limber rapids
#

cross product of two edges of a triangle

iron shadow
#

oui

languid fern
#

'Tis how I do it

iron shadow
#

noooo

#

smh not multithreaded

#

smh doesn't use compute shaders that can scale across multiple gpus to create normals

languid fern
#

Oh yea it's CPU based sowwy

iron shadow
#

kekw it's fine lmaoo

night charm
night charm
languid fern
#

Yes I really should use rayon for that

iron shadow
#

sounds familiar

#

rayon?

languid fern
#

Makes rust multithreading super duper easy

iron shadow
#

is it liek uh

#

that one c++ lib

#

OpenMP

languid fern
#

Yepp

#

Paralellism made easy™️

iron shadow
#

can you multithread uploading to the gpu?

#

wait no you can't

#

well sorta?

#

you just gotta submit all the commands at once

languid fern
#

Yea I guess that would be possible. Idk how that would help though. I think GPU-GPU copy is already paralellised by the GPU itself

iron shadow
#

i say sorta that it's gpu wizardry if it wants to do that

languid fern
#

Yea I have not had to deal with complex command stuff like that yet

iron shadow
#

personally i feed my gpu 3 scoops of raw chicken meet + water bowl to get it

#

now im just waiting on penguin

#

to add the images

#

in the meantime

#

i'm gonna multithread everything i physically can

night charm
#

@languid fern added some comments

iron shadow
#

i just realized this isn't my channel

#

im so sorry

night charm
#

its fine

#

i wonder

#

can you have webhooks in a thread

languid fern
night charm
#

sad

languid fern
#

Sorry that the PR taking time is my first time doing this

night charm
#

no worries take your time lmao

#

im working on descriptor indexing rn

languid fern
#

Les fucking gooo

#

That's gonna make my life much easier when dealing with 3D texture voxel data and I'm all for it

night charm
#

yeah

night charm
#

ok lets run CI and merge

languid fern
#

Sweet

#

Tomorrow I'll work on getting other easy issues fixed

night charm
#

yeah i gotta actually work through a bunch of them soon

#

ill also try to make some progress on exposing more api features

#

@languid fern merged

languid fern
#

Yay

iron shadow
#

thank you nodle

#

for adding mip map levels

night charm
#

dont tell him his pr had a bug

#

i didnt see it either when reviewing tbh

#
let image_type = if extent.height == 1 && extent.depth == 1 {
            vk::ImageType::TYPE_1D
        } else if extent.height > 1 {
            vk::ImageType::TYPE_2D
        } else if extent.depth > 1 {
            vk::ImageType::TYPE_3D
        } else {
            return Err(anyhow::anyhow!("Image extents invalid"));
        }
#

if height > 1 and depth > 1 this will return 2D

#

while it should be 3D

iron shadow
#

huh i realized the examples don't have a way to access the window

night charm
#

yeah the example framework is kinda shit and really simple

iron shadow
#

im using it bleakekw

#

hmmm how to rewrite it so window is visiblde

#

oh god

#

how to do window resizinfg

night charm
#

Tbh the sample is not a good start to use as a beginning point for a project, I should make it better

iron shadow
#

yeah

#

you are remaking the entire context every frame bleakekw

night charm
#

I mean

#

It just copies some refcounted objects

#

Its not too bad

iron shadow
#

oh eh

#

but not ideal

#

hmm how am i supposed to do window resizing with this bleakekw

night charm
#

oops i broke the example compilation lol

#

fixed

#

thank you CI

iron shadow
iron shadow
#

Does phobos have a VkImageMemoryBarrier ?

#

I need it for mip mapping

#

unless there is another way

#

oh uh

#

@night charm I don't you guys added any blit functionality

night charm
night charm
# iron shadow Does phobos have a `VkImageMemoryBarrier `?
iron shadow
#

why is it everytime i searhc up blit

#

mf doesn't show up

night charm
#

no idea

iron shadow
#

oh im blind that is why bleakekw

night charm
#

i should try to remove the vk exports from docs.rs

#

its kinda annoying

limber rapids
#

Penguin, am I hallucinating or did you do something like Material ID = depth in depth buffer in your terrain thingy

night charm
#

bleakekw when did i do that

#

i dont think so

limber rapids
#

epic, I am hallucinating then

night charm
#

i just do normal mapped phong shading everywhere lmao

limber rapids
#

Why is it every time I try to read something Unreal does it requires unimaginable amounts of brain juice to comprehend

night charm
#

true

languid fern
#

I knew there had to be one there due to me coding that tate

night charm
#

its fine lol

iron shadow
#

🫡 unreal engine

languid fern
#

@night charm Shouldn't present, color, color_attachment... etc etc only be supported for the GraphicsDomain in PassBuilder?

night charm
#

that seems reasonable

languid fern
#

Also could help remove the Fails if this pass was not created using PassBuilder::render() case since it would be type checked

night charm
#

ooh

#

yeah I like that

#

Can you open an issue for that with the design label

languid fern
#

Yos

languid fern
#

For this to actually benefit the user we'd have to assume that all PassBuilders using the Graphics domain are going to be render passes

#

If you're fine with that assumption then yea it would work

#

But in the case of present it seems like it's not considered a render pass (unless that's a bug?)

#
pub fn present(name: impl Into<String>, swapchain: &VirtualResource) -> Pass<'cb, D, U, A> {
        Pass {
            name: name.into(),
            color: None,
            inputs: vec![PassResource {
                usage: ResourceUsage::Present,
                resource: swapchain.clone(),
                stage: PipelineStage::BOTTOM_OF_PIPE,
                layout: vk::ImageLayout::PRESENT_SRC_KHR,
                clear_value: None,
                load_op: None,
            }],
            outputs: vec![],
            execute: EmptyPassExecutor::new_boxed(),
            is_renderpass: false,
        }
    }
night charm
#

i see what you mean though yeah

#

i think thats a reasonable assumption

#

actually nevermind its not

#

you can have a compute pass in a frame for example, which would still use the graphics domain

languid fern
#

Yea hmm

#

Cause tbh I don't like that there's that panic that could occur

#

It feels like it could be typed out strongly and completely erased

night charm
#

it just returns an Err case so it doesnt necessarily panic, but I agree

#

ill do some pondering

languid fern
#

I'll submit issue about the other specializing domain stuff though

night charm
#

yep

torn kettle
#

you can present from compoot

#

potentially

night charm
#

right yeah

#

the is_renderpass flag is mostly used to emit a vkCmdBegin/EndRendering when executing the pass @languid fern

#

which obviously you dont need to present

iron shadow
#

big complicated words 🗣️ (what is going on)

night charm
#

design ponderings

torn kettle
#

more gazing into the vuk orb needed

languid fern
night charm
languid fern
#

Time to implement pr heheheha

#

This is what happens when you give summer break to a hs student with nothing to do over the summer

#

Too much time

languid fern
#

MSAA resolve is a graphics only thing or can it also be executed on compute?

night charm
#

graphics only

languid fern
#

Alright I'll specialize that too then

#

I never had to deal with SMAA before because I hate any form or type of AA

night charm
#

fsr2 ftw

languid fern
#

Kek

#

Idk how fsr2 is gonna look like with low poly terrain

night charm
#

Worth a try

#

Its pretty easy to set up

languid fern
#

Yos

#

I'm just worried that my executable size will go up (it's already at 13 mb for an empty scene, which is a lot)

#

Eh whatever

#

@night charm are you looking to make the API like fully error prone with good error / validity or is it too low level for that?
The reason why I'm asking is cause I have my engine graphics API that already does a bunch of error validation (especially when reflecting shaders) so I was wondering if I should keep those or just scrap them and rely on Phobos validation instead

night charm
#

Some validation is done but stuff like validation layers are still needed

#

Also I don’t plan to make the same guarantees as vulkano does

#

Phobos makes it harder to make mistakes but it’s still possible

#

What sort of validation do you do specifically

hybrid pilot
#

Please don't do expensive validation

night charm
#

Definitely not

hybrid pilot
#

I think the right approach is to make UB inexpressible with the api

#

But oviosuly a few asserts here and there won't hurt anything

night charm
#

Yeah that’s the main goal, but I don’t want to end up too much like vulkano

#

You can still cause validation errors, but if you do it should usually not crash everything

hybrid pilot
#

BTW yesterday I forgot to store the instance object and in went out of scope, then it sigsevved when it tried to allocate a buffer lol

night charm
iron shadow
#

what's wrong with Vulkano?

hybrid pilot
languid fern
#

I think I overcomplicated my validation layers a bit....

#

I should just assume whatever spv layout it is to always be valid ngl

#

Could've saved me lots of trouble

night charm
#

Not sure how desirable that is

hybrid pilot
#

It was my fault

#

I deserved that sigsev

languid fern
#

It should at least panic or err ngl

night charm
#

Its hard to check that

#

Mostly up to ash

#

If anything

hybrid pilot
#

Though technically safe APIs shouldn't cause this kind of crashes? But I wouldn't suggest doing anything other than marking things as unsafe

night charm
#

Technically not no

#

Ill see if I can make the instance refcounted too

languid fern
hybrid pilot
#

But it's one of those things where preventing it is actually really hard and can't really be done without compromises

languid fern
#

Absolutely yea

#

When I tried making a vulkan abstraction I was stuck trying to split up what should validation and what should be "high level" and "low level"

#

When I used wgpu I kinda disliked it because I did validation on top of what they already do so that's perf wasted

hybrid pilot
#

Wgpu has to do validation because it is meant to run in browsers I think

#

So security and what not

night charm
#

Its webgpu

#

and yeah supports meme platforms

hybrid pilot
#

Yeah sorry

night charm
#

No I mean wgpu implements webgpu

hybrid pilot
#

faces reality

night charm
#

Yeah vulkan is meant to be cross platform but mobile vk is quite different from desktop in terms of best practices and hw support

hybrid pilot
#

Yeah

night charm
#

So making a higher level api unifying those requires compromise

hybrid pilot
#

Though I get the appeal of running things in browsers

night charm
#

And a lot of vulkan programmers don’t care about these platforms, so it would be a shame to make them use a less powerful version of the api

hybrid pilot
#

And clearly vulkan is not acceptable there

night charm
#

Yeah

night charm
#

If your app should run in a browser wgpu is good but that’s not always the case

hybrid pilot
night charm
#

Fair

hybrid pilot
#

Like tiling GPUs are interesting

#

And optimizing things for it is an interesting problem

night charm
#

Its just not my problem KEKW

hybrid pilot
#

But the other stuff that I said is not

#

Dealing with broken drivers is not an interesting problemn

night charm
#

That too

languid fern
#

So it begins...

night charm
#

Big pog

languid fern
#

At least now when I find a bug I can just literally fix it and continue devving unlike waiting for months for WGPU to fix it for all platforms

hybrid pilot
#

Lol

night charm
#

Yeah we go fast here

hybrid pilot
#

Yeah Phobos is small

languid fern
#

12k lines for what it does is actually pretty darn impressive

hybrid pilot
#

Yeah

#

Also it's fairly direct

night charm
#

Is it 12k already

#

I think it was like 6-7k not long ago

hybrid pilot
#

Like if I jump to the definition of a function it's often ash code

languid fern
hybrid pilot
#

Vulkano is like 96k

languid fern
#

My engine itself is at 20k kek

night charm
#

I might have to do a round of cleaning up internals at some point

languid fern
night charm
#

wtf

languid fern
#

I don't believe that

#

Dead ass

hybrid pilot
#

Mine was 30k

#

Before deleting the renderer

#

Now idk

#

But I will go back up and past 30k eventually

#

It will be less lines with Phobos

#

But I'll do more stuff

night charm
#

I gotta keep an eye on your usage’s of the lib so I can see what needs to change

hybrid pilot
#

One of the things is that I want to go bindless right from the start

night charm
#

That should be possible now

hybrid pilot
#

Oh nice

#

And I'll be glad to contribute and what not

night charm
languid fern
languid fern
#

@night charm I have a few questions if you don't mind me asking

night charm
#

go ahead

languid fern
#

ComputePipelineBuilder::persistent just makes the pipeline alive forever and it states that the same method isn't available on PipelineBuilder because they need to rebuilt constantly. What exactly a pipeline to be rebuilt?

night charm
#

when the render target size changes

languid fern
#

Oh there's no way to use dynamic state for that?

night charm
#

its somewhat annoying because theyre closely linked to renderpasses, even with dynamic rendering theres still some state info

languid fern
#

Ahh I see

#

Alright that's fine

night charm
#

honestly its kind of a hack

#

compute pipelines typically dont rebuild unless you do shader hot reloading stuffs

#

so its fine to just keep them alive

languid fern
#

Yep

#

Other question:

#

Is this safe or are there fields that can't be shared?

night charm
#

Surface, Instance and PhysicalDevice are not synced but access to them should be read-only anyway so its fine

#

oh swapchain too

#

you dont need to store the swapchain though

#

the framemanager holds it for you

languid fern
#

Oh sweet cool

night charm
#

in my project I distinguish between SharedContext and "the rest"

languid fern
#

I see I see

#

Yea I'll do the same

#

And a final question:

#

Is there a reason why FrameManager's new_frame takes in a callback instead of separating it into two distinct functions: aqcuire and present?

night charm
#

because it relies on sync between the two

#

and this frame sync is the same for every application so it makes sense to handle it there imo

languid fern
#

I see alright thank you

night charm
languid fern
#

Uhhhhhh this looks cursed to me

#

fn get_buffer_usage_flags(device: &Device) -> vk::BufferUsageFlags {
    let mut usage = vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS
        | vk::BufferUsageFlags::INDEX_BUFFER
        | vk::BufferUsageFlags::INDIRECT_BUFFER
        | vk::BufferUsageFlags::STORAGE_BUFFER
        | vk::BufferUsageFlags::STORAGE_TEXEL_BUFFER
        | vk::BufferUsageFlags::TRANSFER_DST
        | vk::BufferUsageFlags::TRANSFER_SRC
        | vk::BufferUsageFlags::UNIFORM_BUFFER
        | vk::BufferUsageFlags::UNIFORM_TEXEL_BUFFER
        | vk::BufferUsageFlags::VERTEX_BUFFER;
    if device.is_extension_enabled(ExtensionID::AccelerationStructure) {
        usage |= vk::BufferUsageFlags::ACCELERATION_STRUCTURE_STORAGE_KHR
            | vk::BufferUsageFlags::ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_KHR;
    }
    if device.is_extension_enabled(ExtensionID::RayTracingPipeline) {
        usage |= vk::BufferUsageFlags::SHADER_BINDING_TABLE_KHR;
    }

    usage
}
#

Is this okay for performance?

#

I mean if it works it works but I don't see the reason why setting all flags would be needed

#

Unless this is another trick of BDA where you just don't give a shit and it just somehow works out

night charm
#

for buffers it doesnt matter

#

so might as well simplify the api and remove the parameter entirely

languid fern
#

So all that extra validation that I had in my API was pretty much useless

night charm
#

rip

languid fern
#

WGPU kept complaining about it so I wrapped it up

#

Still surprised how there's no perf impact

night charm
#

*on desktop

#

*on half decent drivers

languid fern
#

Eh good enough

night charm
#

yeah

hybrid pilot
#

I think uniform buffers could be different on nvidia

#

Though not sure if the flags matter for it

night charm
#

yeah the flags shouldnt matter

#

but when using them in a shader they have a fast path yes

hybrid pilot
night charm
#

yeah but its more of a cache not a permanent memory location afaik

#

so the usage flags shouldnt affect it much

hybrid pilot
#

With and is just memory accessed with a different instructions with goes through a dedicated read only cache afaik

night charm
#

yep

hybrid pilot
#

I guess the driver loads the cbufs

#

And if it runs out of them uses the cache

night charm
#

maybe

#

i dont know enough of those details

languid fern
#

I'm going to re-expose the usages (for my downstream fork for custom engine) just because I can't trust my 1050 drivers kek

#

I would rather do that then change my whole API and then realize that I fucked up and gotta re-expose them again

iron shadow
#

@night charm Quick question, is there a way for me to modify the subresource range of a given image?

#

I can't seem to change base level + base layer

#

which I kinda need

languid fern
#

For image views you mean?

iron shadow
#

Yeah

#

Image views @languid fern

#

kekw am i illterate

languid fern
#

Oh then yea I submitted a PR for dat

iron shadow
#

hmm what to do until then

iron shadow
#

is it merged...?

languid fern
#

Yes yes it's merged

#

I got confused for a sec lol

iron shadow
#

Call me tripping

#

but

#
pub fn view(
        &self,
        create_info: ImageViewCreateInfo,
    ) -> Result<ImageView> {
        let ImageViewCreateInfo {
            aspect,
            view_type,
            base_mip_level,
            level_count,
            base_layer,
            layers
        } = create_info;

        // TODO: Validate args
        let info = vk::ImageViewCreateInfo {
            s_type: vk::StructureType::IMAGE_VIEW_CREATE_INFO,
            p_next: std::ptr::null(),
            flags: Default::default(),
            image: self.handle,
            view_type,
            format: self.format,
            components: vk::ComponentMapping::default(),
            subresource_range: vk::ImageSubresourceRange {
                aspect_mask: aspect,
                base_mip_level,
                level_count: match level_count {
                    Some(count) => count,
                    None => self.mip_levels - base_mip_level,
                },
                base_array_layer: base_layer,
                layer_count: match layers {
                    Some(count) => count,
                    None => self.layers - base_layer,
                },
            },
        };

        let view_handle = unsafe { self.device.create_image_view(&info, None)? };
        #[cfg(feature = "log-objects")]
        trace!("Created new VkImageView {view_handle:p}");
        Ok(ImageView(Arc::new(ImgView {
            device: self.device.clone(),
            handle: view_handle,
            image: self.handle,
            format: self.format,
            samples: self.samples,
            aspect,
            size: self.size,
            base_level: 0,
            level_count: self.mip_levels,
            base_layer: 0,
            layer_count: self.layers,
            id: ImgView::get_new_id(),
        })))
    }
#

base_level: 0 is defaulted to zero

languid fern
#

Oh yea bug

#

Most probably

#

When I implemented it I only changed the subresource_range values I completely forgot about ImgView kek

iron shadow
#

lets see if i can do a hack

#

god images are annoying asf

#

im getting so many flags errors 💀

languid fern
#

Oh bruh actually

#

Validation errors?

iron shadow
#

why :(

#

but yeah

#
VUID-vkCmdBlitImage-dstImageLayout-00227 ] Object 0: handle = 0x26c8cceefd0, type = VK_OBJECT_TYPE_COMMAND_BUFFER; | MessageID = 0xad2bdfa6 | vkCmdBlitImage: Layout for VkImage 0x9fde6b0000000014[Unnamed Image] is VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL but can only be VK_IMAGE_LAYOUT_GENERAL or VK_IMAGE_LAYOUT_GENERAL. The Vulkan spec states: dstImageLayout must be VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL (https://vulkan.lunarg.com/doc/view/1.3.250.1/windows/1.3-extensions/vkspec.html#VUID-vkCmdBlitImage-dstImageLayout-00227)
#

"maybe changing the flags will work" (it breaks it more)

#

it seems like the issue down to the fact that

#

base_layer isn't being set

languid fern
#

Damn

#

I thought it'd at least tell you or something kek

#

Yea alright I'll submit a bug fix PR

iron shadow
#

as it is defaulting to zero

#

which would explain why i'm also getting that texture

#

i think there is anothe property we need too

#

@languid fern base_level + base_layer. Those two aren't being set whatsoever kek

languid fern
#

Yep

#

I implemented that for the subresource range

#

But again I forgor to put it for the ImgView wrapper

iron shadow
#

forgor

#

"this wouldn't have gone through with test cases" 🤓

#

actually tests can't even help here KEKW

#

well idfk what to do then. hmmmmmm disable mips then try to get normal textures working

languid fern
#

this wouldn't have gone wrong if I didn't decide to code at 5 am

languid fern
#

It's such a dumb bug as well kek

iron shadow
#

eh who cares

#

tbf you had to go through a lot of defaults KEKW

languid fern
#

@iron shadow Can you do me a favor and check if there's this when you go to the phobos-rs repo?

#

I hope it's a thing only locally vislbe otherwise that'd be annoying as fuck

iron shadow
#

let me see

#

no

languid fern
#

Cool

iron shadow
#

I think we should uh

#

wait nvm we already are

#

I was gonna say avoid using hardcoded stuff and instead put it all into our structs

#

then expose some method that will let you straight up send the struct them without phobos doing any magic to it

languid fern
#

Like raw VK structs?

iron shadow
#

yeah

night charm
#

Oops that is missing

#

Anyway I have been thinking about proper tests but it’s hard

night charm
iron shadow
night charm
#

Yeah that might also be a thing

#

But running examples is more effort than running automated tests

languid fern
#

Right

night charm
#

fixed the image view issue @iron shadow @languid fern

languid fern
#

Awesome

night charm
#

im not getting any validation layer errors on my end when resizing in the samples

night charm
#

first time im ever using this feature lmao

night charm
#

no

iron shadow
#

I’ll try updating my drivers

night charm
#

your pc has a skill issue clearly

iron shadow
limber rapids
#

krill issue

#

pengu could you do me a lil favor

#

do you have bistro or sponza

iron shadow
#

Isn’t Sponza on the gltf examples site?

night charm
#

probably somewhere in my downloads folder

#

@limber rapids uploading rn

#

i have the entire gltf sample repo cloned in my downloads apparently

limber rapids
#

could you do this real quicc

#

#general message

night charm
#

i dont have an engine

limber rapids
#

ebic

#

your terrain thingy doesn't count as a rendering engine?

night charm
#

it doesnt load models yet

hybrid pilot
#

Penguin do you have anything to compile glsl shaders?

#

Or do you just use glslc manually?

night charm
#

not in phobos

#

i use shaderc

hybrid pilot
#

I see

#

Guess I'll make a build.rs that builds them

#

Then I can include_bytes the spv

night charm
#

i do something like that yeah

iron shadow
#

@night charm This is weird wtf

#

I'm getting the error despite a driver update

night charm
#

that is weird

iron shadow
#
 ERROR phobos::core::debug             > [VALIDATION]: VUID-VkSwapchainCreateInfoKHR-imageExtent-01274 (2094043421): Validation Error: 
[ VUID-VkSwapchainCreateInfoKHR-imageExtent-01274 ] Object 0: handle = 0x1dc6800e4d0, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0x7cd
0911d | vkCreateSwapchainKHR() called with imageExtent = (1748,768), which is outside the bounds returned by vkGetPhysicalDeviceSurface
CapabilitiesKHR(): currentExtent = (768,768), minImageExtent = (768,768), maxImageExtent = (768,768). The Vulkan spec states: imageExte
nt must be between minImageExtent and maxImageExtent, inclusive, where minImageExtent and maxImageExtent are members of the VkSurfaceCa
pabilitiesKHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface (https://vulkan.lunarg.com/doc/view/1.3.2
50.1/windows/1.3-extensions/vkspec.html#VUID-VkSwapchainCreateInfoKHR-imageExtent-01274)
#

I'm on a newer Vulkan version

#

that could be why?

night charm
#

this error makes no sense to me though

#

if you resize then minExtent/maxExtent should allow that new size

iron shadow
#

winit related issue then?

night charm
#

I dont think so

iron shadow
#

this is odd huh

#

eh well it works resizing. ill just ignore it KEKW

night charm
#

if it works its probably fine

iron shadow
#

Hmmm so for descriptor indexing, is it really just an array of images that you can submit to your shader?

night charm
#

yes

iron shadow
#

oh KEKW well i need a way to "compress" the indices of my images for my shader glsl then
That probably doesn't make sense but like if my asset gives me something like:
0 -> Image
4 -> Image
It should go into
0 -> Image
1 -> Image
Because arrays can't have empty space between them

night charm
#

not the entire array needs to be bound but currently i dont support leaving gaps

#

descriptor indexing allows for those gaps technically but i dont recommend it

iron shadow
#

yeah sounds like a bad idea for undefined behavior

hybrid pilot
#

Doing it with build_rs didn't work out for me because my engine is a library and I found no simple way of storing a file from build.rs and accessing it later.
This works regardless

#

It can be even used by the user of the engine

#

I don't mind anyone borrowing this, it was rather boring to write

#

(Some things could be improved ofc, like not using format for paths lol)

night charm
#

Looks pretty neat

#

I might use it

hybrid pilot
night charm
#

Its pretty copy pasteable I think KEKW

hybrid pilot
#

Yeah lol it's not much code

languid fern
#

Ooh yea that's definitely interesting

hybrid pilot
#

Btw penguin is it possible to get access to descriptor sets directly? Since you currently don't support updating them for image arrays I though I could temporarily just take my old code to do it

night charm
#

i actually made it fully private a few releases ago

#

do you need to frequently update a large array?

hybrid pilot
languid fern
#

Question: Is support for mobile GPUs not intended at all?

night charm
#

yeah but do the actual images inside that array change often

night charm
#

a lot of stuff depends on modern features and assumes dynamic rendering is available

hybrid pilot
night charm
#

They dont get recreated if the contents are the same

#

So it should only happen when you load in a new texture

hybrid pilot
#

Yeah but say I add a new model, so I need a new texture in the array

#

Sure it happens every few frames, but basically it means stuttering

#

Unless I did it asynchronously I guess?

night charm
#

You can hack around doing it asynchronously but theres probably a good argument for implementing updates for arrays at least

hybrid pilot
#

Yeah

#

Updating just an element is super fast

#

Basically a memcpy inside radv iirc

night charm
#

I think this should be simple enough to do without changing any of the public api

hybrid pilot
#

Mmm I'll take a look

#

When I have time, maybe I can make another PR

night charm
#

Well maybe not simple but doable with some small refactors

#

Sure

hybrid pilot
#

I suppose sync is not handled for that kind of resource right?

night charm
#

Yeah theres no sync for descriptor sets

#

Ah that might be an issue

hybrid pilot
#

Great

hybrid pilot
night charm
#

Well the naive method of doing an update would mean youre overwriting the set while its possibly in use on the gpu

#

So you'd probably need to double buffer it

hybrid pilot
#

Yeah there are ectentions to do that "safely"

night charm
#

Ooh, nice

#

If desktop support for that is good we can easily enable that

hybrid pilot
#

Like "nothing will explode so long as the shader is not accessing that stuff"

night charm
#

Right

hybrid pilot
#

Wait that's not safe lol

night charm
#

Good enough

hybrid pilot
#

I might have been misleading

#

Let me find it

night charm
#

Yeah

limber rapids
#

penguin are you still on vacation

night charm
#

I got back last night

limber rapids
#

good

#

then I commission you something

night charm
limber rapids
night charm
limber rapids
#

I promise it'll look good

night charm
#

Yeah sure give me 5 minutes

hybrid pilot
#

UE does raynarching through the shadow nap

limber rapids
#

ye but light leaking

night charm
#

Yeah looks kinda nice

limber rapids
#

My idea was using blocker info to deduce optimal cone size, ray step and clipmap distance

#

if blocker is big then ray step can be big

languid fern
#

Kinda but not kinda

limber rapids
#

I have a beautiful drawing

#

hold on

#

#1090390868449558618 message

#

There it is

#

admire my flawless drawing skills

languid fern
#

Wait but question

#

How would the ray stop at the plane if the shadow depth buffer value was overwritten

#

Unless it's not just normal shadow mapping

limber rapids
#

You don't overwrite the shadow map

languid fern
#

And somehow retains info about stuff that has been obstructed

hybrid pilot
#

Uhm I think you just need the VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT flag to do what I said

limber rapids
#

You shrimply sample the shadow and then raymarch towards the blocker

#

The farther away you are the less chance there is for the ray to hit the blocker

#

thus contact hardening

languid fern
#

Ohhh I see now

#

Oh yea that's pretty smart

#

I might implement that

limber rapids
#

There's only one issue

#

light leaking bleakekw

night charm
hybrid pilot
#

Thoug When entries are overwritten it's kinda unsafe and you need to track what could be potentially used by in flight work

#

Do you think that should be up to the user?

#

I wonder how other graphs handle this

languid fern
#

@limber rapids #general I don't want to floos Phobos thread again bleakekw

limber rapids
#

ye true KEKW

night charm
#

We can support just appending elements I guess

hybrid pilot
#

Mmm that's too limited

night charm
#

it handles the case of new textures being added

hybrid pilot
#

Yeah but eventually you run out of slots

#

Mmm

#

I guess we should just ask one of the many authors of render graphs what they do?

night charm
#

onto #1025797519550185533 we go

hybrid pilot
#

Do I ask or do you ask?

#

Makes more sense doe me to do it I guess

night charm
#

You can go ahead, you seem to know more about the specific requirements

hybrid pilot
#

👍

#

OK dunno if you read

#

But basically everything is bindless for them

#

And any live resource exists within the descriptor set. So long as the resource lifetime is handled correctly so is the descriptor set then I guess

#

That makes a lot of sense

#

I might have already been explained this. It doesn't sound new to me. In any case this is not how ohobos does things which is unfortunate

#

But not all hope is lost

#

I guess bindless resourced can be their own thing and work that way

#

So the rest of the api remains the same?

night charm
#

Hmm that is an interesting approach yeah

hybrid pilot
#

I guess I'll dive deeper into your codebase when I have time and see if I can come up with a sane way if implementing this

night charm
#

yeah ill do some thinking and tinkering too

#

Its also possible to solve the sync issue by storing a frame id in the lookup info that loops around N frames

#

So you implicitly n-buffer them by abusing the cache system

hybrid pilot
#

Mmm

#

BTW penguin if it makes sense for you to use descriptor buffers let me know, dunno if you read the discussion over there

night charm
#

yeah descriptor buffers are not out of the question

#

i just havent had the time to look at them properly

hybrid pilot
night charm
#

Seems easy enough yeah

hybrid pilot
#

So your resourced store that bit of data onf offset in them

#

And then you just memcpy

#

(This is what ravd does interbslyk AFAIK, and AFAIK the extension was just valve wanting to expose this)

night charm
#

yeah i imagine its already done like this internally anyway

iron shadow
#

oh no

#

descriptor indexing is broke

limber rapids
#

if that's the case the world will end tomorrow

#

whenever tomorrow is in your timezone bleakekw

iron shadow
#

it's joever

limber rapids
#

what's the issue

iron shadow
#

an unwrap error too bleakekw

limber rapids
#

that I can't help with

iron shadow
#

some phobos error that mostly is because of incorrect usage but i can't pin point why

#
info.layout = *self.current_set_layouts.get(index as usize).unwrap();

bleakekw

#

says it fails if it couldn't find the desciprtor set/bind

#

but the issue is, this isn't one of the expected errors

limber rapids
#

are you actually using the descriptor in the shader

iron shadow
#

yes i think so

limber rapids
#

the compiler will optimize out any descriptors you don't use

iron shadow
#
layout (set = 1, binding = 2) uniform texture2D texArray[];

Yes?

limber rapids
#

this is a declaration

night charm
#

No but are you actually accessing that array

limber rapids
#

I mean usage wise

#

are you using the descriptor in a way that meaningfully contributes to the output

#

i.e it writes something bleakekw

night charm
#

This could be a bug don’t get me wrong but make sure it’s not optimized out yeah

iron shadow
#

how do i gaslight

#

the compiler into keeping it KEKW

limber rapids
#

you don't

hybrid pilot
#

What does phobos do with descriptors from shaders?

night charm
#

output += 0.001 * texture(…);

iron shadow
#

okok

night charm
hybrid pilot
limber rapids
#

output = texture(...)
output = something else

hybrid pilot
#

And does it check it?

#

Because like it is really annoying when you comment out stuff for debugging but stuff panics

night charm
#

Things easily covered by vulkan validation are usually not checked again, but I know what you mean

hybrid pilot
#

With vulkano it was basically impossible to comment out anything

night charm
#

It might be reasonable to add methods for optionally binding something

#

e.g. bind_xxx_if_exists(…)

iron shadow
#

oh shooot i need to input samplers too i forgor

hybrid pilot
#

Though I guess it is illegal for vulkan to have gaps so you'd also need to bind dummy descriptor sets?

night charm
#

Wouldn’t work with gaps no, but if the shader only goes up to say binding 4

#

You can optionally bind to binding 5 and add it back later

limber rapids
#

Wait wat

#

why no gaps? thonk

hybrid pilot
#

Dunno

limber rapids
#

I don't think that's illegal

night charm
#

You can leave gaps in binding numbers I think yeah

hybrid pilot
#

But I've seen many times the code to fill the gaps with a dummy ds

#

Not hard to do

hybrid pilot
#

It's the sets

limber rapids
#

ye but you need to enable robustness which is annoying

night charm
#

Ah set numbers, fair enough

limber rapids
#

Then you need dummy desc layouts

hybrid pilot
#

So not really a problem after all

night charm
#

Right you’d need to bind them one by one

hybrid pilot
#

Easy to work around

night charm
#

It is yeah

hybrid pilot
#

My lazy way was to bind a random ds lol, but I guess it would be wiser to keep a dummy empty ds aroundb

limber rapids
#

you can shrimply create a desc layout with no bindings for each gap in the numbers

#

And not bind any sets to that layout

night charm
#

That too

hybrid pilot
#

Even easier

#

I though you needed to bind something

limber rapids
#

To be honest I'm reading the spec right now and I'm not entirely sure

night charm
#

Even easier: if the shader compiler optimizes it out then this already happens in Phobos, because then spirv-cross doesn’t report the binding at all

limber rapids
#

But at least you can definitely bind the same dummy set everywhere

hybrid pilot
#

I night just not be remembering and it night have been a dummy descriptor set layout

limber rapids
#

I'm trying to find the part of the spec

night charm
#

@iron shadow does it work now?

iron shadow
#

not yet

#

i got side tracked

limber rapids
#

focus son

iron shadow
#

im trying but im too deep into rewriting the material system

night charm
#

I see

#

Well ima sleep but lmk how it goes

limber rapids
#

@hybrid pilot you are indeed correct

#

But you can bind the same dummy set over and over

#

I'm still waiting for the moment danny realizes what I'd told him days ago about textures in RT

hybrid pilot
limber rapids
#

I'm always wrong bleakekw

hybrid pilot
#

Paradox

#

Are you wrong about being wrong?

limber rapids
#

Oh no

#

you opened a black hole

#

what have you done

hybrid pilot
#

I didn't do it

#

You did

limber rapids
#

fair

#

what have I done

hybrid pilot
#

Now we need a mathematician to create a logic system where your sentence is well defined

limber rapids
#

We'll leave the proof of that system to the reader as an exercise

hybrid pilot
#

Problem fixed ✅

#

(BTW you can't prove that a system has no contradictions)

limber rapids
#

ye

#

you can't prove that math can't prove itself

#

which is sad

#

smh godel's theorem

#

if he didn't make that theorem we'd be proving a lot more things

hybrid pilot
#

Lol

languid fern
#

Also related to phobos:

#

Do you know exaclty which features / extensions cause renderdoc to crash

#

Cause if they're optional (like bda) I could just remove them in my internal fork

limber rapids
#

BDA works great in renderdoc

languid fern
#

Oh huh hm

#

It keeps crashing for me

#

I'll have to look into that

iron shadow
#

make sure you explicitly disable that

#

unless phobos has already done that

#

I know renderdoc doesn't do RT so it crashes when it is on

languid fern
#

I mean when I run the app outside renderdocs it's fine

#

And it's not RT because I have a 1050 bleakekw

iron shadow
#

hmmm

languid fern
#

Eh I'll look more deeply in my logs

#

Should be something somewhere

iron shadow
#

let me pull up the phobos ext

#

Uhh

#

make sure acceleration structs are off?

languid fern
#

Don't even have support for them either lol

iron shadow
#

renderdoc moment bleakekw

languid fern
#

Eh I'll look into it later

iron shadow
#

worst case get nsight
i basically forgotten what renderdoc looks like this point bleakekw

languid fern
#

Yea I just really like renderdoc for debugging since I've gotten used to it

#

(I could put that on my resume)

limber rapids
#

RenderDoc is a million times nicer than nsight

iron shadow
#

it probably is but it doesn't support ray tracing :(

limber rapids
#

BDA is broken beyond any usefulness on Nsight

iron shadow
#

ya but im stuck with it

limber rapids
#

me too bleakekw

#

I usually just use GL_EXT_debug_printf tbh

iron shadow
#

GL_EXT_debug_printf?

#

wtf is this a shader version of print

limber rapids
#

printf in shaders

iron shadow
#

bleakekw i never knew bout it

languid fern
#

Least cursed graphics extension

iron shadow
#

fellas

#

should i submit my material information i.e. albedo texture index in the descriptor

#

wait wrong channel

hybrid pilot
#

So, tomorrow I guess we can discuss with penguin how much he likes daxa's approach. It could be challenging to do it without breaking APIs which is why I'm thinking of making something that sits alongside the existing stuff

languid fern
#

Oh yea can you like fill me in on what you guys are even talking about

#

I don't really understand what it is you're spying on in the first place KEKW

hybrid pilot
languid fern
#

Oh so like descriptor indexing basically?

hybrid pilot
#

Descriptor indexing is how you do it for images

#

Bda for buffers

languid fern
#

Ah I see alright

iron shadow
#

why would Daxa's approach be better? im confused

#

ah it generalizes it across every resource buffer, image, etc.

#

yeah i like that idea

hybrid pilot
iron shadow
#

oh yeah true

#

wait so does daxa generalize the process across every resource?

hybrid pilot
#

Yeah

iron shadow
#

ooh that's cool

#

but would make my suffering redundant :(

hybrid pilot
#

Ehy

#

What are you working on?

iron shadow
#

i just finished getting my bdas working and now working on bindless textures

hybrid pilot
#

I mean I suppose the current stuff would still work

#

Also this is just me saying stuff we'll see what penguin says

iron shadow
#

it would but the urge to recode it KEKW

hybrid pilot
#

It would only make it easier

#

It's late here btw

iron shadow
#

yeah it would sounds really nice

#

tbh I just want barrier management & placement by the rendergraph but i could be tripping and that is not possible KEKW

night charm
#

same with the rt extensions

hybrid pilot
#

Penguin yesterday I asked many questions about daxa. So there every resource is just an handle you pass around. Now the way resource mapping works on their render graph is that it creates and updates a uniform buffer with BDAs and indices for you. Do you think that would make sense doe Phobos?

night charm
#

afaik in daxa the render graph manages and allocates all resources

#

If we do this it’s essentially a rewrite of a lot of stuff

languid fern
#

Idk if this would help but i camacross this

#

By traverse research who made the kajiya rust rendererer.

hybrid pilot
# night charm If we do this it’s essentially a rewrite of a lot of stuff

Mmm no I'm not really proposing that. The thing is that currently Phobos has a concept of virtual resources and physical resources and a way of binding one to the other. Now with bindless there is really no such thing as binding, so the semantics of that operation in the case of daxa is sending the handles to the shader

#

Though I suppose that's not necessarily something we need. After all resources handled by the graph wouldn't be bindless, so I guess it would be enough for Phobos to have a way of saying "bind the bindless descriptor for images here" and then the user does whatever they want to get the handles up in the shader. Then all Phobos would have to do is expose some pool of bindless resources and keep a descriptor set up to date

#

Dunno let me know your thoughts

hybrid pilot
#

Though if use after free is already possible in Phobos I guess nobody fares anyway

night charm
hybrid pilot
#

Yeah I get it

night charm
#

i think the best way to go for now is to keep it simple and figure out how to update large descriptor sets instead of recreating them

hybrid pilot
#

Sounds good?

night charm
#

hmm

#

the thing i dont like about this is how it enforces some kind of layout in the shader (you need a matching bindless descriptor set in the shader)

hybrid pilot
#

I was thinking of having .bind_bindless_pool

#

And you'd decide where to bind it

night charm
#

hmm

hybrid pilot
#

But the actual layout of the pool would be enforced

#

Like of the descriptor set itseld

#

Which makes sense to me though

night charm
#

I was thinking something like

#

We keep the public api the same, with bind_sampled_image_array

#

And then behind the scenes something like

#
if bindings.descriptor_count > update_treshold {
  let new_set = find_unused_set_to_update(bindings);
  update_set(new_set, bindings);
  return new_set;
}
hybrid pilot
#

Mmm what would that do?

#

The thing is

#

With bind image array you always pass all of the images right?

night charm
#

Right

hybrid pilot
#

And if you have thousands or millions it won't ever work

#

So the descriptor set update has to happen when you create the resource

#

Not when you bind it

night charm
#

When would you have millions of textures froghorror

hybrid pilot
#

(Also I'd keep the current api regardless)

hybrid pilot
#

But I mean if it is 4096

#

Just iterating them has a cost

#

And the whole point of bindless is not worrying about binding

#

Which is why you get that layout requirement

#

You are not managing bindings per shader

#

But globally

night charm
#

hmm yeah

#

a global bindless table probably makes more sense

hybrid pilot
#

Also the only requirement is that you have an image array

limber rapids
night charm
#

also allows for better and more seamless bindless support

hybrid pilot
#

Yeah

night charm
#

Then theres mostly just the question of how to handle resource lifetimes

#

e.g. what if you register a texture as a bindless texture but you then want to deallocate it

#

Does the bindless manager own the resources?

#

Or do we somehow signal this destruction

limber rapids
#

oh shit

#

it does matter

#

wtf

hybrid pilot
#

That was the idea behind by Bindless<T> wrapper

limber rapids
#

why are CPUs so slow

night charm
#

Would definitely be easier yeah

hybrid pilot
#

So it's just owned with extra steps

night charm
#

Alright lets work out a more concrete api and see what we end up with

hybrid pilot
#

Though I don't have a ton of times so I can't promess I'll do it quickly

night charm
#

Yeah, can you make a PR with a draft of the design and work on it there?

hybrid pilot
#

My idea was, to make sure it is actually works, to have something using it in my engine before merging anything

hybrid pilot
#

Otherwise it's all shiny and pretty but then it turns out it's not suitable for anything remotely real

night charm
#

The reason I'm asking for a rough outline is so its easier to figure out whats going on and help out

limber rapids
#

Just to get myself up to speed: this is about updating only textures that change inside the large bindless array, right?

hybrid pilot
#

Yeah sure

night charm
hybrid pilot
torn kettle
#

why "bound at all times"?

hybrid pilot
#

Well I mean in a descriptor set

#

Not really bound

night charm
#

It doesnt need to be permanently bound no

torn kettle
#

ok

hybrid pilot
#

I misphrased it

iron shadow
#

I’m so confused what you guys talked about KEKW

night charm
#

Redesigning how Phobos handles bindless

limber rapids
#

And consequently how I handle bindless bleakekw

night charm
hybrid pilot
#

My plan was to leave rhre what is already there

night charm
#

Just use Phobos ™️

hybrid pilot
#

Or you mean in your own thing

limber rapids
#

If you port phobos to C++ I might consider it

night charm
hybrid pilot
#

I love api stability

night charm
hybrid pilot
#

Also the stuff to bind an image array could be useful for smaller image arrays

limber rapids
#

make phobos++ then

#

improve the improvement

hybrid pilot
#

Like when you bind the mip chain as images

night charm
#

Yeah exactly

night charm
iron shadow
#

phobos++ bleakekw

languid fern
#

I thought it was more like an array of descriptors

night charm
#

yeah but you cant mix descriptor types in glsl

#

so you need an array of images to index into

languid fern
#

Like reinterpret one descriptor type as another?

night charm
#

well how would you do an "array of descriptors" in glsl

#

you cant do that

limber rapids
#

An image is a descriptor though thonk

#

Any resource you can bind is a descriptor

languid fern
#

I see

night charm
#

yeah sure it is a descriptor

limber rapids
#

"descriptor" is fancy for pointer (with some metadata)

languid fern
#

I thought descriptors where wrappers around those resources

#

Yea right

night charm
#

but yeah you do need an array of images for bindless usually

limber rapids
#

ye, you could also say it's an array of descriptors that contain images

languid fern
#

Ok so if I understand correctly for bindless you need arrays of images + bda

night charm
#

theres no BDA equivalent for images where you literally yeet a pointer

#

yes

languid fern
#

Ok and another thing

#

Can you do something like this in GLSL

#
layout(set = 0, binding = 0, r32ui) uniform image2D textures[];
layout(set = 0, binding = 0, rg32ui) uniform image2D textures[];
layout(set = 0, binding = 0, rgba32ui) uniform image2D textures[];
#

So you don't have to make multiple descriptor sets for different types of images

night charm
#

why thonk

#

you dont have to anyway

languid fern
#

Oh how

#

Can you just do something like

layout(set = 0, binding = 0) uniform image2D textures[];
``` directly?
night charm
#

this should work already but bindless is usually for textures nto storage images

#

you can alias formats like that

#

the way you wrote it initially

languid fern
#

Oh okay

#

Yea cause I was wondering

#

If you're gonna do bindless from the start

#

Why not stick with it throughout

#

Unless there's a performance cost to doing such things, and doing non-bindless for some things proves to be more efficient

night charm
#

i find it not very useful for storage resources

#

mostly for readonly stuff

#

like textures

limber rapids
#

I'm trying to think what would require so many storage images

night charm
#

pretty much that yeah

limber rapids
#

GI probably

hybrid pilot
#

Pengiun do you think I need to create the pool type myself? I saw there is a Pool type but I don't see how ti make it do what I want

limber rapids
#

specifically Lumen-like SDFDDGI

languid fern
night charm
languid fern
#

In my engine I use like 3 storage textures per comp shader max

hybrid pilot
night charm
#

not yet but its probably not hard to add

hybrid pilot
#

Mmm I see

#

So no new types

#

Which makes sense because some of the logic is in place

night charm
#

If all the logic is there then it'd be nice to fit it in there yeah

#

But if not its totally fine to add new stuff

#

Something like a BindlessPool

hybrid pilot
#

I see

#

Thx

#

I'll met you know if I encounter any roadblocks in rescuing pool

#

Rn I can't work on it but later I should

languid fern
#

So what's the main™️ plan for bindless at the moment?

limber rapids
#

implement some sort of caching for sampled images

hybrid pilot
#

Why caching

night charm
#

Register resources with a global bindless pool -> bind the pool when you want to use it -> this binds one descriptor set with all resource

limber rapids
#

iterating through all textures and updating the whole set at once is expensive

languid fern
#

Probably more performant than iterating through all resources and caching internally

#

Most definitely more performant kek

limber rapids
night charm
#

should be yeah

languid fern
#

so:

create desc bindless pool

update resources when needed

bind pool
```?
limber rapids
#

Hol up

#

doesn't this still require updating the whole set at once? thonk

#

Or do you store "changes" as well in this bindless pool

hybrid pilot
languid fern
#

Ohh I see gotcha

#

So I assume we're gonna need some sort of versioning system

hybrid pilot
limber rapids
#

So you update the whole thing, but different

#

I get it, certainly better than updating it every frame

hybrid pilot
#

What do you mean the whole tjingb

#

You can write individual entries

limber rapids
#

Ah ok

#

even better

#

Can you bind dummy descriptors?

#

That requires robustness doesn't it?

#

Or you could avoid doing that altogether and simply "promise" you won't use that descriptor anymore