1bf215546Sopenharmony_ci/**************************************************************************
2bf215546Sopenharmony_ci *
3bf215546Sopenharmony_ci * Copyright 2007 VMware, Inc.
4bf215546Sopenharmony_ci * All Rights Reserved.
5bf215546Sopenharmony_ci *
6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the
8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including
9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish,
10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to
11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to
12bf215546Sopenharmony_ci * the following conditions:
13bf215546Sopenharmony_ci *
14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the
15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions
16bf215546Sopenharmony_ci * of the Software.
17bf215546Sopenharmony_ci *
18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25bf215546Sopenharmony_ci *
26bf215546Sopenharmony_ci **************************************************************************/
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ci /*
29bf215546Sopenharmony_ci  * Authors:
30bf215546Sopenharmony_ci  *   Keith Whitwell <keithw@vmware.com>
31bf215546Sopenharmony_ci  *   Brian Paul
32bf215546Sopenharmony_ci  */
33bf215546Sopenharmony_ci
34bf215546Sopenharmony_ci#include "main/glheader.h"
35bf215546Sopenharmony_ci#include "main/macros.h"
36bf215546Sopenharmony_ci#include "main/context.h"
37bf215546Sopenharmony_ci#include "st_context.h"
38bf215546Sopenharmony_ci#include "st_cb_bitmap.h"
39bf215546Sopenharmony_ci#include "st_cb_flush.h"
40bf215546Sopenharmony_ci#include "st_cb_clear.h"
41bf215546Sopenharmony_ci#include "st_context.h"
42bf215546Sopenharmony_ci#include "st_manager.h"
43bf215546Sopenharmony_ci#include "pipe/p_context.h"
44bf215546Sopenharmony_ci#include "pipe/p_defines.h"
45bf215546Sopenharmony_ci#include "pipe/p_screen.h"
46bf215546Sopenharmony_ci#include "util/u_gen_mipmap.h"
47bf215546Sopenharmony_ci
48bf215546Sopenharmony_ci
49bf215546Sopenharmony_civoid
50bf215546Sopenharmony_cist_flush(struct st_context *st,
51bf215546Sopenharmony_ci         struct pipe_fence_handle **fence,
52bf215546Sopenharmony_ci         unsigned flags)
53bf215546Sopenharmony_ci{
54bf215546Sopenharmony_ci   /* We want to call this function periodically.
55bf215546Sopenharmony_ci    * Typically, it has nothing to do so it shouldn't be expensive.
56bf215546Sopenharmony_ci    */
57bf215546Sopenharmony_ci   st_context_free_zombie_objects(st);
58bf215546Sopenharmony_ci
59bf215546Sopenharmony_ci   st_flush_bitmap_cache(st);
60bf215546Sopenharmony_ci   st->pipe->flush(st->pipe, fence, flags);
61bf215546Sopenharmony_ci}
62bf215546Sopenharmony_ci
63bf215546Sopenharmony_ci
64bf215546Sopenharmony_ci/**
65bf215546Sopenharmony_ci * Flush, and wait for completion.
66bf215546Sopenharmony_ci */
67bf215546Sopenharmony_civoid
68bf215546Sopenharmony_cist_finish(struct st_context *st)
69bf215546Sopenharmony_ci{
70bf215546Sopenharmony_ci   struct pipe_fence_handle *fence = NULL;
71bf215546Sopenharmony_ci
72bf215546Sopenharmony_ci   st_flush(st, &fence, PIPE_FLUSH_ASYNC | PIPE_FLUSH_HINT_FINISH);
73bf215546Sopenharmony_ci
74bf215546Sopenharmony_ci   if (fence) {
75bf215546Sopenharmony_ci      st->screen->fence_finish(st->screen, NULL, fence,
76bf215546Sopenharmony_ci                               PIPE_TIMEOUT_INFINITE);
77bf215546Sopenharmony_ci      st->screen->fence_reference(st->screen, &fence, NULL);
78bf215546Sopenharmony_ci   }
79bf215546Sopenharmony_ci
80bf215546Sopenharmony_ci   st_manager_flush_swapbuffers();
81bf215546Sopenharmony_ci}
82bf215546Sopenharmony_ci
83bf215546Sopenharmony_ci
84bf215546Sopenharmony_civoid
85bf215546Sopenharmony_cist_glFlush(struct gl_context *ctx, unsigned gallium_flush_flags)
86bf215546Sopenharmony_ci{
87bf215546Sopenharmony_ci   struct st_context *st = st_context(ctx);
88bf215546Sopenharmony_ci
89bf215546Sopenharmony_ci   /* Don't call st_finish() here.  It is not the state tracker's
90bf215546Sopenharmony_ci    * responsibilty to inject sleeps in the hope of avoiding buffer
91bf215546Sopenharmony_ci    * synchronization issues.  Calling finish() here will just hide
92bf215546Sopenharmony_ci    * problems that need to be fixed elsewhere.
93bf215546Sopenharmony_ci    */
94bf215546Sopenharmony_ci   st_flush(st, NULL, gallium_flush_flags);
95bf215546Sopenharmony_ci
96bf215546Sopenharmony_ci   st_manager_flush_frontbuffer(st);
97bf215546Sopenharmony_ci}
98bf215546Sopenharmony_ci
99bf215546Sopenharmony_civoid
100bf215546Sopenharmony_cist_glFinish(struct gl_context *ctx)
101bf215546Sopenharmony_ci{
102bf215546Sopenharmony_ci   struct st_context *st = st_context(ctx);
103bf215546Sopenharmony_ci
104bf215546Sopenharmony_ci   st_finish(st);
105bf215546Sopenharmony_ci
106bf215546Sopenharmony_ci   st_manager_flush_frontbuffer(st);
107bf215546Sopenharmony_ci}
108bf215546Sopenharmony_ci
109bf215546Sopenharmony_ci
110bf215546Sopenharmony_cistatic GLenum
111bf215546Sopenharmony_cigl_reset_status_from_pipe_reset_status(enum pipe_reset_status status)
112bf215546Sopenharmony_ci{
113bf215546Sopenharmony_ci   switch (status) {
114bf215546Sopenharmony_ci   case PIPE_NO_RESET:
115bf215546Sopenharmony_ci      return GL_NO_ERROR;
116bf215546Sopenharmony_ci   case PIPE_GUILTY_CONTEXT_RESET:
117bf215546Sopenharmony_ci      return GL_GUILTY_CONTEXT_RESET_ARB;
118bf215546Sopenharmony_ci   case PIPE_INNOCENT_CONTEXT_RESET:
119bf215546Sopenharmony_ci      return GL_INNOCENT_CONTEXT_RESET_ARB;
120bf215546Sopenharmony_ci   case PIPE_UNKNOWN_CONTEXT_RESET:
121bf215546Sopenharmony_ci      return GL_UNKNOWN_CONTEXT_RESET_ARB;
122bf215546Sopenharmony_ci   default:
123bf215546Sopenharmony_ci      assert(0);
124bf215546Sopenharmony_ci      return GL_NO_ERROR;
125bf215546Sopenharmony_ci   }
126bf215546Sopenharmony_ci}
127bf215546Sopenharmony_ci
128bf215546Sopenharmony_ci
129bf215546Sopenharmony_cistatic void
130bf215546Sopenharmony_cist_device_reset_callback(void *data, enum pipe_reset_status status)
131bf215546Sopenharmony_ci{
132bf215546Sopenharmony_ci   struct st_context *st = data;
133bf215546Sopenharmony_ci
134bf215546Sopenharmony_ci   assert(status != PIPE_NO_RESET);
135bf215546Sopenharmony_ci
136bf215546Sopenharmony_ci   st->reset_status = status;
137bf215546Sopenharmony_ci   _mesa_set_context_lost_dispatch(st->ctx);
138bf215546Sopenharmony_ci}
139bf215546Sopenharmony_ci
140bf215546Sopenharmony_ci
141bf215546Sopenharmony_ci/**
142bf215546Sopenharmony_ci * Query information about GPU resets observed by this context
143bf215546Sopenharmony_ci *
144bf215546Sopenharmony_ci * Called via \c dd_function_table::GetGraphicsResetStatus.
145bf215546Sopenharmony_ci */
146bf215546Sopenharmony_cistatic GLenum
147bf215546Sopenharmony_cist_get_graphics_reset_status(struct gl_context *ctx)
148bf215546Sopenharmony_ci{
149bf215546Sopenharmony_ci   struct st_context *st = st_context(ctx);
150bf215546Sopenharmony_ci   enum pipe_reset_status status;
151bf215546Sopenharmony_ci
152bf215546Sopenharmony_ci   if (st->reset_status != PIPE_NO_RESET) {
153bf215546Sopenharmony_ci      status = st->reset_status;
154bf215546Sopenharmony_ci      st->reset_status = PIPE_NO_RESET;
155bf215546Sopenharmony_ci   } else {
156bf215546Sopenharmony_ci      status = st->pipe->get_device_reset_status(st->pipe);
157bf215546Sopenharmony_ci      if (status != PIPE_NO_RESET)
158bf215546Sopenharmony_ci         st_device_reset_callback(st, status);
159bf215546Sopenharmony_ci   }
160bf215546Sopenharmony_ci
161bf215546Sopenharmony_ci   return gl_reset_status_from_pipe_reset_status(status);
162bf215546Sopenharmony_ci}
163bf215546Sopenharmony_ci
164bf215546Sopenharmony_ci
165bf215546Sopenharmony_civoid
166bf215546Sopenharmony_cist_install_device_reset_callback(struct st_context *st)
167bf215546Sopenharmony_ci{
168bf215546Sopenharmony_ci   if (st->pipe->set_device_reset_callback) {
169bf215546Sopenharmony_ci      struct pipe_device_reset_callback cb;
170bf215546Sopenharmony_ci      cb.reset = st_device_reset_callback;
171bf215546Sopenharmony_ci      cb.data = st;
172bf215546Sopenharmony_ci      st->pipe->set_device_reset_callback(st->pipe, &cb);
173bf215546Sopenharmony_ci   }
174bf215546Sopenharmony_ci}
175bf215546Sopenharmony_ci
176bf215546Sopenharmony_ci
177bf215546Sopenharmony_civoid
178bf215546Sopenharmony_cist_init_flush_functions(struct pipe_screen *screen,
179bf215546Sopenharmony_ci                        struct dd_function_table *functions)
180bf215546Sopenharmony_ci{
181bf215546Sopenharmony_ci   if (screen->get_param(screen, PIPE_CAP_DEVICE_RESET_STATUS_QUERY))
182bf215546Sopenharmony_ci      functions->GetGraphicsResetStatus = st_get_graphics_reset_status;
183bf215546Sopenharmony_ci}
184