เหตุใดฉันจึงไม่ได้รับบูลบรรจุและปรับให้เป็นบัฟเฟอร์คงที่ D3D


9

เอาล่ะฉันมีเวลายากที่จะได้รับการบรรจุและจัดแนวเป็นบัฟเฟอร์คงที่ hlsl และฉันไม่แน่ใจว่าทำไม

นี่คือบัฟเฟอร์ใน hlsl

cbuffer MaterialBuffer : register(b1) {
    float3 materialDiffuseAlbedo;
    float  materialSpecularExponent;
    float3 materialSpecularAlbedo;
    bool isTextured;
};

และนี่คือ c ++

struct GeometryBufferPass_MaterialBuffer {
    XMFLOAT3 diffuse;
    float specularExponent;
    XMFLOAT3 specular;
    bool isTextured;
};

ฉันพยายามย้ายบูลและขยายโครงสร้างในทุก ๆ ด้านโดยไม่มีโชค วิธีที่ถูกต้องในการทำเช่นนี้คืออะไร?


มันก่อให้เกิดปัญหาอะไร?
MichaelHouse

บูลใช้เพื่อกำหนดว่า shader ต้องการตัวอย่างพื้นผิวหรือไม่ ด้วยวิธีนี้ฉันสามารถแสดงวัตถุที่มีพื้นผิวและไม่มีพื้นผิวด้วย shader เดียวกัน บูลนั้นใช้ในคำสั่งแบบมีเงื่อนไข มันไม่ได้รับข้อมูลที่ถูกต้องเพราะมันปฏิบัติต่อวัตถุทั้งหมดเหมือนกัน มันไม่ถูกต้องเพราะท้องฟ้าของฉันเป็นเพียงสิ่งเดียวที่มีพื้นผิวในขณะนี้
Klashnikov เด็ก

ค่าอื่น ๆ ใช้งานได้ แต่ไม่ใช่บูล? คุณได้ลองใช้ตัว debuggers ตัวใดตัวหนึ่งที่มีให้สำหรับเฉดสีเพื่อดูว่ามีอะไรเข้ามาบ้าง
MichaelHouse

2
พยายามเก็บค่าบูลในรูปถ่าน เก็บเป็น 1 สำหรับจริงและ 0 สำหรับเท็จ เพียงเพื่อทดสอบและยังบูลคือ 1 ไบต์ใน C ++ ต่อไป ...
Gustavo Maciel

3
ขนาดของบูลขึ้นอยู่กับการใช้งาน ในบางแพลตฟอร์มมันมีขนาดเท่ากับ int stackoverflow.com/questions/5067492/…
Tetrad

คำตอบ:


9

สำหรับประสิทธิภาพบัฟเฟอร์คงที่จะถูกแมปดังกล่าวว่าค่าทำลงทะเบียน GPU ไม่กาง การลงทะเบียนแต่ละครั้งมีขนาดสี่ลอย (16 ไบต์) ดังนั้นโครงสร้างบัฟเฟอร์คงที่จะต้องมีหลายอย่างใน GPU โครงสร้าง C ++ ของคุณควรถูกเสริมให้เหมาะสมหากคุณต้องการใช้เพื่อความสะดวกในการจับคู่ข้อมูล

ปัญหาของคุณคือบูลีน HLSL คือสี่ไบต์ แต่หนึ่งไบต์ทางด้าน CPU (ในการใช้งานเฉพาะของคุณ) สิ่งนี้ทำให้โครงสร้าง C ++ ของคุณไม่ถูกต้อง: บิตสำคัญของค่าบูลีน (0 หรือ 1 ที่สำคัญ) จะถูกเก็บไว้ในไบต์ที่มีนัยสำคัญน้อยที่สุดของค่าและเนื่องจากขนาดไม่สอดคล้องกับตำแหน่ง ของไบต์นั้นในหน่วยความจำจะแตกต่างกันในโครงสร้างรุ่น CPU และ GPU

การใส่ช่องว่างที่เหมาะสมด้วยตนเองและสร้างความมั่นใจในการจัดตำแหน่ง 16- ไบต์ที่เหมาะสมหรือเพียงแค่ใช้ประเภทขนาดที่เหมาะสมเช่นจำนวนเต็มควรแก้ไขปัญหา เธรดนี้อาจมีประโยชน์สำหรับคุณเนื่องจากมีการอภิปรายเชิงลึกเกี่ยวกับปัญหาเดียวกันโดยประมาณ


