تنظيم صفحاتك في مجموعات
يمكنك حفظ المحتوى وتصنيفه حسب إعداداتك المفضّلة.
يمكنك تشخيص عدد قليل من مشكلات الأداء المحتملة المتعلقة بالرأس من خلال
استخدام تحديد ملامح الإطار. استخدم جزء الأوامر لعرض جميع استدعاءات السحب التي تنفذها لعبتك في إطار معين وأعداد العناصر الأولية المرسومة لكل استدعاء للرسم. بهذه الطريقة، يمكن أن يكون لديك عدد تقريبي للعدد الإجمالي للرؤوس التي يتم إرسالها في إطار واحد.
الشكل 1. عرض تحليل الإطارات لمكالمة
glDrawElements واحدة، يظهر 2,718 قاعدة مثلثية مرسومة
ضغط سمة Vertex
من المشاكل الشائعة التي قد تواجهها لعبتك هي متوسط حجم رأس المال الكبير. عند إرسال عدد كبير من الرؤوس ذات متوسط حجم رأس مرتفع، يتم عرض معدل نقل بيانات قراءة الرأس الكبير للذاكرة عند قراءتها بواسطة وحدة معالجة الرسومات.
لمراقبة تنسيق الرأس لاستدعاء رسم معين، أكمل الخطوات التالية:
اختَر إحدى استدعاءات الرسم التي تهمّك.
قد تكون استدعاء رسم نموذجي للمشهد، أو استدعاء رسم بعدد كبير
من الرؤوس، أو طلب رسم لنموذج معقد لشخصيات، أو
نوعًا آخر من استدعاءات الرسم.
انتقِل إلى جزء Pipeline، ثم انقر على IA لتجميع الإدخال.
يحدد هذا تنسيق الرأس للرؤوس التي تأتي في وحدة معالجة الرسومات.
راقِب سلسلة من السمات وتنسيقاتها. على سبيل المثال، R32G32B32_SFLOAT هو عمود عائم يتضمّن 32 بت يتضمّن 3 مكونات.
الشكل 2. مجموعة إدخال لاستدعاء الرسم، مع سمات غير مضغوطة ينتج عنها حجم رأس 56 بايت
غالبًا ما يمكن ضغط سمات الرأس بأقل تخفيض في جودة النماذج المرسومة. وننصح على وجه الخصوص بما يلي:
ضغط موضع الرأس إلى رموز عائمة بحجم 16 بت بنصف الدقة
ضغط إحداثيات نسيج الأشعة فوق البنفسجية إلى ushorts بعدد صحيح 16 بت غير موقَّع
ضغط مساحة المماس بترميز المتجهات العادية والمماسية والثنائية الطبيعة باستخدام الرباعيات
ويمكن أيضًا مراعاة السمات المتنوعة الأخرى للأنواع منخفضة الدقة على أساس كل حالة على حدة.
تقسيم بث Vertex
يمكنك أيضًا التحقّق ممّا إذا كانت ساحات مشاركات سمات الرأس مقسّمة بشكل مناسب. في بُنى العرض المتجانب، مثل وحدات معالجة الرسومات للأجهزة الجوّالة، يتم استخدام مواضع الرأس
لأول مرة في تمريرة شاملة لإنشاء سلال من العناصر الأولية التي تمت معالجتها في كل مربّع. إذا كانت سمات الرأس متداخلة في مورد احتياطي واحد، تتم قراءة جميع بيانات الرأس في ذاكرة التخزين المؤقت للدمج، على الرغم من استخدام مواضع الرأس فقط.
لتقليل معدّل نقل بيانات الذاكرة المستخدمة بالرأس وتحسين كفاءة ذاكرة التخزين المؤقت، وبالتالي تقليل الوقت المستغرَق في تمرير البيانات، يجب تقسيم بيانات الرأس إلى مصدرَين منفصلَين، أحدهما لموضع الرأس والآخر لجميع سمات الرأس الأخرى.
للتحقّق ممّا إذا كانت سمات الرأس مقسّمة بشكل مناسب:
اختر مكالمة الرسم التي تهمك، ولاحظ رقم مكالمة الرسم.
قد تكون استدعاء رسم نموذجي للمشهد، أو استدعاء رسم بعدد كبير
من الرؤوس، أو طلب رسم لنموذج معقد لشخصيات، أو
نوعًا آخر من استدعاءات الرسم.
انتقِل إلى جزء Pipeline، ثم انقر على IA لتجميع الإدخال. يحدد هذا تنسيق الرأس للرؤوس التي تأتي إلى وحدة معالجة الرسومات.
لاحِظ ارتباطات سمات الرأس، فقد تزداد عادةً هذه الروابط خطيًا (0، 1، 2، 3، إلخ)، ولكن هذا لا يحدث دائمًا.
موضع الرأس هو عادةً سمة الرأس الأولى المدرجة.
في لوحة State (الولاية)، ابحث عن LastDrawInfos ووسِّع رقم طلب الرسم المطابق. بعد ذلك، قم بتوسيع BoundVertexBuffers لاستدعاء الرسم هذا.
لاحظ الموارد الاحتياطية للرأس المحصورة أثناء استدعاء السحب المحدد، مع الفهارس التي تطابق ارتباطات سمة الرأس السابقة.
وسّع الروابط الخاصة بسمات رأس استدعاء الرسم، وقم بتوسيع
الموارد الاحتياطية.
راقِب VulkanHandle لمعرفة الموارد الاحتياطية التي تمثّل الذاكرة الأساسية التي تصدر منها البيانات الرأسية. وإذا كانت السمة VulkanHandle مختلفة، يعني ذلك أنّ السمات تنشأ من مخازن احتياطية أساسية مختلفة. إذا كانت VulkanHandle هي نفسها لكن عمليات الإزاحة كبيرة
(على سبيل المثال، أكبر من 100)، قد تنشأ السمات من مخازن فرعية مختلفة، ولكن هذا يتطلّب مزيدًا من التحقيق.
الشكل 3. إدخال تجميع لاستدعاء السحب، مع أن لوحة الحالة على اليسار توضح أن السمات في الربط 0 و1، وموضع الرأس والوضع العادي، تشترك في مخزن احتياطي أساسي واحد
للحصول على مزيد من التفاصيل حول تقسيم ساحة مشاركات الرأس وكيفية حلها على محركات الألعاب المختلفة، يمكنك الاطلاع على مشاركة المدونة حول هذا الموضوع.
يخضع كل من المحتوى وعيّنات التعليمات البرمجية في هذه الصفحة للتراخيص الموضحّة في ترخيص استخدام المحتوى. إنّ Java وOpenJDK هما علامتان تجاريتان مسجَّلتان لشركة Oracle و/أو الشركات التابعة لها.
تاريخ التعديل الأخير: 2025-07-27 (حسب التوقيت العالمي المتفَّق عليه)
[null,null,["تاريخ التعديل الأخير: 2025-07-27 (حسب التوقيت العالمي المتفَّق عليه)"],[],[],null,["# Analyze vertex formats\n\nYou may diagnose a few possible vertex-related performance problems through the\nuse of frame profiling. Use the **Commands** pane to view all of the draw calls\nyour game performs in a given frame and counts of primitives drawn per draw\ncall. This can give an approximation of the overall number of vertices submitted\nin a single frame.\n**Figure 1.** Frame profiling view for a single `glDrawElements` call, showing 2,718 triangle primitives drawn\n\nVertex attribute compression\n----------------------------\n\nOne common problem your game may face is a large average vertex size. A\nlarge number of vertices submitted with a high average vertex size results in a\nlarge vertex memory read bandwidth when read by the GPU.\n\nTo observe the vertex format for a given draw call, complete the following steps:\n\n1. Select a draw call of interest.\n\n This can be a typical draw call for the scene, a draw call with a large\n number of vertices, a draw call for a complex character model, or some other\n type of draw call.\n2. Navigate to the **Pipeline** pane, and click **IA** for input assembly.\n This defines the vertex format for vertices coming into the GPU.\n\n3. Observe a series of attributes and their formats; for example,\n `R32G32B32_SFLOAT` is a 3-component 32-bit signed float.\n\n**Figure 2.**Input assembly for a draw call, with uncompressed attributes resulting in a vertex size of 56 bytes\n\nFrequently, vertex attributes can be compressed with minimal reduction in the\nquality of the models drawn. In particular, we recommend:\n\n- Compressing vertex position to half-precision 16-bit floats\n- Compressing UV texture coordinates to 16-bit unsigned integer ushorts\n- Compressing the tangent space by encoding normal, tangent, and binormal vectors using quaternions\n\nOther miscellaneous attributes may also be considered for lower-precision types\non a case-by-case basis.\n\nVertex stream splitting\n-----------------------\n\nYou can also investigate whether vertex attribute streams are appropriately\nsplit. On tiled rendering architectures such as mobile GPUs, vertex positions\nare first used in a binning pass to create bins of primitives processed in each\ntile. If vertex attributes are interleaved into a single buffer, all vertex data\nis read into cache for binning, even though only vertex positions are used.\n\nTo reduce vertex read memory bandwidth and improve cache efficiency, and thus\nreduce time spent on the binning pass, vertex data should be split into two\nseparate streams, one for vertex positions, and one for all other vertex\nattributes.\n\nTo investigate whether vertex attributes are appropriately split:\n\n1. Select a draw call of interest, and note the draw call number.\n\n This can be a typical draw call for the scene, a draw call with a large\n number of vertices, a draw call for a complex character model, or some other\n type of draw call.\n2. Navigate to the **Pipeline** pane, and click **IA** for input assembly. This\n defines the vertex format for vertices coming into the GPU.\n\n3. Observe the bindings of your vertex attributes; typically these might\n increase linearly (0, 1, 2, 3, etc.), but this is not always the case.\n Vertex position is typically the first vertex attribute listed.\n\n4. In the **State** pane, find the `LastDrawInfos` and expand the matching draw\n call number. Then, expand the `BoundVertexBuffers` for this draw call.\n\n5. Observe the vertex buffers bound during the given draw call, with indices\n matching the vertex attribute bindings from earlier.\n\n6. Expand the bindings for your draw call's vertex attributes, and expand the\n buffers.\n\n7. Observe the `VulkanHandle` for the buffers, which represent the underlying\n memory that the vertex data sources from. If the `VulkanHandle`s are\n different, this means the attributes originate from different underlying\n buffers. If the `VulkanHandle`s are the same but the offsets are large\n (for example, greater than 100), the attributes may still originate from\n different sub-buffers, but this requires further investigation.\n\n**Figure 3.**Input assembly for a draw call, with the state panel to the right showing that the attributes at binding 0 and 1, vertex position and normal, share a single underlying buffer\n\nFor more detail about vertex stream splitting and how to resolve it on various\ngame engines, see our [blog post](/agi/frame-trace/link-to-Omars-blog-post) on the subject."]]