ग्राफिक राज्य और घटकों का प्रबंधन?


11

मैं अक्सर ग्राफिक्स के साथ काम करते समय बहुत अधिक समयपूर्व अनुकूलन करता हूं। कुछ सिद्धांत हैं जिनका मैं हमेशा पालन करने की कोशिश करता हूं:

  • डी 3 डी घटकों की संख्या को न्यूनतम रखें। (रेंडर स्टेट्स, बफ़र्स, शेड्स इत्यादि)
  • यदि आवश्यक हो तो केवल घटकों को बांधें। (पहले से बाध्य नहीं, आदि)
  • जितना संभव हो उतना घटकों को विशेष करें। (केवल आवश्यक BindFlags आदि सेट करें)

यह मुझे निर्मित घटकों और वर्तमान पाइपिंग स्थिति के प्रबंधन के लिए बहुत विस्तृत आवरण बनाने की ओर ले जाता है। न केवल यह मेरे मूल्यवान विकास के समय का बहुत अधिक उपभोग करता है, यह जटिलता की एक और बड़ी परत को भी जोड़ता है।

और सबसे बुरा: मुझे नहीं पता कि क्या यह परेशानी के लायक है।

मेरे कुछ अनुकूलन के विचार पहले से ही निचले स्तर पर लागू हो सकते हैं और मैं सिर्फ उन्हें दोहरा रहा हूं, इसके अलावा सीपीयू पर समय बर्बाद कर रहा हूं। अन्य विचार पूरी तरह से अनावश्यक हो सकते हैं, क्योंकि प्रदर्शन पर प्रभाव नगण्य है।

तो मेरे सवाल हैं:

  1. उपरोक्त दिशानिर्देशों में से कौन सा मान्य है और मुझे उनका पालन किस सीमा तक करना चाहिए?
  2. जीपीयू की स्थिति कैसे बदलती है?
  3. अगर मैं कभी इस्तेमाल नहीं होने वाले राज्य को बदल दूं तो क्या होगा? (सक्रिय होने पर कोई ड्रा कॉल नहीं किया जा रहा है।)
  4. विभिन्न विभिन्न घटकों को बांधने के लिए वास्तविक प्रदर्शन दंड क्या हैं?
  5. अन्य प्रदर्शन पर क्या विचार किया जाना चाहिए?

कृपया मुझे यह न बताएं, कि मुझे केवल प्रदर्शन की परवाह नहीं करनी चाहिए, जब तक कि मैं वास्तविक सीमाओं को नहीं मारूं। जबकि यह स्पष्ट रूप से एक व्यावहारिक दृष्टिकोण से सच है, मुझे मुख्य रूप से सिद्धांत में दिलचस्पी है। मुझे किसी तरह से इष्टतम ग्राफिक्स ढांचे के निर्माण के आग्रह का मुकाबला करने की आवश्यकता है और मुझे नहीं लगता कि मैं सामान्य रूप से "समय से पहले अनुकूलन व्याख्यान" के साथ ऐसा कर सकता हूं।

घटकों का प्रबंधन

मैं वर्तमान में C # को एक प्रबंधित रैपर के रूप में SlimDX का उपयोग करके DirectX 11 अनुप्रयोग लिख रहा हूं। यह बहुत निम्न स्तर का आवरण है और इसके ऊपर मेरा वर्तमान अमूर्त बनाया गया है।

Direct3D अमूर्त का उपयोग करते समय कुछ स्पष्ट फायदे हैं। पर्यावरण की स्थापना, लोडिंग शेड्स, स्थिरांक स्थापित करना और एक जाल खींचना बहुत सरल है और बहुत कम कोड का उपयोग करता है । इसके अलावा, चूंकि यह अधिकांश घटकों के निर्माण और निपटान का प्रबंधन करता है, इसलिए वे हर जगह स्वचालित रूप से पुन: उपयोग किए जा सकते हैं और मैं मेमोरी लीक से लगभग पूरी तरह से बचता हूं।

  1. आप आमतौर पर सभी ग्राफिक्स घटकों और संसाधनों का प्रबंधन कैसे करते हैं?
  2. क्या आप मेरे उदाहरण के समान कुछ प्रबंधित रैपर की सिफारिश कर सकते हैं?

यहाँ मेरे वर्तमान कार्यान्वयन का एक उदाहरण है। मैं इंटरफेस से काफी खुश हूं। इसमें मेरी जरूरतों के लिए पर्याप्त लचीलापन है और यह उपयोग करने और समझने के लिए बहुत सरल है:

// Init D3D environment
var window = new RenderForm();
var d3d = new Direct3D(window, GraphicsSettings.Default);
var graphics = new GraphicsManager(d3d.Device);

// Load assets
var mesh = GeometryPackage.FromFile(d3d, "teapot.gp");
var texture = Texture.FromFile(d3d, "bricks.dds");