1
ฉันไม่ปฏิบัติตาม: " isTexturedพอดีกับการลงทะเบียนเดียวกันเพราะมันจะต้องก้าวข้ามไปสู่การลงทะเบียนครั้งต่อไปดังนั้นมันจะชนเข้ากับการลงทะเบียนครั้งต่อไป" การลงทะเบียนครั้งที่สองนั้นประกอบไปด้วยspecularสามองค์ประกอบแรกและisTexturedสุดท้ายดังนั้นฉันไม่เห็นว่าสิ่งใดที่จำเป็นในการลงทะเบียนครั้งต่อไปหรือไม่ ความยาวบูล 1 ไบต์เทียบกับ 4 ไบต์มีความสำคัญอย่างชัดเจน แต่อย่างใดอย่างหนึ่งจะพอดีหลังจากspecularในการลงทะเบียนเดียวกัน
นาธานรีด

คุณถูก; ฉันสับสนตัวเองกับขนาดของรีจิสเตอร์เทียบกับขนาดของประเภทและสร้างการแมปที่ไม่ถูกต้อง ปัญหาเดียวคือที่ตั้งของไบต์ที่เกี่ยวข้องในหน่วยความจำ ฉันปรับคำตอบแล้ว

ยอมรับคำตอบของคุณอย่างละเอียด อย่างที่คุณพูดถึงมันเป็นปัญหา endian น้อย / ใหญ่และการใช้ int แก้ไขมัน
Klashnikov เด็ก

3

เอาล่ะได้อ่านแล้วสังเกตว่า hlsl bool นั้นเป็นจำนวนเต็ม 32 บิต ดังนั้นฉันจึงใช้ int ใน c ++ struct เพื่อแก้ปัญหาของฉัน

struct GeometryBufferPass_MaterialBuffer {
    XMFLOAT3 diffuse;
    float specularExponent;
    XMFLOAT3 specular;
    int isTextured;
};

ทำไมคุณไม่เก็บประเภทบูลเอาไว้ แต่ใช้ int ในด้านคอมไพเลอร์? เพียงเพื่อให้ความหมาย
Gustavo Maciel

ใช่นั่นคือสิ่งที่ฉันทำข้างต้น ใช้จำนวนเต็มสำหรับด้าน cpu ด้านโครงสร้างและบูลสำหรับด้าน gpu บัฟเฟอร์คงที่
Klashnikov เด็ก

0

float, bool และ int ไม่จำเป็นต้องมีรายการสำหรับ endian โดยเฉพาะสำหรับหลายรายการ

การสลับเป็น int หรือ float ทำงานในตัวอย่างบางส่วนที่แสดงไว้ที่นี่เนื่องจากสอดคล้องระหว่างรายการ XMFLOAT3 ดังนั้นจึงอ้างอิงได้อย่างถูกต้อง อย่างไรก็ตามหากคุณต้องการประกาศอาร์เรย์หรือหลายรายการในโครงสร้างสำหรับ int ให้ลอย (ไม่มีประเภท XM) คุณจะพบว่าค่า GPU ไม่ตรงกับค่าที่ตั้งไว้ในโครงสร้าง CPU

แน่นอนฉันได้เมื่อเพิ่มอาร์เรย์ชนิด int ที่จะใช้สำหรับประเภทแสง

วิธีที่ง่ายที่สุดที่ฉันพบคือติดกับประเภท XM ที่เรียงตาม 16 ซึ่งอาจต้องใช้องค์ประกอบ / ไบต์ที่สูญเปล่า แต่เรียงลำดับ endian ให้คุณ EG XMINT4 และเพิ่งใช้องค์ประกอบแรก. x สำหรับค่าของคุณหรือถ้าคุณมีความจำเป็นต้องใช้องค์ประกอบอื่น ๆ เพื่อวัตถุประสงค์อื่น แต่หมายถึงการตั้งชื่อไม่ดี (ให้แน่ใจว่าได้แสดงความคิดเห็น) หมายเหตุ: อาร์เรย์ XMINT2 จะไม่อยู่ในลำดับเชิงตรรกะ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.