b43ed98367655902713f4e8d13828ad5254ae919
2 * Mesa 3-D graphics library
4 * Copyright 2003 VMware, Inc.
5 * Copyright 2009 VMware, Inc.
7 * Copyright (C) 2016 Advanced Micro Devices, Inc.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice (including the next
17 * paragraph) shall be included in all copies or substantial portions of the
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
23 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
24 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
25 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
26 * USE OR OTHER DEALINGS IN THE SOFTWARE.
29 #include "main/glheader.h"
30 #include "main/context.h"
31 #include "main/varray.h"
32 #include "main/macros.h"
33 #include "main/sse_minmax.h"
34 #include "x86/common_x86_asm.h"
38 * Compute min and max elements by scanning the index buffer for
39 * glDraw[Range]Elements() calls.
40 * If primitive restart is enabled, we need to ignore restart
41 * indexes when computing min/max.
44 vbo_get_minmax_index(struct gl_context
*ctx
,
45 const struct _mesa_prim
*prim
,
46 const struct _mesa_index_buffer
*ib
,
47 GLuint
*min_index
, GLuint
*max_index
,
50 const GLboolean restart
= ctx
->Array
._PrimitiveRestart
;
51 const GLuint restartIndex
= _mesa_primitive_restart_index(ctx
, ib
->type
);
52 const int index_size
= vbo_sizeof_ib_type(ib
->type
);
56 indices
= (char *) ib
->ptr
+ prim
->start
* index_size
;
57 if (_mesa_is_bufferobj(ib
->obj
)) {
58 GLsizeiptr size
= MIN2(count
* index_size
, ib
->obj
->Size
);
59 indices
= ctx
->Driver
.MapBufferRange(ctx
, (GLintptr
) indices
, size
,
60 GL_MAP_READ_BIT
, ib
->obj
,
65 case GL_UNSIGNED_INT
: {
66 const GLuint
*ui_indices
= (const GLuint
*)indices
;
70 for (i
= 0; i
< count
; i
++) {
71 if (ui_indices
[i
] != restartIndex
) {
72 if (ui_indices
[i
] > max_ui
) max_ui
= ui_indices
[i
];
73 if (ui_indices
[i
] < min_ui
) min_ui
= ui_indices
[i
];
78 #if defined(USE_SSE41)
80 _mesa_uint_array_min_max(ui_indices
, &min_ui
, &max_ui
, count
);
84 for (i
= 0; i
< count
; i
++) {
85 if (ui_indices
[i
] > max_ui
) max_ui
= ui_indices
[i
];
86 if (ui_indices
[i
] < min_ui
) min_ui
= ui_indices
[i
];
93 case GL_UNSIGNED_SHORT
: {
94 const GLushort
*us_indices
= (const GLushort
*)indices
;
98 for (i
= 0; i
< count
; i
++) {
99 if (us_indices
[i
] != restartIndex
) {
100 if (us_indices
[i
] > max_us
) max_us
= us_indices
[i
];
101 if (us_indices
[i
] < min_us
) min_us
= us_indices
[i
];
106 for (i
= 0; i
< count
; i
++) {
107 if (us_indices
[i
] > max_us
) max_us
= us_indices
[i
];
108 if (us_indices
[i
] < min_us
) min_us
= us_indices
[i
];
115 case GL_UNSIGNED_BYTE
: {
116 const GLubyte
*ub_indices
= (const GLubyte
*)indices
;
120 for (i
= 0; i
< count
; i
++) {
121 if (ub_indices
[i
] != restartIndex
) {
122 if (ub_indices
[i
] > max_ub
) max_ub
= ub_indices
[i
];
123 if (ub_indices
[i
] < min_ub
) min_ub
= ub_indices
[i
];
128 for (i
= 0; i
< count
; i
++) {
129 if (ub_indices
[i
] > max_ub
) max_ub
= ub_indices
[i
];
130 if (ub_indices
[i
] < min_ub
) min_ub
= ub_indices
[i
];
138 unreachable("not reached");
141 if (_mesa_is_bufferobj(ib
->obj
)) {
142 ctx
->Driver
.UnmapBuffer(ctx
, ib
->obj
, MAP_INTERNAL
);
147 * Compute min and max elements for nr_prims
150 vbo_get_minmax_indices(struct gl_context
*ctx
,
151 const struct _mesa_prim
*prims
,
152 const struct _mesa_index_buffer
*ib
,
157 GLuint tmp_min
, tmp_max
;
164 for (i
= 0; i
< nr_prims
; i
++) {
165 const struct _mesa_prim
*start_prim
;
167 start_prim
= &prims
[i
];
168 count
= start_prim
->count
;
169 /* Do combination if possible to reduce map/unmap count */
170 while ((i
+ 1 < nr_prims
) &&
171 (prims
[i
].start
+ prims
[i
].count
== prims
[i
+1].start
)) {
172 count
+= prims
[i
+1].count
;
175 vbo_get_minmax_index(ctx
, start_prim
, ib
, &tmp_min
, &tmp_max
, count
);
176 *min_index
= MIN2(*min_index
, tmp_min
);
177 *max_index
= MAX2(*max_index
, tmp_max
);