1b8e80941Smrg/* 2b8e80941Smrg * Copyright © 2012 Intel Corporation 3b8e80941Smrg * 4b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5b8e80941Smrg * copy of this software and associated documentation files (the "Software"), 6b8e80941Smrg * to deal in the Software without restriction, including without limitation 7b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the 9b8e80941Smrg * Software is furnished to do so, subject to the following conditions: 10b8e80941Smrg * 11b8e80941Smrg * The above copyright notice and this permission notice (including the next 12b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the 13b8e80941Smrg * Software. 14b8e80941Smrg * 15b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20b8e80941Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21b8e80941Smrg * IN THE SOFTWARE. 22b8e80941Smrg */ 23b8e80941Smrg 24b8e80941Smrg/** \file marshal.h 25b8e80941Smrg * 26b8e80941Smrg * Declarations of functions related to marshalling GL calls from a client 27b8e80941Smrg * thread to a server thread. 28b8e80941Smrg */ 29b8e80941Smrg 30b8e80941Smrg#ifndef MARSHAL_H 31b8e80941Smrg#define MARSHAL_H 32b8e80941Smrg 33b8e80941Smrg#include "main/glthread.h" 34b8e80941Smrg#include "main/context.h" 35b8e80941Smrg#include "main/macros.h" 36b8e80941Smrg 37b8e80941Smrgstruct marshal_cmd_base 38b8e80941Smrg{ 39b8e80941Smrg /** 40b8e80941Smrg * Type of command. See enum marshal_dispatch_cmd_id. 41b8e80941Smrg */ 42b8e80941Smrg uint16_t cmd_id; 43b8e80941Smrg 44b8e80941Smrg /** 45b8e80941Smrg * Size of command, in multiples of 4 bytes, including cmd_base. 46b8e80941Smrg */ 47b8e80941Smrg uint16_t cmd_size; 48b8e80941Smrg}; 49b8e80941Smrg 50b8e80941Smrgstatic inline void * 51b8e80941Smrg_mesa_glthread_allocate_command(struct gl_context *ctx, 52b8e80941Smrg uint16_t cmd_id, 53b8e80941Smrg size_t size) 54b8e80941Smrg{ 55b8e80941Smrg struct glthread_state *glthread = ctx->GLThread; 56b8e80941Smrg struct glthread_batch *next = &glthread->batches[glthread->next]; 57b8e80941Smrg struct marshal_cmd_base *cmd_base; 58b8e80941Smrg const size_t aligned_size = ALIGN(size, 8); 59b8e80941Smrg 60b8e80941Smrg if (unlikely(next->used + size > MARSHAL_MAX_CMD_SIZE)) { 61b8e80941Smrg _mesa_glthread_flush_batch(ctx); 62b8e80941Smrg next = &glthread->batches[glthread->next]; 63b8e80941Smrg } 64b8e80941Smrg 65b8e80941Smrg cmd_base = (struct marshal_cmd_base *)&next->buffer[next->used]; 66b8e80941Smrg next->used += aligned_size; 67b8e80941Smrg cmd_base->cmd_id = cmd_id; 68b8e80941Smrg cmd_base->cmd_size = aligned_size; 69b8e80941Smrg return cmd_base; 70b8e80941Smrg} 71b8e80941Smrg 72b8e80941Smrg/** 73b8e80941Smrg * Instead of conditionally handling marshaling previously-bound user vertex 74b8e80941Smrg * array data in draw calls (deprecated and removed in GL core), we just 75b8e80941Smrg * disable threading at the point where the user sets a user vertex array. 76b8e80941Smrg */ 77b8e80941Smrgstatic inline bool 78b8e80941Smrg_mesa_glthread_is_non_vbo_vertex_attrib_pointer(const struct gl_context *ctx) 79b8e80941Smrg{ 80b8e80941Smrg struct glthread_state *glthread = ctx->GLThread; 81b8e80941Smrg 82b8e80941Smrg return ctx->API != API_OPENGL_CORE && !glthread->vertex_array_is_vbo; 83b8e80941Smrg} 84b8e80941Smrg 85b8e80941Smrg/** 86b8e80941Smrg * Instead of conditionally handling marshaling immediate index data in draw 87b8e80941Smrg * calls (deprecated and removed in GL core), we just disable threading. 88b8e80941Smrg */ 89b8e80941Smrgstatic inline bool 90b8e80941Smrg_mesa_glthread_is_non_vbo_draw_elements(const struct gl_context *ctx) 91b8e80941Smrg{ 92b8e80941Smrg struct glthread_state *glthread = ctx->GLThread; 93b8e80941Smrg 94b8e80941Smrg return ctx->API != API_OPENGL_CORE && !glthread->element_array_is_vbo; 95b8e80941Smrg} 96b8e80941Smrg 97b8e80941Smrg#define DEBUG_MARSHAL_PRINT_CALLS 0 98b8e80941Smrg 99b8e80941Smrg/** 100b8e80941Smrg * This is printed when we have fallen back to a sync. This can happen when 101b8e80941Smrg * MARSHAL_MAX_CMD_SIZE is exceeded. 102b8e80941Smrg */ 103b8e80941Smrgstatic inline void 104b8e80941Smrgdebug_print_sync_fallback(const char *func) 105b8e80941Smrg{ 106b8e80941Smrg#if DEBUG_MARSHAL_PRINT_CALLS 107b8e80941Smrg printf("fallback to sync: %s\n", func); 108b8e80941Smrg#endif 109b8e80941Smrg} 110b8e80941Smrg 111b8e80941Smrg 112b8e80941Smrgstatic inline void 113b8e80941Smrgdebug_print_sync(const char *func) 114b8e80941Smrg{ 115b8e80941Smrg#if DEBUG_MARSHAL_PRINT_CALLS 116b8e80941Smrg printf("sync: %s\n", func); 117b8e80941Smrg#endif 118b8e80941Smrg} 119b8e80941Smrg 120b8e80941Smrgstatic inline void 121b8e80941Smrgdebug_print_marshal(const char *func) 122b8e80941Smrg{ 123b8e80941Smrg#if DEBUG_MARSHAL_PRINT_CALLS 124b8e80941Smrg printf("marshal: %s\n", func); 125b8e80941Smrg#endif 126b8e80941Smrg} 127b8e80941Smrg 128b8e80941Smrgstatic inline void 129b8e80941Smrgdebug_print_unmarshal(const char *func) 130b8e80941Smrg{ 131b8e80941Smrg#if DEBUG_MARSHAL_PRINT_CALLS 132b8e80941Smrg printf("unmarshal: %s\n", func); 133b8e80941Smrg#endif 134b8e80941Smrg} 135b8e80941Smrg 136b8e80941Smrgstruct _glapi_table * 137b8e80941Smrg_mesa_create_marshal_table(const struct gl_context *ctx); 138b8e80941Smrg 139b8e80941Smrgsize_t 140b8e80941Smrg_mesa_unmarshal_dispatch_cmd(struct gl_context *ctx, const void *cmd); 141b8e80941Smrg 142b8e80941Smrgstatic inline void 143b8e80941Smrg_mesa_post_marshal_hook(struct gl_context *ctx) 144b8e80941Smrg{ 145b8e80941Smrg /* This can be enabled for debugging whether a failure is a synchronization 146b8e80941Smrg * problem between the main thread and the worker thread, or a failure in 147b8e80941Smrg * how we actually marshal. 148b8e80941Smrg */ 149b8e80941Smrg if (false) 150b8e80941Smrg _mesa_glthread_finish(ctx); 151b8e80941Smrg} 152b8e80941Smrg 153b8e80941Smrg 154b8e80941Smrg/** 155b8e80941Smrg * Checks whether we're on a compat context for code-generated 156b8e80941Smrg * glBindVertexArray(). 157b8e80941Smrg * 158b8e80941Smrg * In order to decide whether a draw call uses only VBOs for vertex and index 159b8e80941Smrg * buffers, we track the current vertex and index buffer bindings by 160b8e80941Smrg * glBindBuffer(). However, the index buffer binding is stored in the vertex 161b8e80941Smrg * array as opposed to the context. If we were to accurately track whether 162b8e80941Smrg * the index buffer was a user pointer ot not, we'd have to track it per 163b8e80941Smrg * vertex array, which would mean synchronizing with the client thread and 164b8e80941Smrg * looking into the hash table to find the actual vertex array object. That's 165b8e80941Smrg * more tracking than we'd like to do in the main thread, if possible. 166b8e80941Smrg * 167b8e80941Smrg * Instead, just punt for now and disable threading on apps using vertex 168b8e80941Smrg * arrays and compat contexts. Apps using vertex arrays can probably use a 169b8e80941Smrg * core context. 170b8e80941Smrg */ 171b8e80941Smrgstatic inline bool 172b8e80941Smrg_mesa_glthread_is_compat_bind_vertex_array(const struct gl_context *ctx) 173b8e80941Smrg{ 174b8e80941Smrg return ctx->API != API_OPENGL_CORE; 175b8e80941Smrg} 176b8e80941Smrg 177b8e80941Smrgstruct marshal_cmd_Enable; 178b8e80941Smrgstruct marshal_cmd_ShaderSource; 179b8e80941Smrgstruct marshal_cmd_Flush; 180b8e80941Smrgstruct marshal_cmd_BindBuffer; 181b8e80941Smrgstruct marshal_cmd_BufferData; 182b8e80941Smrgstruct marshal_cmd_BufferSubData; 183b8e80941Smrgstruct marshal_cmd_NamedBufferData; 184b8e80941Smrgstruct marshal_cmd_NamedBufferSubData; 185b8e80941Smrgstruct marshal_cmd_ClearBuffer; 186b8e80941Smrg#define marshal_cmd_ClearBufferfv marshal_cmd_ClearBuffer 187b8e80941Smrg#define marshal_cmd_ClearBufferiv marshal_cmd_ClearBuffer 188b8e80941Smrg#define marshal_cmd_ClearBufferuiv marshal_cmd_ClearBuffer 189b8e80941Smrg#define marshal_cmd_ClearBufferfi marshal_cmd_ClearBuffer 190b8e80941Smrg 191b8e80941Smrgvoid 192b8e80941Smrg_mesa_unmarshal_Enable(struct gl_context *ctx, 193b8e80941Smrg const struct marshal_cmd_Enable *cmd); 194b8e80941Smrg 195b8e80941Smrgvoid GLAPIENTRY 196b8e80941Smrg_mesa_marshal_Enable(GLenum cap); 197b8e80941Smrg 198b8e80941Smrgvoid GLAPIENTRY 199b8e80941Smrg_mesa_marshal_ShaderSource(GLuint shader, GLsizei count, 200b8e80941Smrg const GLchar * const *string, const GLint *length); 201b8e80941Smrg 202b8e80941Smrgvoid 203b8e80941Smrg_mesa_unmarshal_ShaderSource(struct gl_context *ctx, 204b8e80941Smrg const struct marshal_cmd_ShaderSource *cmd); 205b8e80941Smrg 206b8e80941Smrgvoid GLAPIENTRY 207b8e80941Smrg_mesa_marshal_Flush(void); 208b8e80941Smrg 209b8e80941Smrgvoid 210b8e80941Smrg_mesa_unmarshal_Flush(struct gl_context *ctx, 211b8e80941Smrg const struct marshal_cmd_Flush *cmd); 212b8e80941Smrg 213b8e80941Smrgvoid GLAPIENTRY 214b8e80941Smrg_mesa_marshal_BindBuffer(GLenum target, GLuint buffer); 215b8e80941Smrg 216b8e80941Smrgvoid 217b8e80941Smrg_mesa_unmarshal_BindBuffer(struct gl_context *ctx, 218b8e80941Smrg const struct marshal_cmd_BindBuffer *cmd); 219b8e80941Smrg 220b8e80941Smrgvoid 221b8e80941Smrg_mesa_unmarshal_BufferData(struct gl_context *ctx, 222b8e80941Smrg const struct marshal_cmd_BufferData *cmd); 223b8e80941Smrg 224b8e80941Smrgvoid GLAPIENTRY 225b8e80941Smrg_mesa_marshal_BufferData(GLenum target, GLsizeiptr size, const GLvoid * data, 226b8e80941Smrg GLenum usage); 227b8e80941Smrg 228b8e80941Smrgvoid 229b8e80941Smrg_mesa_unmarshal_BufferSubData(struct gl_context *ctx, 230b8e80941Smrg const struct marshal_cmd_BufferSubData *cmd); 231b8e80941Smrg 232b8e80941Smrgvoid GLAPIENTRY 233b8e80941Smrg_mesa_marshal_BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, 234b8e80941Smrg const GLvoid * data); 235b8e80941Smrg 236b8e80941Smrgvoid 237b8e80941Smrg_mesa_unmarshal_NamedBufferData(struct gl_context *ctx, 238b8e80941Smrg const struct marshal_cmd_NamedBufferData *cmd); 239b8e80941Smrg 240b8e80941Smrgvoid GLAPIENTRY 241b8e80941Smrg_mesa_marshal_NamedBufferData(GLuint buffer, GLsizeiptr size, 242b8e80941Smrg const GLvoid * data, GLenum usage); 243b8e80941Smrg 244b8e80941Smrgvoid 245b8e80941Smrg_mesa_unmarshal_NamedBufferSubData(struct gl_context *ctx, 246b8e80941Smrg const struct marshal_cmd_NamedBufferSubData *cmd); 247b8e80941Smrg 248b8e80941Smrgvoid GLAPIENTRY 249b8e80941Smrg_mesa_marshal_NamedBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr size, 250b8e80941Smrg const GLvoid * data); 251b8e80941Smrg 252b8e80941Smrgvoid 253b8e80941Smrg_mesa_unmarshal_ClearBufferfv(struct gl_context *ctx, 254b8e80941Smrg const struct marshal_cmd_ClearBuffer *cmd); 255b8e80941Smrg 256b8e80941Smrgvoid GLAPIENTRY 257b8e80941Smrg_mesa_marshal_ClearBufferfv(GLenum buffer, GLint drawbuffer, 258b8e80941Smrg const GLfloat *value); 259b8e80941Smrg 260b8e80941Smrgvoid 261b8e80941Smrg_mesa_unmarshal_ClearBufferiv(struct gl_context *ctx, 262b8e80941Smrg const struct marshal_cmd_ClearBuffer *cmd); 263b8e80941Smrg 264b8e80941Smrgvoid GLAPIENTRY 265b8e80941Smrg_mesa_marshal_ClearBufferiv(GLenum buffer, GLint drawbuffer, 266b8e80941Smrg const GLint *value); 267b8e80941Smrg 268b8e80941Smrgvoid 269b8e80941Smrg_mesa_unmarshal_ClearBufferuiv(struct gl_context *ctx, 270b8e80941Smrg const struct marshal_cmd_ClearBuffer *cmd); 271b8e80941Smrg 272b8e80941Smrgvoid GLAPIENTRY 273b8e80941Smrg_mesa_marshal_ClearBufferuiv(GLenum buffer, GLint drawbuffer, 274b8e80941Smrg const GLuint *value); 275b8e80941Smrg 276b8e80941Smrgvoid 277b8e80941Smrg_mesa_unmarshal_ClearBufferfi(struct gl_context *ctx, 278b8e80941Smrg const struct marshal_cmd_ClearBuffer *cmd); 279b8e80941Smrg 280b8e80941Smrgvoid GLAPIENTRY 281b8e80941Smrg_mesa_marshal_ClearBufferfi(GLenum buffer, GLint drawbuffer, 282b8e80941Smrg const GLfloat depth, const GLint stencil); 283b8e80941Smrg 284b8e80941Smrg#endif /* MARSHAL_H */ 285