/*
* Mesa 3-D graphics library
*
- * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2007-2008 VMware, Inc.
* Copyright (C) 2010 LunarG Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
#define SEGMENT_SIZE 1024
#define MAP_SIZE 256
-/* The largest possible index withing an index buffer */
+/* The largest possible index within an index buffer */
#define MAX_ELT_IDX 0xffffffff
struct vsplit_frontend {
/**
* Add a fetch element and add it to the draw elements.
*/
-static INLINE void
-vsplit_add_cache(struct vsplit_frontend *vsplit, unsigned fetch, unsigned ofbias)
+static inline void
+vsplit_add_cache(struct vsplit_frontend *vsplit, unsigned fetch)
{
unsigned hash;
hash = fetch % MAP_SIZE;
- /* If the value isn't in the cache of it's an overflow due to the
+ /* If the value isn't in the cache or it's an overflow due to the
* element bias */
- if (vsplit->cache.fetches[hash] != fetch || ofbias) {
+ if (vsplit->cache.fetches[hash] != fetch) {
/* update cache */
vsplit->cache.fetches[hash] = fetch;
vsplit->cache.draws[hash] = vsplit->cache.num_fetch_elts;
/**
* Returns the base index to the elements array.
- * The value is checked for overflows (both integer overflows
- * and the elements array overflow).
+ * The value is checked for integer overflow (not sure it can happen?).
*/
-static INLINE unsigned
-vsplit_get_base_idx(struct vsplit_frontend *vsplit,
- unsigned start, unsigned fetch, unsigned *ofbit)
+static inline unsigned
+vsplit_get_base_idx(unsigned start, unsigned fetch)
{
- struct draw_context *draw = vsplit->draw;
- unsigned elt_idx = draw_overflow_uadd(start, fetch, MAX_ELT_IDX);
- if (ofbit)
- *ofbit = 0;
-
- /* Overflown indices need to wrap to the first element
- * in the index buffer */
- if (elt_idx >= draw->pt.user.eltMax) {
- if (ofbit)
- *ofbit = 1;
- elt_idx = 0;
- }
-
- return elt_idx;
-}
-
-/**
- * Returns the element index adjust for the element bias.
- * The final element index is created from the actual element
- * index, plus the element bias, clamped to maximum elememt
- * index if that addition overflows.
- */
-static INLINE unsigned
-vsplit_get_bias_idx(struct vsplit_frontend *vsplit,
- int idx, int bias, unsigned *ofbias)
-{
- int res = idx + bias;
-
- if (ofbias)
- *ofbias = 0;
-
- if (idx > 0 && bias > 0) {
- if (res < idx || res < bias) {
- res = DRAW_MAX_FETCH_IDX;
- if (ofbias)
- *ofbias = 1;
- }
- } else if (idx < 0 && bias < 0) {
- if (res > idx || res > bias) {
- res = DRAW_MAX_FETCH_IDX;
- if (ofbias)
- *ofbias = 1;
- }
- }
-
- return res;
+ return draw_overflow_uadd(start, fetch, MAX_ELT_IDX);
}
-#define VSPLIT_CREATE_IDX(elts, start, fetch, elt_bias) \
- unsigned elt_idx; \
- unsigned ofbit; \
- unsigned ofbias; \
- elt_idx = vsplit_get_base_idx(vsplit, start, fetch, &ofbit); \
- elt_idx = vsplit_get_bias_idx(vsplit, ofbit ? 0 : DRAW_GET_IDX(elts, elt_idx), elt_bias, &ofbias)
-static INLINE void
+static inline void
vsplit_add_cache_ubyte(struct vsplit_frontend *vsplit, const ubyte *elts,
unsigned start, unsigned fetch, int elt_bias)
{
struct draw_context *draw = vsplit->draw;
- VSPLIT_CREATE_IDX(elts, start, fetch, elt_bias);
- vsplit_add_cache(vsplit, elt_idx, ofbias);
+ unsigned elt_idx;
+ elt_idx = vsplit_get_base_idx(start, fetch);
+ elt_idx = (unsigned)((int)(DRAW_GET_IDX(elts, elt_idx)) + elt_bias);
+ /* unlike the uint case this can only happen with elt_bias */
+ if (elt_bias && elt_idx == DRAW_MAX_FETCH_IDX && !vsplit->cache.has_max_fetch) {
+ unsigned hash = elt_idx % MAP_SIZE;
+ vsplit->cache.fetches[hash] = 0;
+ vsplit->cache.has_max_fetch = TRUE;
+ }
+ vsplit_add_cache(vsplit, elt_idx);
}
-static INLINE void
+static inline void
vsplit_add_cache_ushort(struct vsplit_frontend *vsplit, const ushort *elts,
unsigned start, unsigned fetch, int elt_bias)
{
struct draw_context *draw = vsplit->draw;
- VSPLIT_CREATE_IDX(elts, start, fetch, elt_bias);
- vsplit_add_cache(vsplit, elt_idx, ofbias);
+ unsigned elt_idx;
+ elt_idx = vsplit_get_base_idx(start, fetch);
+ elt_idx = (unsigned)((int)(DRAW_GET_IDX(elts, elt_idx)) + elt_bias);
+ /* unlike the uint case this can only happen with elt_bias */
+ if (elt_bias && elt_idx == DRAW_MAX_FETCH_IDX && !vsplit->cache.has_max_fetch) {
+ unsigned hash = elt_idx % MAP_SIZE;
+ vsplit->cache.fetches[hash] = 0;
+ vsplit->cache.has_max_fetch = TRUE;
+ }
+ vsplit_add_cache(vsplit, elt_idx);
}
* Add a fetch element and add it to the draw elements. The fetch element is
* in full range (uint).
*/
-static INLINE void
+static inline void
vsplit_add_cache_uint(struct vsplit_frontend *vsplit, const uint *elts,
unsigned start, unsigned fetch, int elt_bias)
{
struct draw_context *draw = vsplit->draw;
- unsigned raw_elem_idx = start + fetch + elt_bias;
- VSPLIT_CREATE_IDX(elts, start, fetch, elt_bias);
-
- /* special care for DRAW_MAX_FETCH_IDX */
- if (raw_elem_idx == DRAW_MAX_FETCH_IDX && !vsplit->cache.has_max_fetch) {
- unsigned hash = fetch % MAP_SIZE;
- vsplit->cache.fetches[hash] = raw_elem_idx - 1; /* force update */
+ unsigned elt_idx;
+ /*
+ * The final element index is just element index plus element bias.
+ */
+ elt_idx = vsplit_get_base_idx(start, fetch);
+ elt_idx = (unsigned)((int)(DRAW_GET_IDX(elts, elt_idx)) + elt_bias);
+ /* Take care for DRAW_MAX_FETCH_IDX (since cache is initialized to -1). */
+ if (elt_idx == DRAW_MAX_FETCH_IDX && !vsplit->cache.has_max_fetch) {
+ unsigned hash = elt_idx % MAP_SIZE;
+ /* force update - any value will do except DRAW_MAX_FETCH_IDX */
+ vsplit->cache.fetches[hash] = 0;
vsplit->cache.has_max_fetch = TRUE;
}
-
- vsplit_add_cache(vsplit, elt_idx, ofbias);
+ vsplit_add_cache(vsplit, elt_idx);
}