// Render states
graphics.SetViewports(new Viewport(0, 0, 800, 600);
graphics.SetRasterizer(wireFrame: false, culling: CullMode.Back);
graphics.SetDepthState(depthEnabled: true, depthWriteEnabled: true);
graphics.SetBlendState(BlendMethod.Transparency);

// Input layout
graphics.SetLayout("effect.fx", "VS", "vs_4_0",
    new InputElement("POSITION", 0, Format.R32G32B32_Float, 0),
    new InputElement("TEXCOORD", 0, Format.R32G32_Float, 0)
);

// Vertex shader
graphics.SetShader(Shader.Vertex, "effect.fx", "VS", "vs_4_0");
graphics.SetConstants(Shader.Vertex, 0, 4, stream => stream.Write(wvpMatrix));

// Pixel shader
graphics.SetShader(Shader.Pixel, "effect.fx", "PS", "ps_4_0");
graphics.SetTexture(Shader.Pixel, 0, texture);
graphics.SetSampler(Shader.Pixel, 0, Sampler.AnisotropicWrap);
graphics.SetConstants(Shader.Pixel, 0, 1, stream => stream.Write(new Color4(1, 0, 1, 0);

d3d.Run(() =>
{
    // Draw and present
    d3d.BackBuffer.Clear(new Color4(1, 0, 0.5f, 1));
    graphics.SetOutput(d3d.BackBuffer);
    graphics.Draw(mesh);
    d3d.Present();
}

8
इस तरह के प्रश्न के लिए मैं "प्रीमेच्योर ऑप्टिमाइज़ेशन" लेक्चर नहीं दे पाऊंगा, मैं आपको "प्रोफाइल में बदलाव करता हूँ ताकि आप खुद इस लेक्चर को देख सकें।"
टेट्राद

@Tetrad मैं लगभग शर्मिंदा हूँ कि यह कुछ बहुत अच्छी सलाह है। मुझे निश्चित रूप से अधिक प्रोफाइलिंग करनी चाहिए।
लुसियस

1
प्रोफाइलिंग नंबर "पिक्स का जम्मीडिव वर्जन है या ऐसा नहीं हुआ है" निश्चित रूप से =)
पैट्रिक ह्यूजेस

जवाबों:


3

मुझे gamedev.net पर इन थ्रेड्स में हॉजमैन द्वारा उल्लिखित अमूर्त दृष्टिकोण पसंद है:

वह तीन स्तरीय प्रतिपादन प्रणाली का वर्णन करता है:

  1. निम्न-स्तरीय रेंडरिंग API जो "कमांड्स" को स्वीकार करता है, विभिन्न ग्राफिक्स API के अंतरों से अलग नहीं है, जैसे कि Direct3D 9, Direct3D 11 और OpenGL। प्रत्येक "कमांड" एक अलग राज्य या ड्रॉ-कॉल के लिए मैप करता है, जैसे कि एक शीर्ष धारा या बनावट को बांधना, या आदिमों को आकर्षित करना।
  2. API जो "रेंडर आइटम" को स्वीकार करता है, जो सभी राज्यों को एक साथ समूह करता है और एक निश्चित ऑब्जेक्ट को रेंडर करने के लिए एक एकल ड्रॉ-कॉल की आवश्यकता होती है, और उन्हें उन कमांड्स में अनुवाद करता है जो पहले स्तर पर भेजे जाते हैं। रेंडर स्टेट में ड्रॉ-कॉल और "स्टेट ग्रुप्स" का एक स्टैक होता है, जो तार्किक रूप से ग्रुप स्टेट-चेंज होता है। उदाहरण के लिए, आपके पास रेंडर पास के लिए एक राज्य समूह, सामग्री के लिए एक राज्य समूह, ज्यामिति के लिए एक राज्य समूह, उदाहरण के लिए एक राज्य समूह और इसी तरह एक समूह होगा। यह स्तर इन रेंडर आइटमों को निरर्थक राज्य परिवर्तनों को कम करने और किसी भी राज्य परिवर्तनों को कम करने के लिए जिम्मेदार है, जो वास्तव में, निरर्थक हैं।
  3. हाई-लेवल सिस्टम जैसे एक सीन ग्राफ या जीयूआई रेंडरर जो रेंडर आइटम को दूसरे स्तर पर भेजते हैं। गौर करने वाली महत्वपूर्ण बात यह है कि इन प्रणालियों को या तो राज्य छँटाई वाले एल्गोरिदम या विशिष्ट प्रतिपादन एपीआई के बारे में नहीं पता है, जिससे वे पूरी तरह से प्लेटफ़ॉर्म-एग्रोस्टिक बन जाते हैं। निचले स्तर के API के कार्यान्वित होने के बाद उनका उपयोग करना आसान होता है।

अंत में, यह मॉडल एक ही बार में आपकी दोनों समस्याओं को हल करता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.