1 /* 2 * Copyright (C) 2009-2010 Francisco Jerez. 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sublicense, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial 15 * portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 */ 26 27 #include "main/bufferobj.h" 28 #include "nouveau_driver.h" 29 #include "nouveau_array.h" 30 #include "nouveau_bufferobj.h" 31 #include "nouveau_context.h" 32 33 #define EXTRACT(in_t, out_t) extract_func_##in_t##_to_##out_t 34 35 #define EXTRACT_FUNC(in_t, out_t, k) \ 36 static out_t EXTRACT(in_t, out_t) \ 37 (struct nouveau_array *a, int i, int j) { \ 38 in_t x = ((in_t *)(a->buf + i * a->stride))[j]; \ 39 \ 40 return (out_t)x / (k); \ 41 } 42 43 EXTRACT_FUNC(GLchar, unsigned, 1); 44 EXTRACT_FUNC(GLchar, float, SCHAR_MAX); 45 EXTRACT_FUNC(GLubyte, unsigned, 1); 46 EXTRACT_FUNC(GLubyte, float, UCHAR_MAX); 47 EXTRACT_FUNC(GLshort, unsigned, 1); 48 EXTRACT_FUNC(GLshort, float, SHRT_MAX); 49 EXTRACT_FUNC(GLushort, unsigned, 1); 50 EXTRACT_FUNC(GLushort, float, USHRT_MAX); 51 EXTRACT_FUNC(GLint, unsigned, 1); 52 EXTRACT_FUNC(GLint, float, INT_MAX); 53 EXTRACT_FUNC(GLuint, unsigned, 1); 54 EXTRACT_FUNC(GLuint, float, UINT_MAX); 55 EXTRACT_FUNC(GLfloat, unsigned, 1.0 / UINT_MAX); 56 EXTRACT_FUNC(GLfloat, float, 1); 57 58 #undef EXTRACT_FUNC 59 60 static void 61 get_array_extract(struct nouveau_array *a, extract_u_t *extract_u, 62 extract_f_t *extract_f) 63 { 64 switch (a->type) { 65 case GL_BYTE: 66 *extract_u = EXTRACT(GLchar, unsigned); 67 *extract_f = EXTRACT(GLchar, float); 68 break; 69 case GL_UNSIGNED_BYTE: 70 *extract_u = EXTRACT(GLubyte, unsigned); 71 *extract_f = EXTRACT(GLubyte, float); 72 break; 73 case GL_SHORT: 74 *extract_u = EXTRACT(GLshort, unsigned); 75 *extract_f = EXTRACT(GLshort, float); 76 break; 77 case GL_UNSIGNED_SHORT: 78 *extract_u = EXTRACT(GLushort, unsigned); 79 *extract_f = EXTRACT(GLushort, float); 80 break; 81 case GL_INT: 82 *extract_u = EXTRACT(GLint, unsigned); 83 *extract_f = EXTRACT(GLint, float); 84 break; 85 case GL_UNSIGNED_INT: 86 *extract_u = EXTRACT(GLuint, unsigned); 87 *extract_f = EXTRACT(GLuint, float); 88 break; 89 case GL_FLOAT: 90 *extract_u = EXTRACT(GLfloat, unsigned); 91 *extract_f = EXTRACT(GLfloat, float); 92 break; 93 default: 94 assert(0); 95 } 96 } 97 #undef EXTRACT 98 99 void 100 nouveau_init_array(struct nouveau_array *a, int attr, int stride, 101 int fields, int type, struct gl_buffer_object *obj, 102 const void *ptr, GLboolean map, struct gl_context *ctx) 103 { 104 struct nouveau_client *client = context_client(ctx); 105 106 a->attr = attr; 107 a->stride = stride; 108 a->fields = fields; 109 a->type = type; 110 a->buf = NULL; 111 112 if (obj) { 113 if (nouveau_bufferobj_hw(obj)) { 114 struct nouveau_bufferobj *nbo = 115 to_nouveau_bufferobj(obj); 116 117 nouveau_bo_ref(nbo->bo, &a->bo); 118 a->offset = (intptr_t)ptr; 119 120 if (map) { 121 nouveau_bo_map(a->bo, NOUVEAU_BO_RD, client); 122 a->buf = a->bo->map + a->offset; 123 } 124 125 } else { 126 nouveau_bo_ref(NULL, &a->bo); 127 a->offset = 0; 128 129 if (map) 130 a->buf = ADD_POINTERS( 131 nouveau_bufferobj_sys(obj), ptr); 132 } 133 } 134 135 if (a->buf) 136 get_array_extract(a, &a->extract_u, &a->extract_f); 137 } 138 139 void 140 nouveau_deinit_array(struct nouveau_array *a) 141 { 142 a->buf = NULL; 143 a->fields = 0; 144 } 145 146 void 147 nouveau_cleanup_array(struct nouveau_array *a) 148 { 149 nouveau_deinit_array(a); 150 nouveau_bo_ref(NULL, &a->bo); 151 } 152