15c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell/**************************************************************************
25c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell *
35c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
45c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell * All Rights Reserved.
55c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell *
65c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a
75c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell * copy of this software and associated documentation files (the
85c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell * "Software"), to deal in the Software without restriction, including
95c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell * without limitation the rights to use, copy, modify, merge, publish,
105c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell * distribute, sub license, and/or sell copies of the Software, and to
115c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell * permit persons to whom the Software is furnished to do so, subject to
125c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell * the following conditions:
135c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell *
145c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell * The above copyright notice and this permission notice (including the
155c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell * next paragraph) shall be included in all copies or substantial portions
165c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell * of the Software.
175c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell *
185c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
195c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
205c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
215c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
225c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
235c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
245c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
255c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell *
265c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell **************************************************************************/
275c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell
285c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell /*
295c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell  * Authors:
305c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell  *   Keith Whitwell <keith@tungstengraphics.com>
315c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell  *   Brian Paul
325c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell  */
335c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell
345c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell#include "main/glheader.h"
355c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell#include "main/macros.h"
360ff447e7c4ae26a1c0ae6f92265dee4561816832Brian#include "main/context.h"
375c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell#include "st_context.h"
38c62b197b528293abb56b099503344e3cdd7d6c40Brian#include "st_cb_bitmap.h"
395c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell#include "st_cb_flush.h"
40d2c2e9316d043ab584794a3524f22776deb4c777Keith Whitwell#include "st_cb_clear.h"
41d8e66aca8443c6802ecd8f1a353024ed1d0f32c3Brian#include "st_cb_fbo.h"
42de8a879f5c77dbf5c31251e07b2f1b8d2635716cChia-I Wu#include "st_manager.h"
435c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell#include "pipe/p_context.h"
445c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell#include "pipe/p_defines.h"
45adfbba476db1fc55006efb748656ebb1a481d143Zack Rusin#include "pipe/p_screen.h"
46d2c2e9316d043ab584794a3524f22776deb4c777Keith Whitwell#include "util/u_gen_mipmap.h"
47d2c2e9316d043ab584794a3524f22776deb4c777Keith Whitwell#include "util/u_blit.h"
485c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell
495c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell
50b85b315ebbe25efbd118887bdc87a562d4334fccBrian Paul/** Check if we have a front color buffer and if it's been drawn to. */
51311e40268414649f047ee177ba22a17a2d437843Brian Paulstatic INLINE GLboolean
5254d7c399a888283711bdc00f93cb54a3ce0b30ebBrian Paulis_front_buffer_dirty(struct st_context *st)
53596a92ee7590cd3819aad0139cf779d28e57874dKeith Whitwell{
5431aca27c08d6a385c595d34fe4ee06390bf5b0e8Kristian Høgsberg   struct gl_framebuffer *fb = st->ctx->DrawBuffer;
55da8412ec19ad00627ae9139dc02f46f344bbb6acChia-I Wu   struct st_renderbuffer *strb
56da8412ec19ad00627ae9139dc02f46f344bbb6acChia-I Wu      = st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
57da8412ec19ad00627ae9139dc02f46f344bbb6acChia-I Wu   return strb && strb->defined;
5854d7c399a888283711bdc00f93cb54a3ce0b30ebBrian Paul}
5954d7c399a888283711bdc00f93cb54a3ce0b30ebBrian Paul
6054d7c399a888283711bdc00f93cb54a3ce0b30ebBrian Paul
6154d7c399a888283711bdc00f93cb54a3ce0b30ebBrian Paul/**
62adfbba476db1fc55006efb748656ebb1a481d143Zack Rusin * Tell the screen to display the front color buffer on-screen.
6354d7c399a888283711bdc00f93cb54a3ce0b30ebBrian Paul */
6454d7c399a888283711bdc00f93cb54a3ce0b30ebBrian Paulstatic void
6554d7c399a888283711bdc00f93cb54a3ce0b30ebBrian Pauldisplay_front_buffer(struct st_context *st)
6654d7c399a888283711bdc00f93cb54a3ce0b30ebBrian Paul{
6731aca27c08d6a385c595d34fe4ee06390bf5b0e8Kristian Høgsberg   struct gl_framebuffer *fb = st->ctx->DrawBuffer;
6854d7c399a888283711bdc00f93cb54a3ce0b30ebBrian Paul   struct st_renderbuffer *strb
6954d7c399a888283711bdc00f93cb54a3ce0b30ebBrian Paul      = st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
7054d7c399a888283711bdc00f93cb54a3ce0b30ebBrian Paul
71b3be1651f4a45660b447881f7c61c03a1b24302aKeith Whitwell   if (strb) {
72b3be1651f4a45660b447881f7c61c03a1b24302aKeith Whitwell      /* Hook for copying "fake" frontbuffer if necessary:
73b3be1651f4a45660b447881f7c61c03a1b24302aKeith Whitwell       */
74de8a879f5c77dbf5c31251e07b2f1b8d2635716cChia-I Wu      st_manager_flush_frontbuffer(st);
75b3be1651f4a45660b447881f7c61c03a1b24302aKeith Whitwell   }
765c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell}
775c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell
784019277f09448a0f7ffb7dd620e9bc5613f9b758Brian
797e02303497237cde958c28608477d0c355a8038bMarek Olšákvoid st_flush( struct st_context *st,
809c86c0e88b09370584f767747c52b7f352844ac5Brian Paul               struct pipe_fence_handle **fence )
819c86c0e88b09370584f767747c52b7f352844ac5Brian Paul{
8237e955d491664d27b1335c60ee40b730af6a1515Keith Whitwell   FLUSH_CURRENT(st->ctx, 0);
839c86c0e88b09370584f767747c52b7f352844ac5Brian Paul
84f96405f254819238ef6bce8e7341fcc7d00eaf85Marek Olšák   st_flush_bitmap_cache(st);
859c86c0e88b09370584f767747c52b7f352844ac5Brian Paul
867e02303497237cde958c28608477d0c355a8038bMarek Olšák   st->pipe->flush( st->pipe, fence );
879c86c0e88b09370584f767747c52b7f352844ac5Brian Paul}
889c86c0e88b09370584f767747c52b7f352844ac5Brian Paul
899c86c0e88b09370584f767747c52b7f352844ac5Brian Paul
9054d7c399a888283711bdc00f93cb54a3ce0b30ebBrian Paul/**
9154d7c399a888283711bdc00f93cb54a3ce0b30ebBrian Paul * Flush, and wait for completion.
9254d7c399a888283711bdc00f93cb54a3ce0b30ebBrian Paul */
934ecbd5a70fba3e7d5f8b56ede34867ea5964afc6Brian Paulvoid st_finish( struct st_context *st )
944ecbd5a70fba3e7d5f8b56ede34867ea5964afc6Brian Paul{
954ecbd5a70fba3e7d5f8b56ede34867ea5964afc6Brian Paul   struct pipe_fence_handle *fence = NULL;
964ecbd5a70fba3e7d5f8b56ede34867ea5964afc6Brian Paul
977e02303497237cde958c28608477d0c355a8038bMarek Olšák   st_flush(st, &fence);
984ecbd5a70fba3e7d5f8b56ede34867ea5964afc6Brian Paul
9952e9c9770ac47e9d92df208ec5cfd4e004c45f3dJosé Fonseca   if(fence) {
100bfe88e69988b3d3bdff0b9f6051d0428e1315653Marek Olšák      st->pipe->screen->fence_finish(st->pipe->screen, fence,
101b39bccbd4ed71e9585da4cf5acf7b887b2e90899Marek Olšák                                     PIPE_TIMEOUT_INFINITE);
102adfbba476db1fc55006efb748656ebb1a481d143Zack Rusin      st->pipe->screen->fence_reference(st->pipe->screen, &fence, NULL);
10352e9c9770ac47e9d92df208ec5cfd4e004c45f3dJosé Fonseca   }
1044ecbd5a70fba3e7d5f8b56ede34867ea5964afc6Brian Paul}
1054ecbd5a70fba3e7d5f8b56ede34867ea5964afc6Brian Paul
1064ecbd5a70fba3e7d5f8b56ede34867ea5964afc6Brian Paul
1074ecbd5a70fba3e7d5f8b56ede34867ea5964afc6Brian Paul
1084019277f09448a0f7ffb7dd620e9bc5613f9b758Brian/**
1094019277f09448a0f7ffb7dd620e9bc5613f9b758Brian * Called via ctx->Driver.Flush()
1104019277f09448a0f7ffb7dd620e9bc5613f9b758Brian */
111f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void st_glFlush(struct gl_context *ctx)
1124019277f09448a0f7ffb7dd620e9bc5613f9b758Brian{
11376c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul   struct st_context *st = st_context(ctx);
114574f964667c5ec35f4832c839a9dcc24f92e2aabBrian Paul
115af34fa316db32c09e0753f58d8275a357e187729Keith Whitwell   /* Don't call st_finish() here.  It is not the state tracker's
116af34fa316db32c09e0753f58d8275a357e187729Keith Whitwell    * responsibilty to inject sleeps in the hope of avoiding buffer
117af34fa316db32c09e0753f58d8275a357e187729Keith Whitwell    * synchronization issues.  Calling finish() here will just hide
118af34fa316db32c09e0753f58d8275a357e187729Keith Whitwell    * problems that need to be fixed elsewhere.
119af34fa316db32c09e0753f58d8275a357e187729Keith Whitwell    */
1207e02303497237cde958c28608477d0c355a8038bMarek Olšák   st_flush(st, NULL);
121196214bf2b677a83653d49f79d03752f29df44ecFrancisco Jerez
122196214bf2b677a83653d49f79d03752f29df44ecFrancisco Jerez   if (is_front_buffer_dirty(st)) {
123196214bf2b677a83653d49f79d03752f29df44ecFrancisco Jerez      display_front_buffer(st);
124196214bf2b677a83653d49f79d03752f29df44ecFrancisco Jerez   }
1254abe1eb980ed76d2b2d3383eaab520d0aa2ae6f4Michel Dänzer}
1264abe1eb980ed76d2b2d3383eaab520d0aa2ae6f4Michel Dänzer
1274abe1eb980ed76d2b2d3383eaab520d0aa2ae6f4Michel Dänzer
1284019277f09448a0f7ffb7dd620e9bc5613f9b758Brian/**
1294019277f09448a0f7ffb7dd620e9bc5613f9b758Brian * Called via ctx->Driver.Finish()
1304019277f09448a0f7ffb7dd620e9bc5613f9b758Brian */
131f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void st_glFinish(struct gl_context *ctx)
1325c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell{
13376c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul   struct st_context *st = st_context(ctx);
134aade2f41b0d5cf0fb44e094c0b10cfaf1f621aecBrian Paul
13554d7c399a888283711bdc00f93cb54a3ce0b30ebBrian Paul   st_finish(st);
136196214bf2b677a83653d49f79d03752f29df44ecFrancisco Jerez
137196214bf2b677a83653d49f79d03752f29df44ecFrancisco Jerez   if (is_front_buffer_dirty(st)) {
138196214bf2b677a83653d49f79d03752f29df44ecFrancisco Jerez      display_front_buffer(st);
139196214bf2b677a83653d49f79d03752f29df44ecFrancisco Jerez   }
1405c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell}
1415c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell
1425c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell
1435c2c05600081f811e001a81a600778de0fcab85dKeith Whitwellvoid st_init_flush_functions(struct dd_function_table *functions)
1445c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell{
145596a92ee7590cd3819aad0139cf779d28e57874dKeith Whitwell   functions->Flush = st_glFlush;
146596a92ee7590cd3819aad0139cf779d28e57874dKeith Whitwell   functions->Finish = st_glFinish;
147684282953937a37541f26c6e51ceec4134c62dfbKeith Whitwell
148684282953937a37541f26c6e51ceec4134c62dfbKeith Whitwell   /* Windows opengl32.dll calls glFinish prior to every swapbuffers.
149684282953937a37541f26c6e51ceec4134c62dfbKeith Whitwell    * This is unnecessary and degrades performance.  Luckily we have some
150684282953937a37541f26c6e51ceec4134c62dfbKeith Whitwell    * scope to work around this, as the externally-visible behaviour of
151684282953937a37541f26c6e51ceec4134c62dfbKeith Whitwell    * Finish() is identical to Flush() in all cases - no differences in
152684282953937a37541f26c6e51ceec4134c62dfbKeith Whitwell    * rendering or ReadPixels are visible if we opt not to wait here.
153684282953937a37541f26c6e51ceec4134c62dfbKeith Whitwell    *
154684282953937a37541f26c6e51ceec4134c62dfbKeith Whitwell    * Only set this up on windows to avoid suprise elsewhere.
155684282953937a37541f26c6e51ceec4134c62dfbKeith Whitwell    */
156684282953937a37541f26c6e51ceec4134c62dfbKeith Whitwell#ifdef PIPE_OS_WINDOWS
157684282953937a37541f26c6e51ceec4134c62dfbKeith Whitwell   functions->Finish = st_glFlush;
158684282953937a37541f26c6e51ceec4134c62dfbKeith Whitwell#endif
1595c2c05600081f811e001a81a600778de0fcab85dKeith Whitwell}
160