2012-03-10 53 views
4

我使用的是MacMini '11用的AMD Radeon HD 6630M。我使用數組結構繪製網格,一切正常:60 fps(使用CVDisplayLink)。我使用具有內置屬性的着色器。生活很好。我正在切換到使用一系列結構(交錯),因爲我知道這是「現代」GPU的首選。屬性在着色器中定義。網格畫得很漂亮。但是當我這樣做時,幀頻下降了大約33%(達到40 fps)。這些電話有多個副本。使用工具:時間探查,我得到了以下比較:陣列結構或數組的結構性能

Using structure of arrays (60 fps) 
Running Time Self Symbol Name 
3.0ms 0.0% 3.0 0x21b76c4   ATIRadeonX3000GLDriver 
2.0ms 0.0% 0.0 gldUpdateDispatch ATIRadeonX3000GLDriver 
2.0ms 0.0% 0.0 gleDoDrawDispatchCore  GLEngine 
2.0ms 0.0% 0.0  glDrawElements_ACC_Exec GLEngine 
2.0ms 0.0% 0.0  glDrawElements  libGL.dylib 
2.0ms 0.0% 0.0  -[Mesh draw]  me 

Using array of structures (40 fps) 
Running Time Self  Symbol Name 
393.0ms 7.4% 393.0 0x86f6695    ? 
393.0ms 7.4% 0.0 gleDrawArraysOrElements_ExecCore GLEngine 
393.0ms 7.4% 0.0 glDrawElements_IMM_Exec  GLEngine 
393.0ms 7.4% 0.0  glDrawElements   libGL.dylib 
393.0ms 7.4% 0.0  -[Mesh draw]   me 

看起來libGL函數是做出決定在不同的方向走,和結構的陣列看起來像X3000驅動程序沒有獲取調用。它是否在Apple軟件模擬器中執行?我應該留在數組結構中嗎?有沒有人看過類似的東西?


的屬性的代碼是從蘋果例子,在這些領域,性能沒有用在我的應用程序(至少10個其他地區)。這是從慢版本。正如我所提到的,由於數據不是交錯的,因此我在快速版本中使用了內置屬性。渲染現場,只是緩慢。

我希望這是你在找什麼:

// Step 5 - Bind each of the vertex shader's attributes to the programs 
[self.meshShader addAttribute:@"inPosition"]; 
[self.meshShader addAttribute:@"inNormal"]; 
[self.meshShader addAttribute:@"inTexCoord"]; 

// Step 6 - Link the program 
if([[self meshShader] linkShader] == 0){ 
    self.posAttribute = [meshShader attributeIndex:@"inPosition"]; 
    self.normAttribute = [meshShader attributeIndex:@"inNormal"]; 
    self.texCoordAttribute = [meshShader attributeIndex:@"inTexCoord"]; 

... 


- (void) addAttribute:(NSString *)attributeName 
{ 
    if ([attributes containsObject:attributeName] == NO){ 
     [attributes addObject:attributeName]; 
     glBindAttribLocation(program, [attributes indexOfObject:attributeName],  
     [attributeName UTF8String]); 
    } 
} 

更新: 經過進一步調查: 1)我使用dhpoWare的modelObj裝載機(修改),並且由於它使用的交織排列結構,它也像我的性能明智的結構陣列 - 只是沒有一點點擊。我可能會錯誤地解釋樂器。 modelObj代碼調用glDrawElements_IMM_Exec,它也以迂迴的方式調用gleDoDrawDispatchCore。我不確定它是否只是在glDrawElements_IMM_Exec上累積了一堆調用,然後通過gleDoDrawDispatchCore進行爆發。不知道。 2)我認爲儀器有問題,因爲它顯示GLEngine調用我沒有使用外部鉤子的未使用的內部3ds對象方法之一。我通過在那裏設置一個Xcode斷點來檢查它,並且它從未被觸發。我不再做3DS了。

我想我會繼續環顧四周,也許就回答絆倒。如果有人會給我一個關於一系列結構是否可行的意見,那將不勝感激。

SOLUTION: 我添加了一個VBO到的這個前端和一切都很好。原始代碼來自OpenGL ES 2.0指南,增加了VBO修復了我的問題。幀速率爲60,1ms驅動程序調用。這裏是代碼:

glGenVertexArrays(1, &vaoName); 
glBindVertexArray(vaoName); 

// new - create VBO 
glGenBuffers(1, &vboName); 
glBindBuffer(GL_ARRAY_BUFFER, vboName); 

// Allocate and load position data into the VBO 
glBufferData(GL_ARRAY_BUFFER, sizeof(struct vertexAttribs) * self.numVertices,            
        vertexAttribData, GL_STATIC_DRAW); 
// end of new 

NSUInteger vtxStride = sizeof(struct vertexAttribs); 
//GLfloat *vtxBuf = (GLfloat *)vertexAttribData; // no longer use this 
GLfloat *vtxBuf = (GLfloat *)NULL;    // use this instead 

glEnableVertexAttribArray(self.posAttribute); 
glVertexAttribPointer(self.posAttribute, VERTEX_POS_SIZE, GL_FLOAT, GL_FALSE, 
         vtxStride, vtxBuf); 
vtxBuf += VERTEX_POS_SIZE; 

glEnableVertexAttribArray(self.normAttribute); 
glVertexAttribPointer(self.normAttribute, VERTEX_NORM_SIZE, GL_FLOAT, GL_FALSE, 
         vtxStride, vtxBuf); 
vtxBuf += VERTEX_NORM_SIZE; 

glEnableVertexAttribArray(self.texCoordAttribute); 
glVertexAttribPointer(self.texCoordAttribute, VERTEX_TEX_SIZE, GL_FLOAT, GL_FALSE, 
         vtxStride, vtxBuf); 
... 
+0

你能張貼的設置了屬性陣列的代碼?快速和慢速版本? – 2012-03-10 20:50:49

+1

你可以發佈你的解決方案作爲答案並接受它,讓別人知道這個問題解決了嗎? – 2012-03-27 15:34:33

回答

0

在內存中實現單位跨度訪問的數組結構是經驗法則。它不僅適用於GPU,還適用於像Intel Xeon Phi這樣的CPUS和協處理器。

在你的情況下,我不相信這個代碼部分被髮送到GPU,而不是性能的損失是由於非單位跨度存儲器存取(CPU向/從存儲器)。