parent
03e3116a75
commit
b6f2d8f531
@ -0,0 +1,328 @@ |
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 VMware, Inc. |
||||
* All Rights Reserved. |
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a |
||||
* copy of this software and associated documentation files (the |
||||
* "Software"), to deal in the Software without restriction, including |
||||
* without limitation the rights to use, copy, modify, merge, publish, |
||||
* distribute, sub license, and/or sell copies of the Software, and to |
||||
* permit persons to whom the Software is furnished to do so, subject to |
||||
* the following conditions: |
||||
*
|
||||
* The above copyright notice and this permission notice (including the |
||||
* next paragraph) shall be included in all copies or substantial portions |
||||
* of the Software. |
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||
*
|
||||
**************************************************************************/ |
||||
|
||||
/**
|
||||
* @file |
||||
* Generic bitmask implementation. |
||||
*
|
||||
* @author Jose Fonseca <jfonseca@vmware.com> |
||||
*/ |
||||
|
||||
|
||||
#include "pipe/p_compiler.h" |
||||
#include "util/u_debug.h" |
||||
|
||||
#include "util/u_memory.h" |
||||
#include "util/u_bitmask.h" |
||||
|
||||
|
||||
typedef uint32_t util_bitmask_word;
|
||||
|
||||
|
||||
#define UTIL_BITMASK_INITIAL_WORDS 16 |
||||
#define UTIL_BITMASK_BITS_PER_BYTE 8 |
||||
#define UTIL_BITMASK_BITS_PER_WORD (sizeof(util_bitmask_word) * UTIL_BITMASK_BITS_PER_BYTE) |
||||
|
||||
|
||||
struct util_bitmask |
||||
{ |
||||
util_bitmask_word *words; |
||||
|
||||
/** Number of bits we can currently hold */ |
||||
unsigned size; |
||||
|
||||
/** Number of consecutive bits set at the start of the bitmask */ |
||||
unsigned filled; |
||||
}; |
||||
|
||||
|
||||
struct util_bitmask * |
||||
util_bitmask_create(void) |
||||
{ |
||||
struct util_bitmask *bm; |
||||
|
||||
bm = MALLOC_STRUCT(util_bitmask); |
||||
if(!bm) |
||||
return NULL; |
||||
|
||||
bm->words = (util_bitmask_word *)CALLOC(UTIL_BITMASK_INITIAL_WORDS, sizeof(util_bitmask_word)); |
||||
if(!bm->words) { |
||||
FREE(bm); |
||||
return NULL; |
||||
} |
||||
|
||||
bm->size = UTIL_BITMASK_INITIAL_WORDS * UTIL_BITMASK_BITS_PER_WORD; |
||||
bm->filled = 0; |
||||
|
||||
return bm; |
||||
} |
||||
|
||||
|
||||
/**
|
||||
* Resize the bitmask if necessary
|
||||
*/ |
||||
static INLINE boolean |
||||
util_bitmask_resize(struct util_bitmask *bm, |
||||
unsigned minimum_index) |
||||
{ |
||||
unsigned minimum_size = minimum_index + 1; |
||||
unsigned new_size; |
||||
util_bitmask_word *new_words; |
||||
|
||||
/* Check integer overflow */ |
||||
if(!minimum_size) |
||||
return FALSE; |
||||
|
||||
if(bm->size >= minimum_size) |
||||
return TRUE; |
||||
|
||||
assert(bm->size % UTIL_BITMASK_BITS_PER_WORD == 0); |
||||
new_size = bm->size; |
||||
while(new_size < minimum_size) { |
||||
new_size *= 2; |
||||
/* Check integer overflow */ |
||||
if(new_size < bm->size) |
||||
return FALSE; |
||||
} |
||||
assert(new_size); |
||||
assert(new_size % UTIL_BITMASK_BITS_PER_WORD == 0); |
||||
|
||||
new_words = (util_bitmask_word *)REALLOC((void *)bm->words, |
||||
bm->size / UTIL_BITMASK_BITS_PER_BYTE, |
||||
new_size / UTIL_BITMASK_BITS_PER_BYTE); |
||||
if(!new_words) |
||||
return FALSE; |
||||
|
||||
memset(new_words + bm->size/UTIL_BITMASK_BITS_PER_WORD,
|
||||
0,
|
||||
(new_size - bm->size)/UTIL_BITMASK_BITS_PER_BYTE); |
||||
|
||||
bm->size = new_size; |
||||
bm->words = new_words; |
||||
|
||||
return TRUE; |
||||
} |
||||
|
||||
|
||||
/**
|
||||
* Lazily update the filled. |
||||
*/ |
||||
static INLINE void |
||||
util_bitmask_filled_set(struct util_bitmask *bm, |
||||
unsigned index) |
||||
{ |
||||
assert(bm->filled <= bm->size); |
||||
assert(index < bm->size); |
||||
|
||||
if(index == bm->filled) { |
||||
++bm->filled; |
||||
assert(bm->filled <= bm->size); |
||||
} |
||||
} |
||||
|
||||
static INLINE void |
||||
util_bitmask_filled_unset(struct util_bitmask *bm, |
||||
unsigned index) |
||||
{ |
||||
assert(bm->filled <= bm->size); |
||||
assert(index < bm->size); |
||||
|
||||
if(index < bm->filled) |
||||
bm->filled = index; |
||||
} |
||||
|
||||
|
||||
unsigned |
||||
util_bitmask_add(struct util_bitmask *bm) |
||||
{ |
||||
unsigned word; |
||||
unsigned bit; |
||||
util_bitmask_word mask; |
||||
|
||||
assert(bm); |
||||
|
||||
/* linear search for an empty index */ |
||||
word = bm->filled / UTIL_BITMASK_BITS_PER_WORD; |
||||
bit = bm->filled % UTIL_BITMASK_BITS_PER_WORD; |
||||
mask = 1 << bit; |
||||
while(word < bm->size / UTIL_BITMASK_BITS_PER_WORD) { |
||||
while(bit < UTIL_BITMASK_BITS_PER_WORD) { |
||||
if(!(bm->words[word] & mask)) |
||||
goto found; |
||||
++bm->filled; |
||||
++bit; |
||||
mask <<= 1; |
||||
} |
||||
++word; |
||||
bit = 0; |
||||
mask = 1; |
||||
} |
||||
found: |
||||
|
||||
/* grow the bitmask if necessary */ |
||||
if(!util_bitmask_resize(bm, bm->filled)) |
||||
return UTIL_BITMASK_INVALID_INDEX; |
||||
|
||||
assert(!(bm->words[word] & mask)); |
||||
bm->words[word] |= mask; |
||||
|
||||
return bm->filled++; |
||||
} |
||||
|
||||
|
||||
unsigned |
||||
util_bitmask_set(struct util_bitmask *bm,
|
||||
unsigned index) |
||||
{ |
||||
unsigned word; |
||||
unsigned bit; |
||||
util_bitmask_word mask; |
||||
|
||||
assert(bm); |
||||
|
||||
/* grow the bitmask if necessary */ |
||||
if(!util_bitmask_resize(bm, index)) |
||||
return UTIL_BITMASK_INVALID_INDEX; |
||||
|
||||
word = index / UTIL_BITMASK_BITS_PER_WORD; |
||||
bit = index % UTIL_BITMASK_BITS_PER_WORD; |
||||
mask = 1 << bit; |
||||
|
||||
bm->words[word] |= mask; |
||||
|
||||
util_bitmask_filled_set(bm, index); |
||||
|
||||
return index; |
||||
} |
||||
|
||||
|
||||
void |
||||
util_bitmask_clear(struct util_bitmask *bm,
|
||||
unsigned index) |
||||
{ |
||||
unsigned word; |
||||
unsigned bit; |
||||
util_bitmask_word mask; |
||||
|
||||
assert(bm); |
||||
|
||||
if(index >= bm->size) |
||||
return; |
||||
|
||||
word = index / UTIL_BITMASK_BITS_PER_WORD; |
||||
bit = index % UTIL_BITMASK_BITS_PER_WORD; |
||||
mask = 1 << bit; |
||||
|
||||
bm->words[word] &= ~mask; |
||||
|
||||
util_bitmask_filled_unset(bm, index); |
||||
} |
||||
|
||||
|
||||
boolean |
||||
util_bitmask_get(struct util_bitmask *bm,
|
||||
unsigned index) |
||||
{ |
||||
unsigned word = index / UTIL_BITMASK_BITS_PER_WORD; |
||||
unsigned bit = index % UTIL_BITMASK_BITS_PER_WORD; |
||||
util_bitmask_word mask = 1 << bit; |
||||
|
||||
assert(bm); |
||||
|
||||
if(index < bm->filled) { |
||||
assert(bm->words[word] & mask); |
||||
return TRUE; |
||||
} |
||||
|
||||
if(index >= bm->size) |
||||
return FALSE; |
||||
|
||||
if(bm->words[word] & mask) { |
||||
util_bitmask_filled_set(bm, index); |
||||
return TRUE; |
||||
} |
||||
else |
||||
return FALSE; |
||||
} |
||||
|
||||
|
||||
unsigned |
||||
util_bitmask_get_next_index(struct util_bitmask *bm,
|
||||
unsigned index) |
||||
{ |
||||
unsigned word = index / UTIL_BITMASK_BITS_PER_WORD; |
||||
unsigned bit = index % UTIL_BITMASK_BITS_PER_WORD; |
||||
util_bitmask_word mask = 1 << bit; |
||||
|
||||
if(index < bm->filled) { |
||||
assert(bm->words[word] & mask); |
||||
return index; |
||||
} |
||||
|
||||
if(index >= bm->size) { |
||||
return UTIL_BITMASK_INVALID_INDEX; |
||||
} |
||||
|
||||
/* Do a linear search */ |
||||
while(word < bm->size / UTIL_BITMASK_BITS_PER_WORD) { |
||||
while(bit < UTIL_BITMASK_BITS_PER_WORD) { |
||||
if(bm->words[word] & mask) { |
||||
if(index == bm->filled) { |
||||
++bm->filled; |
||||
assert(bm->filled <= bm->size); |
||||
} |
||||
return index; |
||||
} |
||||
++index; |
||||
++bit; |
||||
mask <<= 1; |
||||
} |
||||
++word; |
||||
bit = 0; |
||||
mask = 1; |
||||
} |
||||
|
||||
return UTIL_BITMASK_INVALID_INDEX; |
||||
} |
||||
|
||||
|
||||
unsigned |
||||
util_bitmask_get_first_index(struct util_bitmask *bm) |
||||
{ |
||||
return util_bitmask_get_next_index(bm, 0); |
||||
} |
||||
|
||||
|
||||
void |
||||
util_bitmask_destroy(struct util_bitmask *bm) |
||||
{ |
||||
assert(bm); |
||||
|
||||
FREE(bm->words); |
||||
FREE(bm); |
||||
} |
||||
|
@ -0,0 +1,110 @@ |
||||
/**************************************************************************
|
||||
* |
||||
* Copyright 2008 VMware, Inc. |
||||
* All Rights Reserved. |
||||
* Copyright 2008 VMware, Inc. All rights reserved. |
||||
* Copyright 2009 Marek Olšák <maraeo@gmail.com> |
||||
* |
||||
* Permission is hereby granted, free of charge, to any person obtaining a |
||||
* copy of this software and associated documentation files (the |
||||
* "Software"), to deal in the Software without restriction, including |
||||
* without limitation the rights to use, copy, modify, merge, publish, |
||||
* distribute, sub license, and/or sell copies of the Software, and to |
||||
* permit persons to whom the Software is furnished to do so, subject to |
||||
* the following conditions: |
||||
* |
||||
* The above copyright notice and this permission notice (including the |
||||
* next paragraph) shall be included in all copies or substantial portions |
||||
* of the Software. |
||||
* |
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||
* |
||||
**************************************************************************/ |
||||
|
||||
/**
|
||||
* @file |
||||
* Texture mapping utility functions. |
||||
* |
||||
* @author Brian Paul |
||||
* Marek Olšák |
||||
*/ |
||||
|
||||
#include "pipe/p_defines.h" |
||||
|
||||
#include "util/u_debug.h" |
||||
#include "util/u_texture.h" |
||||
|
||||
void util_map_texcoords2d_onto_cubemap(unsigned face, |
||||
const float *in_st, unsigned in_stride, |
||||
float *out_str, unsigned out_stride, |
||||
boolean allow_scale) |
||||
{ |
||||
int i; |
||||
float rx, ry, rz; |
||||
|
||||
/* loop over quad verts */ |
||||
for (i = 0; i < 4; i++) { |
||||
/* Compute sc = +/-scale and tc = +/-scale.
|
||||
* Not +/-1 to avoid cube face selection ambiguity near the edges, |
||||
* though that can still sometimes happen with this scale factor... |
||||
* |
||||
* XXX: Yep, there is no safe scale factor that will prevent sampling |
||||
* the neighbouring face when stretching out. A more reliable solution |
||||
* would be to clamp (sc, tc) against +/- 1.0-1.0/mipsize, in the shader. |
||||
* |
||||
* Also, this is not necessary when minifying, or 1:1 blits. |
||||
*/ |
||||
const float scale = allow_scale ? 0.9999f : 1.0f; |
||||
const float sc = (2 * in_st[0] - 1) * scale; |
||||
const float tc = (2 * in_st[1] - 1) * scale; |
||||
|
||||
switch (face) { |
||||
case PIPE_TEX_FACE_POS_X: |
||||
rx = 1; |
||||
ry = -tc; |
||||
rz = -sc; |
||||
break; |
||||
case PIPE_TEX_FACE_NEG_X: |
||||
rx = -1; |
||||
ry = -tc; |
||||
rz = sc; |
||||
break; |
||||
case PIPE_TEX_FACE_POS_Y: |
||||
rx = sc; |
||||
ry = 1; |
||||
rz = tc; |
||||
break; |
||||
case PIPE_TEX_FACE_NEG_Y: |
||||
rx = sc; |
||||
ry = -1; |
||||
rz = -tc; |
||||
break; |
||||
case PIPE_TEX_FACE_POS_Z: |
||||
rx = sc; |
||||
ry = -tc; |
||||
rz = 1; |
||||
break; |
||||
case PIPE_TEX_FACE_NEG_Z: |
||||
rx = -sc; |
||||
ry = -tc; |
||||
rz = -1; |
||||
break; |
||||
default: |
||||
rx = ry = rz = 0; |
||||
assert(0); |
||||
} |
||||
|
||||
out_str[0] = rx; /*s*/ |
||||
out_str[1] = ry; /*t*/ |
||||
out_str[2] = rz; /*r*/ |
||||
|
||||
in_st += in_stride; |
||||
out_str += out_stride; |
||||
} |
||||
} |
Loading…
Reference in new issue