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