2011-08-06 31 views
6

Tôi chỉ tìm thấy OpenGL specification for ARB_map_buffer_range sau đây.Opengl Bản đồ không đồng bộ/không bị chặn

Tôi tự hỏi liệu có thể thực hiện các cuộc gọi bản đồ không chặn bằng tiện ích mở rộng này không?

Hiện tại trong ứng dụng của tôi, im đang hiển thị cho FBO mà sau đó tôi ánh xạ tới bộ đệm PBO lưu trữ.

glMapBuffer(target_, GL_READ_ONLY); 

Tuy nhiên, vấn đề với điều này là nó chặn chuỗi hiển thị trong khi truyền dữ liệu.

Tôi có thể giảm vấn đề này bằng cách pipelining hiển thị, nhưng độ trễ là một vấn đề lớn trong ứng dụng của tôi.

Câu hỏi của tôi là liệu tôi có thể sử dụng map_buffer_range với MAP_UNSYNCHRONIZED_BIT và đợi thao tác bản đồ kết thúc trên chuỗi khác hay trì hoãn thao tác bản đồ trên cùng một chuỗi, trong khi chuỗi hiển thị hiển thị khung tiếp theo.

ví dụ:

thread 1: 

map(); 
render_next_frame(); 

thread 2: 

wait_for_map 

hoặc

thread 1: 

map(); 
while(!is_map_ready()) 
    do_some_rendering_for_next_frame(); 

gì tôi không rõ là làm thế nào tôi biết khi nào hoạt động bản đồ đã sẵn sàng, các đặc điểm kỹ thuật chỉ đề cập đến "kỹ thuật đồng bộ khác để đảm bảo hoạt động đúng".

Bất kỳ ý tưởng nào?

Trả lời

5

Nói chung, không thể thực hiện "bản đồ không chặn", nhưng bạn có thể ánh xạ mà không bị chặn.

Lý do tại sao có thể không có "bản đồ không chặn" là thời điểm cuộc gọi hàm trả về, bạn có thể truy cập dữ liệu, vì vậy người lái xe phải đảm bảo dữ liệu ở đó, tích cực. Nếu dữ liệu chưa được chuyển, người lái xe khác có thể làm gì nhưng chặn.
Chủ đề không làm điều này tốt hơn, và có thể làm cho nó tồi tệ hơn (thêm đồng bộ hóa và các vấn đề chia sẻ ngữ cảnh). Chủ đề không thể loại bỏ nhu cầu truyền dữ liệu một cách kỳ diệu.

Và điều này dẫn đến cách không chặn lập bản đồ: Chỉ bản đồ khi bạn chắc chắn rằng quá trình chuyển hoàn tất. Một cách an toàn để làm điều này là ánh xạ bộ đệm sau khi lật bộ đệm hoặc sau glFinish hoặc sau khi chờ đợi đối tượng truy vấn/hàng rào. Sử dụng một hàng rào là cách thích hợp hơn nếu bạn không thể đợi cho đến khi bộ đệm được đổi chỗ. Một hàng rào sẽ không ngăn chặn đường ống, nhưng sẽ cho bạn biết việc chuyển nhượng của bạn có được thực hiện hay không (glFinish có thể có hoặc không, nhưng sẽ có thể là gian hàng). Đọc sau khi trao đổi bộ đệm cũng là 100% an toàn, nhưng có thể không chấp nhận được nếu bạn cần dữ liệu trong cùng một khung (hoạt động hoàn hảo cho ảnh chụp màn hình hoặc để tính toán biểu đồ cho tonemapping).

Cách an toàn hơn là chèn "một số nội dung khác" và hy vọng rằng trong thời gian đó quá trình chuyển đã hoàn tất.


Đối với các bình luận dưới đây:
Câu trả lời này là không không chính xác. Nó không thể làm bất kỳ tốt hơn so với dữ liệu truy cập sau khi nó có sẵn (điều này nên được rõ ràng). Điều này có nghĩa là bạn phải đồng bộ/chặn, cách này hay cách khác, không có lựa chọn nào khác.
Mặc dù, từ một điểm rất pedantic của xem, bạn có thể sử dụng tất nhiên GL_MAP_UNSYNCHRONIZED_BIT để có được một chặn không hoạt động bản đồ, điều này là hoàn toàn không thích hợp, vì nó không hoạt động trừ khi bạn rõ ràng tái tạo ngầm đồng bộ như mô tả ở trên. Một ánh xạ mà bạn không thể truy cập một cách an toàn là tốt cho không có gì.

Lập bản đồ và truy cập bộ đệm mà OpenGL đang chuyển dữ liệu sang mà không đồng bộ hóa/chặn (ngầm hoặc rõ ràng) có nghĩa là "hành vi không xác định", chỉ là một từ ngữ đẹp hơn cho "kết quả có thể là rác".
Nếu, mặt khác, bạn đồng bộ hóa một cách rõ ràng (với hàng rào như mô tả ở trên), thì không liên quan đến việc bạn có sử dụng cờ không đồng bộ hay không, vì không cần đồng bộ ngầm hơn nữa.

