2013-07-12 32 views
7

Tôi đang sử dụng FBO + RBO và thay vì đệm kép thông thường trên bộ đệm khung mặc định, tôi vẽ đến RBO và sau đó ghi trực tiếp lên bộ đệm GL_FRONT của FBO mặc định (0) trong một bối cảnh OpenGL đệm duy nhất.đệm đôi với FBO + RBO và glFinish()

Điều đó là tốt và tôi không nhận được bất kỳ nhấp nháy nào, nhưng nếu cảnh trở nên phức tạp một chút, tôi trải qua một lượt giảm HUGE trong fps, điều gì đó kỳ lạ đến mức tôi biết điều gì đó đã sai. Và tôi không có nghĩa là từ 1/60 đến 1/30 vì một đồng bộ bỏ qua, tôi có nghĩa là giảm 90% fps đột ngột.

Tôi đã thử một glFlush() sau khi blit - không có sự khác biệt, sau đó tôi đã thử một glFinish() sau blit, và tôi đã tăng 10x fps.

Vì vậy, tôi đã sử dụng bộ đệm ngẫu nhiên thường xuyên trên bộ đệm khung mặc định và bộ đệm(), và khung hình/giây cũng có tăng cường, như khi sử dụng glFinish().

Tôi không thể hiểu được điều gì đang xảy ra. Tại sao glFinish() tạo nên nhiều sự khác biệt khi nó không nên? và, nó là ok để sử dụng một RBO và blit trực tiếp trên bộ đệm phía trước, thay vì sử dụng một cuộc gọi swapbuffers trong một bối cảnh đệm đôi? Tôi biết Im thiếu vsync nhưng người quản lý tổng hợp sẽ đồng bộ hóa anyway (infact im không nhìn thấy bất kỳ rách), nó chỉ là nếu màn hình bị thiếu 9 trong số 10 khung hình.

Và chỉ vì tò mò, có phải là người dùng swapbuffers() sử dụng glFinish() trên một trong hai cửa sổ hoặc Linux không?

+0

* "sau đó tôi đã thử glFinish() sau blit, và tôi đã tăng 10x fps" * - Thay vào đó giống như một vấn đề với phương pháp định thời gian của bạn, một cái gì đó như nó không được đồng bộ hóa tốt với GPU của bạn. glFinish' tất nhiên đạt được). Một số mã nữa sẽ là thú vị. –

+0

Tôi không thấy làm thế nào reimplementing đệm đôi sẽ tốt hơn anyway, xem xét tất cả những thứ trong các trình điều khiển như Triple đệm, Adaptive VSync và như vậy. –

+0

@BartekBanachewicz Nó có ý nghĩa nếu bạn cần bộ đệm cho cả màn hình trên màn hình và hiển thị ngoài màn hình, nhưng bạn sẽ thực sự có một số công việc để (lại) tối ưu hóa phần trên màn hình. – KillianDS

Trả lời

1

Tôi tin rằng đó là sự cố liên quan đến đồng bộ hóa.

Khi hiển thị trực tiếp tới RBO và đổ sang bộ đệm phía trước, đơn giản là không có đồng bộ nào. Do đó trên các cảnh phức tạp, hàng đợi lệnh GPU sẽ lấp đầy khá nhanh, sau đó hàng đợi trình điều khiển CPU cũng sẽ nhanh chóng lấp đầy, cho đến khi đồng bộ CPU bị buộc bởi trình điều khiển trong lệnh OpenGL. Tại thời điểm đó, chuỗi CPU sẽ bị tạm dừng. Điều này có nghĩa là, không có bất kỳ hình thức đồng bộ nào, kết xuất phức tạp (kết xuất mà một hoặc nhiều lệnh OpenGL sẽ được đặt trong hàng đợi) sẽ luôn khiến cho chuỗi CPU bị dừng tại một số điểm, vì hàng đợi sẽ lấp đầy, CPU sẽ phát hành nhiều lệnh hơn.

Để có được sự tương tác người dùng trơn tru (không đổi), cần đồng bộ hóa (với một swapbuffers cụ thể cho nền tảng) hoặc để ngăn CPU làm cho mọi thứ tồi tệ hơn khi phát hành ngày càng nhiều lệnh (mà lần lượt sẽ mang lại sự phân luồng CPU để dừng chân sau)

tham khảo: OpenGL Synchronization

+0

CPU phát hành nhiều lệnh hơn và không nên làm cho mọi thứ tồi tệ hơn cho việc dựng hình thực tế, tuy nhiên nó sẽ làm cho CPU và GPU không đồng bộ, CPU có thể nghĩ rằng nó đã kết xuất 20 khung trong khi GPU chỉ hoàn thành 1. Nhưng tôi không nghĩ rằng CPU đăng nhiều lệnh trong hàng đợi sẽ ảnh hưởng đến tốc độ khung hình có thể nhìn thấy mà nhiều (đo tốc độ khung hình mặc dù ...). Tuy nhiên, đó chỉ là một chút trực giác, không thể thử nó ngay bây giờ :). – KillianDS

1

có những vấn đề riêng biệt ở đây, đó cũng là một chút kết nối.

1) Tự thực hiện lại việc đệm đôi, trong khi trên cùng một thông số, không giống với trình điều khiển. Trình điều khiển được tối ưu hóa cao cho trường hợp phổ biến. Ví dụ, nhiều chip có đơn vị 2d và 3d riêng biệt. Hoán đổi trong swapBuffers thường được xử lý bởi đơn vị 2d. Blitting một bộ đệm có lẽ vẫn được thực hiện với các đơn vị 3d.

2) glFlush (và Kết thúc) bị bỏ qua bởi nhiều trình điều khiển. Flush là một di tích của máy chủ khách hàng rendering. Kết thúc được dự định cho hồ sơ. Nhưng nó đã bị lạm dụng để làm việc xung quanh lỗi trình điều khiển. Vì vậy, bây giờ trình điều khiển thường bỏ qua nó để cải thiện hiệu suất của mã kế thừa sử dụng Kết thúc như một giải pháp thay thế.

3) Chỉ cần không làm đệm đơn. Không có lợi ích hiệu suất và bạn đang làm việc ra khỏi con đường "tốt" của người lái xe. Quản lý cửa sổ được tối ưu hóa siêu cho opengl đệm đôi.

4) Những gì bạn nhìn thấy rất giống như bạn chỉ đơn giản là rò rỉ tài nguyên. Bạn có cấp phát bộ đệm mà không giải phóng chúng không? Một cách nhanh chóng và dơ bẩn để kiểm tra là nếu bất kỳ hàm glGen * nào trả về các id ngày càng tăng.

Các vấn đề liên quan