send bit from XNA to HLSL

Started by
4 comments, last by winsrp 11 years, 8 months ago
So I'm using a standard position, color, texture vertex declaration, but I need to send 1 more data per vertex, which is a byte from (0 to 255), I know how to make a custom vertex declaration and all that jazz, but, how do I send a byte type, instead of a float, so I can keep my structure small.

Regards,

Winsrp.
Advertisement
You're only talking about a 10% growth in the structure, if even that (I thought I read that HLSL registers pad out in multiples of float4, so if your position is a float3 you might be wasting a little space anyway on that first register, as color would be put in slot #2. Can someone confirm that? Edit: There we go). This might be premature optimization. Have you confirmed the size difference impacts framerate noticeably?

You could use half of a "half" and accept the wasted byte of space, I suppose...

Hazard Pay :: FPS/RTS in SharpDX (gathering dust, retained for... historical purposes)
DeviantArt :: Because right-brain needs love too (also pretty neglected these days)


You're only talking about a 10% growth in the structure, if even that (I thought I read that HLSL registers pad out in multiples of float4, so if your position is a float3 you might be wasting a little space anyway on that first register, as color would be put in slot #2. Can someone confirm that? Edit: There we go). This might be premature optimization. Have you confirmed the size difference impacts framerate noticeably?

You could use half of a "half" and accept the wasted byte of space, I suppose...

You are confused between vertex stream data and uniform data, uniforms are passed as a vector of 4, 32 bit values. If you send one float as a uniform DX runtime will send that value padded out with 96 bits set to 0. Packing on uniform data is up to you as the programmer, unpacking in the shader is then again up to you as well.

I think for vertex streams the lowest data size you can send is 4 bytes worth as the driver will most likely want to do alligned reads for this data, so you are going to have to suck up the lost space. You would use "Byte4" as a value for the VertexElementFromat field in the declaration, and just add the value as a "uint" to the vertex data stream.

Your vertex struct would look like this
[source=csharp]
struct VertexData
{
float x,y,z;
Color color;
float u,v;
uint byteData;
};
//and assignment would be this
currentVertexData.byteData = (uint)byteValue; //say byteValue = 3, the uint has a value of 3 as well
[/source]

Remember that the cast never really changes the value of your byte just tells the CPU to use a bigger register and memmory location to store it in.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max, Watch Dogs: Legion


You are confused between vertex stream data and uniform data, uniforms are passed as a vector of 4, 32 bit values. If you send one float as a uniform DX runtime will send that value padded out with 96 bits set to 0. Packing on uniform data is up to you as the programmer, unpacking in the shader is then again up to you as well.

Ah, I see, thanks for the clarification.

I'm still curious if the optimization is even worthwhile, unless you're passing in a huge number of verts and the aggregate difference in buffer size is on a noticeable level...

Hazard Pay :: FPS/RTS in SharpDX (gathering dust, retained for... historical purposes)
DeviantArt :: Because right-brain needs love too (also pretty neglected these days)


I'm still curious if the optimization is even worthwhile, unless you're passing in a huge number of verts and the aggregate difference in buffer size is on a noticeable level...
Yes, compressing vertex data is a very important optimisation, especially if you want to port your XNA code over to the 360. Firstly, when it'll add up to a few MiB of wasted RAM, and secondly the (360's) input assembler (which feeds data into the vertex shader) fetches data from vertex-buffers in 32-byte chunks. If your vertex structure is 33 bytes, it will be twice as slow to prepare each call to the vertex-shader as a 32-byte structure - so a lot of care should be taken when designing your vertex formats.

Unfortunately XNA doesn't let you use single-byte vertex elements though... So you're left with trying to pack it in elsewhere. For example:
*if 10-bits of precision is enough for your texture-coordinates, you could use the Normalized101010 format, which gives you 3 10-bit values per element.
*if you only need RGB colours, you're still paying for the alpha channel, so you could use it to store your other byte of data.
*you could store your positions in a HalfVector4, and use the 4th value to store your extra data.
hmmm interesting,

So I could define my position as half vector4, and that would give me, la "w" value in the position that I could store some info in,... even when its bigger than a byte. I was currently using the alpha channel of the color, but it seems that I need that now, so I need to store my byte somewhere else.

This topic is closed to new replies.

Advertisement