+0

Bạn có thể giải thích thêm một chút về "đối tượng truy vấn" này không? Âm thanh như tôi có thể sử dụng để trì hoãn cuộc gọi đến bản đồ nếu nó chưa sẵn sàng. – ronag

+2

Điều đó đề cập đến [ARB_sync] (http://www.opengl.org/registry/specs/ARB/sync.txt) cũng nằm trong lõi 3.2. Điều này cho phép bạn chèn các truy vấn đồng bộ hóa ("hàng rào") vào dòng lệnh, bạn có thể đợi (máy khách hoặc máy khách + máy chủ) hoặc truy vấn trạng thái hoàn thành. Nếu truy vấn đồng bộ trả về rằng nó được thực hiện, nó có nghĩa là tất cả các lệnh đã xảy ra trước khi bạn chèn hàng rào đã hoàn thành. Vì vậy, trong trường hợp của bạn, bạn biết rằng dữ liệu là nơi bạn muốn nó, và lập bản đồ bộ đệm sẽ không chặn. – Damon

+0

Tuyệt vời, vì vậy nếu tôi hiểu điều này một cách chính xác, tôi nên đặt một truy vấn đồng bộ hóa ngay sau khi cuộc gọi của tôi đến glReadPixels (thiết bị-> chuyển host). Khi tôi biết rằng truy vấn đã sẵn sàng, thì cuộc gọi tới bản đồ sẽ không chặn (hoặc chỉ rất ngắn)? – ronag

5

Nếu bạn ánh xạ bộ đệm với GL_MAP_UNSYNCHRONIZED_BIT, trình điều khiển sẽ không đợi cho đến khi OpenGL được thực hiện với bộ nhớ đó trước khi ánh xạ nó cho bạn. Vì vậy, bạn sẽ nhận được nhiều hơn hoặc ít hơn ngay lập tức truy cập vào nó.

Vấn đề là điều này không không có nghĩa là bạn chỉ có thể đọc/ghi bộ nhớ đó. Nếu OpenGL đang đọc hoặc ghi vào bộ đệm đó và bạn thay đổi nó ... chào mừng bạn đến hành vi không xác định. Điều này có thể bao gồm sự cố.

Do đó, để thực sự sử dụng ánh xạ không đồng bộ, bạn phải đồng bộ hóa hành vi của mình với quyền truy cập của OpenGL của bộ đệm đó. Điều này sẽ liên quan đến việc sử dụng ARB_sync objects (hoặc NV_fence nếu bạn chỉ có trên NVIDIA và chưa cập nhật trình điều khiển của bạn gần đây).

Điều đó đang được nói, nếu bạn đang sử dụng đối tượng hàng rào để đồng bộ hóa quyền truy cập vào bộ đệm, thì bạn thực sự không cần GL_MAP_UNSYNCHRONIZED_BIT chút nào. Một khi bạn hoàn thành hàng rào, hoặc phát hiện rằng nó đã hoàn thành, bạn có thể bản đồ bộ đệm bình thường và nó sẽ hoàn thành ngay lập tức (trừ khi một số hoạt động khác là đọc/ghi quá).

Nói chung, truy cập không đồng bộ được sử dụng tốt nhất khi bạn cần truy cập ghi chi tiết vào bộ đệm. Trong trường hợp này, việc sử dụng tốt các đối tượng đồng bộ sẽ giúp bạn có được những gì bạn thực sự cần (khả năng cho biết khi nào hoạt động bản đồ kết thúc).


Phụ lục: Ở trên hiện đã lỗi thời (tùy theo phần cứng của bạn). Nhờ OpenGL 4.4/ARB_buffer_storage, bây giờ bạn không chỉ có thể ánh xạ không đồng bộ, bạn có thể giữ một vùng đệm được ánh xạ vô thời hạn. Có, bạn có thể có bộ đệm được ánh xạ khi đang sử dụng.

Điều này được thực hiện bằng cách tạo bộ nhớ không thay đổi và cung cấp bộ nhớ đó với (trong số những thứ khác) GL_MAP_PERSISTENT_BIT. Sau đó, bạn glMapBufferRange, cũng cung cấp cùng một bit.

Bây giờ về mặt kỹ thuật, thay đổi đó không có gì nhiều. Bạn vẫn cần đồng bộ hóa các tác vụ của mình với OpenGL. Nếu bạn viết nội dung vào vùng đệm, bạn cần phải issue a barrier hoặc flush that region of the buffer explicitly. Và nếu bạn đang đọc, bạn vẫn cần sử dụng fence sync object để đảm bảo rằng dữ liệu thực tế là ở đó trước khi đọc nó (và trừ khi bạn sử dụng GL_MAP_COHERENT_BIT cũng vậy, bạn cần phải đưa ra một rào cản trước khi đọc).

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