में बनावट बफर को पढ़ना और अपडेट करना मैं इस पर थोड़ा सा पागल हो रहा हूं क्योंकि मुझे वास्तव में क्या गलत नहीं है और क्या नहीं। वहां कुछ ऐसा होना चाहिए जिसे मैंने बहुत गलत समझा है या कोड या ड्राइवर में किसी प्रकार का बग है। मैं इसे पिछले सप्ताह के रूप में नवीनतम उत्प्रेरक बीटा ड्राइवरों के साथ एएमडी राडेन 5850 पर चला रहा हूं।ओपनजीएल/जीएलएसएल 4.3
ठीक है, मैंने ओआईटी-प्रतिपादन कार्यान्वयन करना शुरू किया और एक शेडर स्टोरेज बफर ऑब्जेक्ट में सहेजी गई स्ट्रक्चर-सरणी का उपयोग करना चाहता था। खैर, उसमें इंडेक्स मेमोरी तरीके से गलत तरीके से प्रतिबिंबित/आगे बढ़ रहे थे और मुझे लगता है कि यह एक ड्राइवर बग था - क्योंकि उन्होंने हाल ही में ऐसी चीज का समर्थन करना शुरू किया है, हाँ, यह एक बीटा ड्राइवर है। इसलिए मैंने बदले में बनावट बफर ऑब्जेक्ट्स से एक पायदान और उपयोग की गई glsl-images को वापस ले जाया, जो मुझे लगता है कि कम से कम कुछ समय पहले समर्थित था।
अभी भी सही तरीके से व्यवहार नहीं कर रहा था। इसलिए मैंने एक साधारण परीक्षण प्रोजेक्ट बनाया और थोड़ी देर के लिए फंसे हुए और अब मुझे लगता है कि मैंने यह कहां चुरा लिया है।
ठीक है! पहले मैं बफर और बनावट आरंभ करना। मैं देखना क्या अद्यतन करता है समय है कि इतने के बीच में ... अद्यतन और आकर्षित, अद्यतन और आकर्षित एक देरी के साथ -
//Clearcolor and Cleardepth setup, disabling of depth test, compile and link shaderprogram etc.
...
//
GLint tbo, tex;
datasize = resolution.x * resolution.y * 4 * sizeof(GLfloat);
glGenBuffers(1, &tbo);
glBindBuffer(GL_TEXTURE_BUFFER, tbo);
glBufferData(GL_TEXTURE_BUFFER, datasize, NULL, GL_DYNAMIC_COPY);
glBindBuffer(GL_TEXTURE_BUFFER, 0);
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_BUFFER, tex);
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, tex);
glBindTexture(GL_TEXTURE_BUFFER, 0);
glBindImageTexture(2, tex, 0, GL_TRUE, 0, GL_READ_WRITE, GL_RGBA32F);
फिर प्रतिपादन पाश है।
अद्यतन इस तरह है ...
ivec2 resolution; //Using GLM
resolution.x = (GLuint)(iResolution.x + .5f);
resolution.y = (GLuint)(iResolution.y + .5f);
glBindBuffer(GL_TEXTURE_BUFFER, tbo);
void *ptr = glMapBuffer(GL_TEXTURE_BUFFER, GL_WRITE_ONLY);
color *c = (color*)ptr; //color is a simple struct containing 4 GLfloats.
for (int i = 0; i < resolution.x*resolution.y; ++i)
{
c[i].r = c[i].g = c[i].b = c[i].a = 1.0f;
}
glUnmapBuffer(GL_TEXTURE_BUFFER); c = (color*)(ptr = NULL);
glBindBuffer(GL_TEXTURE_BUFFER, 0);
और आकर्षित इस तरह है ...
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMemoryBarrier(GL_ALL_BARRIER_BITS);
ShaderProgram->Use(); //Simple shader program class
quad->Draw(GL_TRIANGLES); //Simple mesh class containing triangles (vertices) and colors
glFinish();
glMemoryBarrier(GL_ALL_BARRIER_BITS);
मैं बस के आसपास कुछ स्मृति बाधाओं डाल अतिरिक्त सुनिश्चित करने के लिए , प्रदर्शन से अधिक नुकसान नहीं करना चाहिए? खैर, परिणाम वैसे भी बाधाओं के साथ या बिना थे, इसलिए ... :)
शेडर प्रोग्राम एक साधारण पास-थ्रू वर्टेक्स शेडर और टुकड़ा शेडर है जो परीक्षण कर रहा है।
वर्टेक्स शेडर
#version 430
in vec3 in_vertex;
void main(void)
{
gl_Position = vec4(in_vertex, 1.0);
}
टुकड़ा शेडर (मुझे लगता है कि सुसंगत & memoryBarrier() वास्तव में यहाँ की जरूरत नहीं है के बाद से मैं ड्रा/टुकड़ा शेडर निष्पादन के बीच में CPU पर उन्हें करने के ... लेकिन यह नुकसान करता है)
#version 430
uniform vec2 iResolution;
layout(binding = 2, rgba32f) coherent uniform imageBuffer colorMap;
out vec4 FragColor;
void main(void)
{
ivec2 res = ivec2(int(iResolution.x + 0.5), int(iResolution.y + 0.5));
ivec2 pos = ivec2(int(gl_FragCoord.x + 0.5), int(gl_FragCoord.y + 0.5));
int pixelpos = pos.y * res.x + pos.x;
memoryBarrier();
vec4 prevPixel = imageLoad(colorMap, pixelpos);
vec4 green = vec4(0.0, 1.0, 0.0, 0.0);
imageStore(colorMap, pixelpos, green);
FragColor = prevPixel;
}
उम्मीद: एक सफेद स्क्रीन! चूंकि मैं प्रत्येक ड्रॉ के बीच पूरे बफर में "सफेद" लिख रहा हूं, भले ही मैं वास्तविक शेडर में लोड के बाद छवि को हरा लिख रहा हूं।
परिणाम: पहला फ्रेम हरा है, बाकी काला है। मेरे कुछ हिस्से में लगता है कि एक सफेद फ्रेम है जो देखा जा सकता है या कुछ बनाम चीज जो इसे टायर करता है, लेकिन यह तर्क के लिए एक जगह है? : पी
ठीक है, तो मैंने एक नई चीज की कोशिश की और अद्यतन ब्लॉक को स्थानांतरित कर दिया (जहां मैं पूरे बफर में "सफेद" लिख रहा हूं) इसके बजाय init में।
अपेक्षा: एक सफेद पहला फ्रेम, उसके बाद एक हरे रंग की स्क्रीन।
परिणाम: अरे हाँ अपने हरे allright! भले ही पहला फ्रेम सफेद/हरे रंग की कुछ कलाकृतियों के साथ है, कभी-कभी केवल हरा। यह शायद किसी चीज के बनाम (की कमी) के कारण हो सकता है, उसने इसे चेक नहीं किया है। फिर भी, मुझे लगता है कि मुझे वह परिणाम मिला जो मैं ढूंढ रहा था।
निष्कर्ष मैं इस से बाहर आकर्षित कर सकते हैं कुछ मेरे अद्यतन में कुछ गड़बड़ है है। क्या यह बफर को बनावट संदर्भ या कुछ से अनदेखा करता है? उस स्थिति में, यह अजीब नहीं है कि पहला फ्रेम ठीक है? यह केवल पहली छविस्टोर-कमांड (अच्छी तरह से, पहला फ्रेम) के बाद है कि बनावट सभी काले हो जाती है - "बाइंड() - नक्शा() - unmap() - बाइंड (0)" पहली बार काम करता है, लेकिन बाद में नहीं। GlMapBuffer की मेरी तस्वीर यह है कि यह जीपीयू से सीपीयू मेमोरी में बफर डेटा की प्रतिलिपि बनाता है, चलो आप इसे बदल दें और इसे वापस कॉपी न करें। खैर, अभी मैंने सोचा था कि शायद यह बफर को जीपीयू से सीपीयू में कॉपी नहीं करेगा और फिर वापस, लेकिन केवल एक ही रास्ता है? क्या यह GL_WRITE_ONLY हो सकता है जिसे GL_READ_WRITE में बदला जाना चाहिए? खैर, मैंने दोनों की कोशिश की है। माना जाता है कि उनमें से एक सही था, क्या मेरी स्क्रीन स्क्रीन का उपयोग करते समय हमेशा "टेस्ट 1" में सफेद नहीं होगी?
अर्घ, मैं गलत क्या कर रहा हूँ?
संपादित करें: ठीक है, मैं अभी भी नहीं पता ... जाहिर है glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, tex);
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, tbo);
होना चाहिए, लेकिन मुझे लगता है कि tbo
और tex
एक ही मूल्य था, क्योंकि वे एक ही क्रम में उत्पन्न किया गया। इसलिए यह इस कार्यान्वयन में काम किया। मैंने इसे हल किया है, इस तरह से मैं बहुत खुश नहीं हूं क्योंकि मुझे लगता है कि उपरोक्त काम करना चाहिए। दूसरी तरफ, नया समाधान शायद थोड़ा बेहतर प्रदर्शन-वार है। इसके बजाय glMapBuffer()
का उपयोग करने का , मैं CPU/GPU के बीच डेटा भेजने के लिए glBufferSubData()
और glgetBufferSubData()
का उपयोग करके CPU पर TBO-स्मृति की एक प्रति रखने के लिए बंद। यह काम किया, तो मैं बस उस समाधान के साथ जारी रखूंगा।
लेकिन, हाँ, सवाल अब भी खड़ा है - क्यों मेरी बनावट बफर वस्तुओं के साथ नहीं glMapBuffer()
काम करता है?