Advertisement Jump to content
Sign in to follow this  
ongamex92

D3DCompile and #pragma pack_matrix

This topic is 1879 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Well there is something that I'm missing.

 

I prefer to use (rowVector mul rowMatrix) layout in my code. I know that there are a lot for ppl who hate rowVector layout so I've impemented a math library(CPU side) that supports both layouts natively.

 

Later the HLSL compiler is just ignoring the  #pragma pack_matrix.

Colum Major layout is always used. The only soultion is to use D3DCOMPILE_PACK_MATRIX_ROW_MAJOR option.

 

Is the  #pragma pack_matrix allowed for the FX only?

Can I force the matrix packing to be row major from the shader code?

 

The uglyest solution that comes to mind is to include the matrix layout into the my custom shader met data?

Edited by imoogiBG

Share this post


Link to post
Share on other sites
Advertisement

Do you use it like this?

#pragma pack_matrix(row_major)

 

This works for me and i think this is the default for FX while not for "raw" HLSL

Share this post


Link to post
Share on other sites

It should work in HLSL as well. Are you using it correctly? Should be

#pragma pack_matrix(row_major)

at the start of the shader.

Also, if you are using the D3DX functions to generate matrix, make sure you don't transpose them before setting them into the CB.

Share this post


Link to post
Share on other sites

This is somewhat tangential, but I thought I'd bring it up. row_major and column_major only refer to the MEMORY layout of the matrix. They do not refer to whether your matrices store the bases in rows or columns, though if you are careless changing the memory layout WILL effectively change whether the bases are stored in rows or columns.

 

You can use matrices with column major matrices and still have the basis vectors stored in the matrices rows (which would allow you to do rowVector mul rowMatrix math). In fact, you probably SHOULD do it this way, because then each vector mul matrix operation will just be four dot products. (sidebar: I don't know if rowVector mul rowMatrix when rowMatrix has a row major memory layout will actually have worse assembly code generated on modern hardware, it may or may not, but rowVector mul rowMatrix when rowMatrix has column major memory layout can definitely be done simply with just four dot4s internally).

 

So, you need to keep two things in mind: 1) are the basis vectors of my matrix stored in rows or columns, and 2) is my matrix stored in row major, or column major order in memory? These are two separate issues! So long as you lay the memory out in row major or column major order when you write your constant buffers (according to what the shader expects) then row_major or column_major packing shouldn't have any effect on your shader code (though the generated assembly may be different). 

Share this post


Link to post
Share on other sites

 

You can use matrices with column major matrices and still have the basis vectors stored in the matrices rows (which would allow you to do rowVector mul rowMatrix math). In fact, you probably SHOULD do it this way, because then each vector mul matrix operation will just be four dot products. (sidebar: I don't know if rowVector mul rowMatrix when rowMatrix has a row major memory layout will actually have worse assembly code generated on modern hardware, it may or may not, but rowVector mul rowMatrix when rowMatrix has column major memory layout can definitely be done simply with just four dot4s internally).

 

 I'm OK with the math behind the things. Just wanted the memory layout to be the same as my math lib.

 

The problem was in the way I use #pragma pack_matrix; It was #pragma pack_matrix row_major wich is wrong.

Share this post


Link to post
Share on other sites

Actually I want to ask you guys. In which order you prefer to apply transforms? v * M or M * v?

v * M is mat1x4 * mat4x4 (row vector convention).
M * v is mat4x4 * mat4x1 (column vector convention).

Most mathematicians use column-vector notation, but some early programmers preferred to go with the other convention, which is why they both show up in comp graphics.

Depending on whih convention you choose, you've got to construct your matrices differently.

If you use the column-vector convention, then column-major storage will produce the most optimal code (and vice versa - is usin row-vector convention, you should prefer to also use row-major storage). [citation needed]

At the end of the day, it doesn't matter. I chose column-vectors because it seems to be more popular with mathematicians (and column-major storage for matching efficiency).

Edited by Hodgman

Share this post


Link to post
Share on other sites

If you use the column-vector convention, then column-major storage will produce the most optimal code (and vice versa - is usin row-vector convention, you should prefer to also use row-major storage


Could you explain why that is? Earlier in the thread I suggested the exact opposite was true. I don't want to be going around giving bad advice.

The reason I thought the opposite was that a vector*matrix op should just be four dot products with the vector and each column of the matrix (in the row matrix style). If the row matrix is stored in column major order then it should (! This is my leap of faith) produce more optimal code.

I must be missing something. I should probably just compile a shader both ways and look at the disassembly.

Share this post


Link to post
Share on other sites

 

If you use the column-vector convention, then column-major storage will produce the most optimal code (and vice versa - is usin row-vector convention, you should prefer to also use row-major storage


Could you explain why that is? Earlier in the thread I suggested the exact opposite was true. I don't want to be going around giving bad advice.

 

 

This depends on your implementation method. You can write equally *speed* code using both methods. In row-major implementation you will express M * M by 4 dots using row vectors, and for  M*M column-major you can treat the memory layout as it was transposed. Or express the multiplication with SUM of (Coulm by Column componetwise multiplication). It's up to you what you will pick.

 

I prefer ROW major because V * T1 * T2 ... is much more natural to me. Also i found it easier to implement.

Edited by imoogiBG

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!