मैं वर्तमान में HLSL 5.0 और D3D11 में निरंतर बफर पैकिंग नियमों के आसपास अपना सिर लाने की कोशिश कर रहा हूं। इसलिए मैंने fxc.exe के साथ थोड़ा खेला:

// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.18773
//
//
// Buffer Definitions:
//
// cbuffer testbuffer
// {
//
//   float foo;                         // Offset:    0 Size:     4
//   float3x1 bar;                      // Offset:    4 Size:    12 [unused]
//
// }
//
//
// Resource Bindings:
//
// Name                                 Type  Format         Dim Slot Elements
// ------------------------------ ---------- ------- ----------- ---- --------
// testbuffer                        cbuffer      NA          NA    0        1

अब तक सब कुछ वैसा ही व्यवहार करता है जैसा मैं उम्मीद करता हूं। float3x1 आकार में 12 बाइट्स है और इसलिए इसे पहले 16 बाइट स्लॉट में रखा जा सकता है क्योंकि वेरिएबल पहले 4 बाइट्स आकार में है। float3x1 को float1x3 में बदलने के बाद, कंपाइलर आउटपुट अब इस तरह दिखता है:

// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.18773
//
//
// Buffer Definitions:
//
// cbuffer testbuffer
// {
//
//   float foo;                         // Offset:    0 Size:     4
//   float1x3 bar;                      // Offset:   16 Size:    36 [unused]
//
// }
//
//
// Resource Bindings:
//
// Name                                 Type  Format         Dim Slot Elements
// ------------------------------ ---------- ------- ----------- ---- --------
// testbuffer                        cbuffer      NA          NA    0        1

तो ऐसा लगता है कि एचएलएसएल कंपाइलर अचानक float1x3 में प्रत्येक फ्लोट को अपना 16 बाइट स्लॉट देता है जो काफी बेकार है। मैंने इस व्यवहार को समझने के लिए बहुत कुछ किया लेकिन कुछ भी नहीं मिला। मुझे आशा है कि आप में से कुछ लोग मुझे यह समझा सकते हैं क्योंकि यह व्यवहार वास्तव में मुझे भ्रमित करता है।

2
user1655806 17 नवम्बर 2018, 19:17

1 उत्तर

सबसे बढ़िया उत्तर

यह उत्तर एचएलएसएल की मेरी समझ के आधार पर अनुमान है, जो डिफ़ॉल्ट रूप से कॉलम प्रमुख मैट्रिक्स पैकिंग का उपयोग करता है। एचएलएसएल में रजिस्टर कुल 16 बाइट्स प्रति रजिस्टर के लिए चार 4-बाइट वर्गों के सेट से बने होते हैं। प्रत्येक रजिस्टर तब चार स्तंभों वाली एकल पंक्ति के रूप में कार्य करता है।

जब आप एक फ्लोट 3x1 घोषित करते हैं, तो आप 3 कॉलम और एक पंक्ति के साथ एक मैट्रिक्स घोषित कर रहे हैं। यह एचएलएसएल की रजिस्टर पैकिंग की विधि में अच्छी तरह फिट बैठता है जहां एक पंक्ति में 16 बाइट्स हो सकते हैं।

जब आप फ्लोट 1x3 घोषित करते हैं, तो आप एक कॉलम और तीन पंक्तियों के साथ एक मैट्रिक्स घोषित कर रहे हैं। जिस तरह से HLSL रजिस्टर पैकिंग को संभालता है, उसे डेटा को रजिस्टरों के 3 सेटों में फैलाना पड़ता है और 3x3 मैट्रिक्स का स्थान सुरक्षित रखता है।

यदि आपको 1xX मैट्रिक्स की आवश्यकता है, तो आप एक वेक्टर घोषित करने से बेहतर हैं जो स्वचालित रूप से एक ही रजिस्टर में फिट हो जाएगा और किसी भी स्थिति में 1x3 या 3x1 मैट्रिक्स हो सकता है।

2
GaleRazorwind 17 नवम्बर 2018, 19:25