diff options
27 files changed, 836 insertions, 671 deletions
diff --git a/mesalib/docs/devinfo.html b/mesalib/docs/devinfo.html index d9e82e29d..678e48c01 100644 --- a/mesalib/docs/devinfo.html +++ b/mesalib/docs/devinfo.html @@ -142,9 +142,9 @@ Places that are not directly visible to the GL API should prefer the use of <tt>bool</tt>, <tt>true</tt>, and <tt>false</tt> over <tt>GLboolean</tt>, <tt>GL_TRUE</tt>, and <tt>GL_FALSE</tt>. In C code, this may mean that -<tt>#include <stdbool.h></tt> need to be added. The +<tt>#include <stdbool.h></tt> needs to be added. The <tt>try_emit_</tt>* methods in src/mesa/program/ir_to_mesa.cpp and -src/mesa/state_tracker/st_glsl_to_tgsi.cpp can serve as an example. +src/mesa/state_tracker/st_glsl_to_tgsi.cpp can serve as examples. </p> diff --git a/mesalib/src/gallium/auxiliary/util/u_debug_describe.c b/mesalib/src/gallium/auxiliary/util/u_debug_describe.c index f84f942d6..3574accc0 100644 --- a/mesalib/src/gallium/auxiliary/util/u_debug_describe.c +++ b/mesalib/src/gallium/auxiliary/util/u_debug_describe.c @@ -1,81 +1,81 @@ -/**************************************************************************
- *
- * Copyright 2010 Luca Barbieri
- *
- * 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, sublicense, 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 NONINFRINGEMENT.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
- *
- **************************************************************************/
-
-#include <pipe/p_state.h>
-#include <util/u_format.h>
-#include <util/u_debug_describe.h>
-#include <util/u_string.h>
-
-void
-debug_describe_reference(char* buf, const struct pipe_reference*ptr)
-{
- strcpy(buf, "pipe_object");
-}
-
-void
-debug_describe_resource(char* buf, const struct pipe_resource *ptr)
-{
- switch(ptr->target)
- {
- case PIPE_BUFFER:
- util_sprintf(buf, "pipe_buffer<%u>", (unsigned)util_format_get_stride(ptr->format, ptr->width0));
- break;
- case PIPE_TEXTURE_1D:
- util_sprintf(buf, "pipe_texture1d<%u,%s,%u>", ptr->width0, util_format_short_name(ptr->format), ptr->last_level);
- break;
- case PIPE_TEXTURE_2D:
- util_sprintf(buf, "pipe_texture2d<%u,%u,%s,%u>", ptr->width0, ptr->height0, util_format_short_name(ptr->format), ptr->last_level);
- break;
- case PIPE_TEXTURE_RECT:
- util_sprintf(buf, "pipe_texture_rect<%u,%u,%s>", ptr->width0, ptr->height0, util_format_short_name(ptr->format));
- break;
- case PIPE_TEXTURE_CUBE:
- util_sprintf(buf, "pipe_texture_cube<%u,%u,%s,%u>", ptr->width0, ptr->height0, util_format_short_name(ptr->format), ptr->last_level);
- break;
- case PIPE_TEXTURE_3D:
- util_sprintf(buf, "pipe_texture3d<%u,%u,%u,%s,%u>", ptr->width0, ptr->height0, ptr->depth0, util_format_short_name(ptr->format), ptr->last_level);
- break;
- default:
- util_sprintf(buf, "pipe_martian_resource<%u>", ptr->target);
- break;
- }
-}
-
-void
-debug_describe_surface(char* buf, const struct pipe_surface *ptr)
-{
- char res[128];
- debug_describe_resource(res, ptr->texture);
- util_sprintf(buf, "pipe_surface<%s,%u,%u,%u>", res, ptr->u.tex.level, ptr->u.tex.first_layer, ptr->u.tex.last_layer);
-}
-
-void
-debug_describe_sampler_view(char* buf, const struct pipe_sampler_view *ptr)
-{
- char res[128];
- debug_describe_resource(res, ptr->texture);
- util_sprintf(buf, "pipe_sampler_view<%s,%s>", res, util_format_short_name(ptr->format));
-}
+/************************************************************************** + * + * Copyright 2010 Luca Barbieri + * + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. + * + **************************************************************************/ + +#include "pipe/p_state.h" +#include "util/u_format.h" +#include "util/u_debug_describe.h" +#include "util/u_string.h" + +void +debug_describe_reference(char* buf, const struct pipe_reference*ptr) +{ + strcpy(buf, "pipe_object"); +} + +void +debug_describe_resource(char* buf, const struct pipe_resource *ptr) +{ + switch(ptr->target) + { + case PIPE_BUFFER: + util_sprintf(buf, "pipe_buffer<%u>", (unsigned)util_format_get_stride(ptr->format, ptr->width0)); + break; + case PIPE_TEXTURE_1D: + util_sprintf(buf, "pipe_texture1d<%u,%s,%u>", ptr->width0, util_format_short_name(ptr->format), ptr->last_level); + break; + case PIPE_TEXTURE_2D: + util_sprintf(buf, "pipe_texture2d<%u,%u,%s,%u>", ptr->width0, ptr->height0, util_format_short_name(ptr->format), ptr->last_level); + break; + case PIPE_TEXTURE_RECT: + util_sprintf(buf, "pipe_texture_rect<%u,%u,%s>", ptr->width0, ptr->height0, util_format_short_name(ptr->format)); + break; + case PIPE_TEXTURE_CUBE: + util_sprintf(buf, "pipe_texture_cube<%u,%u,%s,%u>", ptr->width0, ptr->height0, util_format_short_name(ptr->format), ptr->last_level); + break; + case PIPE_TEXTURE_3D: + util_sprintf(buf, "pipe_texture3d<%u,%u,%u,%s,%u>", ptr->width0, ptr->height0, ptr->depth0, util_format_short_name(ptr->format), ptr->last_level); + break; + default: + util_sprintf(buf, "pipe_martian_resource<%u>", ptr->target); + break; + } +} + +void +debug_describe_surface(char* buf, const struct pipe_surface *ptr) +{ + char res[128]; + debug_describe_resource(res, ptr->texture); + util_sprintf(buf, "pipe_surface<%s,%u,%u,%u>", res, ptr->u.tex.level, ptr->u.tex.first_layer, ptr->u.tex.last_layer); +} + +void +debug_describe_sampler_view(char* buf, const struct pipe_sampler_view *ptr) +{ + char res[128]; + debug_describe_resource(res, ptr->texture); + util_sprintf(buf, "pipe_sampler_view<%s,%s>", res, util_format_short_name(ptr->format)); +} diff --git a/mesalib/src/gallium/auxiliary/util/u_debug_refcnt.c b/mesalib/src/gallium/auxiliary/util/u_debug_refcnt.c index 0a242e124..b3e389408 100644 --- a/mesalib/src/gallium/auxiliary/util/u_debug_refcnt.c +++ b/mesalib/src/gallium/auxiliary/util/u_debug_refcnt.c @@ -1,191 +1,191 @@ -/**************************************************************************
- *
- * Copyright 2010 Luca Barbieri
- *
- * 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, sublicense, 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 NONINFRINGEMENT.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
- *
- **************************************************************************/
-
-#if defined(DEBUG) && (!defined(PIPE_OS_WINDOWS) || defined(PIPE_SUBSYSTEM_WINDOWS_USER))
-
-/* see http://www.mozilla.org/performance/refcnt-balancer.html for what do with the output
- * on Linux, use tools/addr2line.sh to postprocess it before anything else
- **/
-#include <util/u_debug.h>
-#include <util/u_debug_refcnt.h>
-#include <util/u_debug_stack.h>
-#include <util/u_debug_symbol.h>
-#include <util/u_string.h>
-#include <util/u_hash_table.h>
-#include <os/os_thread.h>
-#include <os/os_stream.h>
-
-int debug_refcnt_state;
-
-struct os_stream* stream;
-
-/* TODO: maybe move this serial machinery to a stand-alone module and expose it? */
-pipe_static_mutex(serials_mutex);
-
-static struct util_hash_table* serials_hash;
-static unsigned serials_last;
-
-static unsigned hash_ptr(void* p)
-{
- return (unsigned)(uintptr_t)p;
-}
-
-static int compare_ptr(void* a, void* b)
-{
- if(a == b)
- return 0;
- else if(a < b)
- return -1;
- else
- return 1;
-}
-
-static boolean debug_serial(void* p, unsigned* pserial)
-{
- unsigned serial;
- boolean found = TRUE;
-#ifdef PIPE_SUBSYSTEM_WINDOWS_USER
- static boolean first = TRUE;
-
- if (first) {
- pipe_mutex_init(serials_mutex);
- first = FALSE;
- }
-#endif
-
- pipe_mutex_lock(serials_mutex);
- if(!serials_hash)
- serials_hash = util_hash_table_create(hash_ptr, compare_ptr);
- serial = (unsigned)(uintptr_t)util_hash_table_get(serials_hash, p);
- if(!serial)
- {
- /* time to stop logging... (you'll have a 100 GB logfile at least at this point)
- * TODO: avoid this
- */
- serial = ++serials_last;
- if(!serial)
- {
- debug_error("More than 2^32 objects detected, aborting.\n");
- os_abort();
- }
-
- util_hash_table_set(serials_hash, p, (void*)(uintptr_t)serial);
- found = FALSE;
- }
- pipe_mutex_unlock(serials_mutex);
- *pserial = serial;
- return found;
-}
-
-static void debug_serial_delete(void* p)
-{
- pipe_mutex_lock(serials_mutex);
- util_hash_table_remove(serials_hash, p);
- pipe_mutex_unlock(serials_mutex);
-}
-
-#define STACK_LEN 64
-
-static void dump_stack(const char* symbols[STACK_LEN])
-{
- unsigned i;
- for(i = 0; i < STACK_LEN; ++i)
- {
- if(symbols[i])
- os_stream_printf(stream, "%s\n", symbols[i]);
- }
- os_stream_write(stream, "\n", 1);
-}
-
-void debug_reference_slowpath(const struct pipe_reference* p, debug_reference_descriptor get_desc, int change)
-{
- if(debug_refcnt_state < 0)
- return;
-
- if(!debug_refcnt_state)
- {
- const char* filename = debug_get_option("GALLIUM_REFCNT_LOG", NULL);
- if(filename && filename[0])
- stream = os_file_stream_create(filename);
-
- if(stream)
- debug_refcnt_state = 1;
- else
- debug_refcnt_state = -1;
- }
-
- if(debug_refcnt_state > 0)
- {
- struct debug_stack_frame frames[STACK_LEN];
- const char* symbols[STACK_LEN];
- char buf[1024];
-
- unsigned i;
- unsigned refcnt = p->count;
- unsigned serial;
- boolean existing = debug_serial((void*)p, &serial);
-
- debug_backtrace_capture(frames, 1, STACK_LEN);
- for(i = 0; i < STACK_LEN; ++i)
- {
- if(frames[i].function)
- symbols[i] = debug_symbol_name_cached(frames[i].function);
- else
- symbols[i] = 0;
- }
-
- get_desc(buf, p);
-
- if(!existing)
- {
- os_stream_printf(stream, "<%s> %p %u Create\n", buf, p, serial);
- dump_stack(symbols);
-
- /* this is there to provide a gradual change even if we don't see the initialization */
- for(i = 1; i <= refcnt - change; ++i)
- {
- os_stream_printf(stream, "<%s> %p %u AddRef %u\n", buf, p, serial, i);
- dump_stack(symbols);
- }
- }
-
- if(change)
- {
- os_stream_printf(stream, "<%s> %p %u %s %u\n", buf, p, serial, change > 0 ? "AddRef" : "Release", refcnt);
- dump_stack(symbols);
- }
-
- if(!refcnt)
- {
- debug_serial_delete((void*)p);
- os_stream_printf(stream, "<%s> %p %u Destroy\n", buf, p, serial);
- dump_stack(symbols);
- }
-
- os_stream_flush(stream);
- }
-}
-#endif
+/************************************************************************** + * + * Copyright 2010 Luca Barbieri + * + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. + * + **************************************************************************/ + +#if defined(DEBUG) && (!defined(PIPE_OS_WINDOWS) || defined(PIPE_SUBSYSTEM_WINDOWS_USER)) + +/* see http://www.mozilla.org/performance/refcnt-balancer.html for what do with the output + * on Linux, use tools/addr2line.sh to postprocess it before anything else + **/ +#include "util/u_debug.h" +#include "util/u_debug_refcnt.h" +#include "util/u_debug_stack.h" +#include "util/u_debug_symbol.h" +#include "util/u_string.h" +#include "util/u_hash_table.h" +#include "os/os_thread.h" +#include "os/os_stream.h" + +int debug_refcnt_state; + +struct os_stream* stream; + +/* TODO: maybe move this serial machinery to a stand-alone module and expose it? */ +pipe_static_mutex(serials_mutex); + +static struct util_hash_table* serials_hash; +static unsigned serials_last; + +static unsigned hash_ptr(void* p) +{ + return (unsigned)(uintptr_t)p; +} + +static int compare_ptr(void* a, void* b) +{ + if(a == b) + return 0; + else if(a < b) + return -1; + else + return 1; +} + +static boolean debug_serial(void* p, unsigned* pserial) +{ + unsigned serial; + boolean found = TRUE; +#ifdef PIPE_SUBSYSTEM_WINDOWS_USER + static boolean first = TRUE; + + if (first) { + pipe_mutex_init(serials_mutex); + first = FALSE; + } +#endif + + pipe_mutex_lock(serials_mutex); + if(!serials_hash) + serials_hash = util_hash_table_create(hash_ptr, compare_ptr); + serial = (unsigned)(uintptr_t)util_hash_table_get(serials_hash, p); + if(!serial) + { + /* time to stop logging... (you'll have a 100 GB logfile at least at this point) + * TODO: avoid this + */ + serial = ++serials_last; + if(!serial) + { + debug_error("More than 2^32 objects detected, aborting.\n"); + os_abort(); + } + + util_hash_table_set(serials_hash, p, (void*)(uintptr_t)serial); + found = FALSE; + } + pipe_mutex_unlock(serials_mutex); + *pserial = serial; + return found; +} + +static void debug_serial_delete(void* p) +{ + pipe_mutex_lock(serials_mutex); + util_hash_table_remove(serials_hash, p); + pipe_mutex_unlock(serials_mutex); +} + +#define STACK_LEN 64 + +static void dump_stack(const char* symbols[STACK_LEN]) +{ + unsigned i; + for(i = 0; i < STACK_LEN; ++i) + { + if(symbols[i]) + os_stream_printf(stream, "%s\n", symbols[i]); + } + os_stream_write(stream, "\n", 1); +} + +void debug_reference_slowpath(const struct pipe_reference* p, debug_reference_descriptor get_desc, int change) +{ + if(debug_refcnt_state < 0) + return; + + if(!debug_refcnt_state) + { + const char* filename = debug_get_option("GALLIUM_REFCNT_LOG", NULL); + if(filename && filename[0]) + stream = os_file_stream_create(filename); + + if(stream) + debug_refcnt_state = 1; + else + debug_refcnt_state = -1; + } + + if(debug_refcnt_state > 0) + { + struct debug_stack_frame frames[STACK_LEN]; + const char* symbols[STACK_LEN]; + char buf[1024]; + + unsigned i; + unsigned refcnt = p->count; + unsigned serial; + boolean existing = debug_serial((void*)p, &serial); + + debug_backtrace_capture(frames, 1, STACK_LEN); + for(i = 0; i < STACK_LEN; ++i) + { + if(frames[i].function) + symbols[i] = debug_symbol_name_cached(frames[i].function); + else + symbols[i] = 0; + } + + get_desc(buf, p); + + if(!existing) + { + os_stream_printf(stream, "<%s> %p %u Create\n", buf, p, serial); + dump_stack(symbols); + + /* this is there to provide a gradual change even if we don't see the initialization */ + for(i = 1; i <= refcnt - change; ++i) + { + os_stream_printf(stream, "<%s> %p %u AddRef %u\n", buf, p, serial, i); + dump_stack(symbols); + } + } + + if(change) + { + os_stream_printf(stream, "<%s> %p %u %s %u\n", buf, p, serial, change > 0 ? "AddRef" : "Release", refcnt); + dump_stack(symbols); + } + + if(!refcnt) + { + debug_serial_delete((void*)p); + os_stream_printf(stream, "<%s> %p %u Destroy\n", buf, p, serial); + dump_stack(symbols); + } + + os_stream_flush(stream); + } +} +#endif diff --git a/mesalib/src/gallium/auxiliary/util/u_debug_refcnt.h b/mesalib/src/gallium/auxiliary/util/u_debug_refcnt.h index 61cc7122c..c02fba27d 100644 --- a/mesalib/src/gallium/auxiliary/util/u_debug_refcnt.h +++ b/mesalib/src/gallium/auxiliary/util/u_debug_refcnt.h @@ -1,63 +1,63 @@ -/**************************************************************************
- *
- * Copyright 2010 Luca Barbieri
- *
- * 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, sublicense, 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 NONINFRINGEMENT.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
- *
- **************************************************************************/
-
-#ifndef U_DEBUG_REFCNT_H_
-#define U_DEBUG_REFCNT_H_
-
-#include <pipe/p_config.h>
-#include <pipe/p_state.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef void (*debug_reference_descriptor)(char*, const struct pipe_reference*);
-
-#if defined(DEBUG) && (!defined(PIPE_OS_WINDOWS) || defined(PIPE_SUBSYSTEM_WINDOWS_USER))
-
-extern int debug_refcnt_state;
-
-void debug_reference_slowpath(const struct pipe_reference* p, debug_reference_descriptor get_desc, int change);
-
-static INLINE void debug_reference(const struct pipe_reference* p, debug_reference_descriptor get_desc, int change)
-{
- if (debug_refcnt_state >= 0)
- debug_reference_slowpath(p, get_desc, change);
-}
-
-#else
-
-static INLINE void debug_reference(const struct pipe_reference* p, debug_reference_descriptor get_desc, int change)
-{
-}
-
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* U_DEBUG_REFCNT_H_ */
+/************************************************************************** + * + * Copyright 2010 Luca Barbieri + * + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. + * + **************************************************************************/ + +#ifndef U_DEBUG_REFCNT_H_ +#define U_DEBUG_REFCNT_H_ + +#include "pipe/p_config.h" +#include "pipe/p_state.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*debug_reference_descriptor)(char*, const struct pipe_reference*); + +#if defined(DEBUG) && (!defined(PIPE_OS_WINDOWS) || defined(PIPE_SUBSYSTEM_WINDOWS_USER)) + +extern int debug_refcnt_state; + +void debug_reference_slowpath(const struct pipe_reference* p, debug_reference_descriptor get_desc, int change); + +static INLINE void debug_reference(const struct pipe_reference* p, debug_reference_descriptor get_desc, int change) +{ + if (debug_refcnt_state >= 0) + debug_reference_slowpath(p, get_desc, change); +} + +#else + +static INLINE void debug_reference(const struct pipe_reference* p, debug_reference_descriptor get_desc, int change) +{ +} + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* U_DEBUG_REFCNT_H_ */ diff --git a/mesalib/src/gallium/auxiliary/util/u_video.h b/mesalib/src/gallium/auxiliary/util/u_video.h index 6b67881e6..be3fac2d0 100644 --- a/mesalib/src/gallium/auxiliary/util/u_video.h +++ b/mesalib/src/gallium/auxiliary/util/u_video.h @@ -32,12 +32,12 @@ extern "C" { #endif -#include <pipe/p_defines.h> -#include <pipe/p_video_enums.h> +#include "pipe/p_defines.h" +#include "pipe/p_video_enums.h" /* u_reduce_video_profile() needs these */ -#include <pipe/p_compiler.h> -#include <util/u_debug.h> +#include "pipe/p_compiler.h" +#include "util/u_debug.h" static INLINE enum pipe_video_codec u_reduce_video_profile(enum pipe_video_profile profile) diff --git a/mesalib/src/mesa/SConscript b/mesalib/src/mesa/SConscript index b0c3334fa..64b706534 100644 --- a/mesalib/src/mesa/SConscript +++ b/mesalib/src/mesa/SConscript @@ -174,6 +174,7 @@ swrast_sources = [ 'swrast/s_texcombine.c', 'swrast/s_texfilter.c', 'swrast/s_texrender.c', + 'swrast/s_texture.c', 'swrast/s_triangle.c', 'swrast/s_zoom.c', ] diff --git a/mesalib/src/mesa/drivers/common/driverfuncs.c b/mesalib/src/mesa/drivers/common/driverfuncs.c index a6174ee2f..78caa0542 100644 --- a/mesalib/src/mesa/drivers/common/driverfuncs.c +++ b/mesalib/src/mesa/drivers/common/driverfuncs.c @@ -111,7 +111,9 @@ _mesa_init_driver_functions(struct dd_function_table *driver) driver->NewTextureObject = _mesa_new_texture_object; driver->DeleteTexture = _mesa_delete_texture_object; driver->NewTextureImage = _mesa_new_texture_image; - driver->FreeTexImageData = _mesa_free_texture_image_data; + driver->FreeTextureImageBuffer = _mesa_free_texture_image_data; + driver->MapTextureImage = _swrast_map_teximage; + driver->UnmapTextureImage = _swrast_unmap_teximage; driver->MapTexture = NULL; driver->UnmapTexture = NULL; driver->TextureMemCpy = memcpy; diff --git a/mesalib/src/mesa/drivers/dri/common/texmem.c b/mesalib/src/mesa/drivers/dri/common/texmem.c index e927cf0ad..798ef1ee8 100644 --- a/mesalib/src/mesa/drivers/dri/common/texmem.c +++ b/mesalib/src/mesa/drivers/dri/common/texmem.c @@ -1310,7 +1310,6 @@ gl_format _dri_texformat_argb4444 = MESA_FORMAT_NONE; gl_format _dri_texformat_argb1555 = MESA_FORMAT_NONE; gl_format _dri_texformat_al88 = MESA_FORMAT_NONE; gl_format _dri_texformat_a8 = MESA_FORMAT_A8; -gl_format _dri_texformat_ci8 = MESA_FORMAT_CI8; gl_format _dri_texformat_i8 = MESA_FORMAT_I8; gl_format _dri_texformat_l8 = MESA_FORMAT_L8; /*@}*/ diff --git a/mesalib/src/mesa/main/context.c b/mesalib/src/mesa/main/context.c index b83a5d621..0cf794735 100644 --- a/mesalib/src/mesa/main/context.c +++ b/mesalib/src/mesa/main/context.c @@ -907,7 +907,7 @@ _mesa_initialize_context(struct gl_context *ctx, /*ASSERT(driverContext);*/ assert(driverFunctions->NewTextureObject); - assert(driverFunctions->FreeTexImageData); + assert(driverFunctions->FreeTextureImageBuffer); ctx->API = api; ctx->Visual = *visual; diff --git a/mesalib/src/mesa/main/dd.h b/mesalib/src/mesa/main/dd.h index fcf40ecf1..d918b1e31 100644 --- a/mesalib/src/mesa/main/dd.h +++ b/mesalib/src/mesa/main/dd.h @@ -479,7 +479,26 @@ struct dd_function_table { /** * Called to free tImage->Data. */ - void (*FreeTexImageData)( struct gl_context *ctx, struct gl_texture_image *tImage ); + void (*FreeTextureImageBuffer)( struct gl_context *ctx, struct gl_texture_image *tImage ); + + /** Map a slice of a texture image into user space. + * \param texImage the texture image + * \param slice the 3D image slice or array texture slice + * \param x, y, w, h region of interest + * \param mode bitmask of GL_MAP_READ_BIT, GL_MAP_WRITE_BIT + * \param mapOut returns start of mapping of region of interest + * \param rowStrideOut returns row stride (in bytes) + */ + void (*MapTextureImage)(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLuint slice, + GLuint x, GLuint y, GLuint w, GLuint h, + GLbitfield mode, + GLubyte **mapOut, GLint *rowStrideOut); + + void (*UnmapTextureImage)(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLuint slice); /** Map texture image data into user space */ void (*MapTexture)( struct gl_context *ctx, struct gl_texture_object *tObj ); diff --git a/mesalib/src/mesa/main/debug.c b/mesalib/src/mesa/main/debug.c index b1fc096f2..2bb37452d 100644 --- a/mesalib/src/mesa/main/debug.c +++ b/mesalib/src/mesa/main/debug.c @@ -353,11 +353,10 @@ dump_texture(struct gl_texture_object *texObj, GLuint writeImages) for (j = 0; j < numFaces; j++) { struct gl_texture_image *texImg = texObj->Image[j][i]; if (texImg) { - printf(" Face %u level %u: %d x %d x %d, format %s at %p\n", + printf(" Face %u level %u: %d x %d x %d, format %s\n", j, i, texImg->Width, texImg->Height, texImg->Depth, - _mesa_get_format_name(texImg->TexFormat), - texImg->Data); + _mesa_get_format_name(texImg->TexFormat)); if (writeImages == WRITE_ALL || (writeImages == WRITE_ONE && !written)) { write_texture_image(texObj, j, i); @@ -566,58 +565,66 @@ _mesa_dump_image(const char *filename, const void *image, GLuint w, GLuint h, * Quick and dirty function to "print" a texture to stdout. */ void -_mesa_print_texture(struct gl_context *ctx, const struct gl_texture_image *img) +_mesa_print_texture(struct gl_context *ctx, struct gl_texture_image *img) { #if CHAN_TYPE != GL_UNSIGNED_BYTE _mesa_problem(NULL, "PrintTexture not supported"); #else + const GLint slice = 0; + GLint srcRowStride; GLuint i, j, c; - const GLubyte *data = (const GLubyte *) img->Data; + GLubyte *data; + + ctx->Driver.MapTextureImage(ctx, img, slice, + 0, 0, img->Width, img->Height, GL_MAP_READ_BIT, + &data, &srcRowStride); if (!data) { printf("No texture data\n"); - return; } + else { + /* XXX add more formats or make into a new format utility function */ + switch (img->TexFormat) { + case MESA_FORMAT_A8: + case MESA_FORMAT_L8: + case MESA_FORMAT_I8: + c = 1; + break; + case MESA_FORMAT_AL88: + case MESA_FORMAT_AL88_REV: + c = 2; + break; + case MESA_FORMAT_RGB888: + case MESA_FORMAT_BGR888: + c = 3; + break; + case MESA_FORMAT_RGBA8888: + case MESA_FORMAT_ARGB8888: + c = 4; + break; + default: + _mesa_problem(NULL, "error in PrintTexture\n"); + return; + } - /* XXX add more formats or make into a new format utility function */ - switch (img->TexFormat) { - case MESA_FORMAT_A8: - case MESA_FORMAT_L8: - case MESA_FORMAT_I8: - case MESA_FORMAT_CI8: - c = 1; - break; - case MESA_FORMAT_AL88: - case MESA_FORMAT_AL88_REV: - c = 2; - break; - case MESA_FORMAT_RGB888: - case MESA_FORMAT_BGR888: - c = 3; - break; - case MESA_FORMAT_RGBA8888: - case MESA_FORMAT_ARGB8888: - c = 4; - break; - default: - _mesa_problem(NULL, "error in PrintTexture\n"); - return; - } + for (i = 0; i < img->Height; i++) { + for (j = 0; j < img->Width; j++) { + if (c==1) + printf("%02x ", data[0]); + else if (c==2) + printf("%02x%02x ", data[0], data[1]); + else if (c==3) + printf("%02x%02x%02x ", data[0], data[1], data[2]); + else if (c==4) + printf("%02x%02x%02x%02x ", data[0], data[1], data[2], data[3]); + data += (srcRowStride - img->Width) * c; + } + /* XXX use img->ImageStride here */ + printf("\n"); - for (i = 0; i < img->Height; i++) { - for (j = 0; j < img->Width; j++) { - if (c==1) - printf("%02x ", data[0]); - else if (c==2) - printf("%02x%02x ", data[0], data[1]); - else if (c==3) - printf("%02x%02x%02x ", data[0], data[1], data[2]); - else if (c==4) - printf("%02x%02x%02x%02x ", data[0], data[1], data[2], data[3]); - data += (img->RowStride - img->Width) * c; } - /* XXX use img->ImageStride here */ - printf("\n"); } + + ctx->Driver.UnmapTextureImage(ctx, img, slice); #endif } diff --git a/mesalib/src/mesa/main/debug.h b/mesalib/src/mesa/main/debug.h index d7c53b655..bc64a83bb 100644 --- a/mesalib/src/mesa/main/debug.h +++ b/mesalib/src/mesa/main/debug.h @@ -89,6 +89,6 @@ _mesa_dump_image(const char *filename, const void *image, GLuint w, GLuint h, GLenum format, GLenum type); extern void -_mesa_print_texture(struct gl_context *ctx, const struct gl_texture_image *img); +_mesa_print_texture(struct gl_context *ctx, struct gl_texture_image *img); #endif diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c index 0b48fc7ea..fd371aba8 100644 --- a/mesalib/src/mesa/main/fbobject.c +++ b/mesalib/src/mesa/main/fbobject.c @@ -2321,7 +2321,7 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment, } else { gl_format format = att->Renderbuffer->Format; - if (format == MESA_FORMAT_CI8 || format == MESA_FORMAT_S8) { + if (format == MESA_FORMAT_S8) { /* special cases */ *params = GL_INDEX; } diff --git a/mesalib/src/mesa/main/formats.c b/mesalib/src/mesa/main/formats.c index f9298d2d1..65c08f024 100644 --- a/mesalib/src/mesa/main/formats.c +++ b/mesalib/src/mesa/main/formats.c @@ -42,8 +42,7 @@ struct gl_format_info /** * Base format is one of GL_RED, GL_RG, GL_RGB, GL_RGBA, GL_ALPHA, * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_INTENSITY, GL_YCBCR_MESA, - * GL_COLOR_INDEX, GL_DEPTH_COMPONENT, GL_STENCIL_INDEX, - * GL_DEPTH_STENCIL, GL_DUDV_ATI. + * GL_DEPTH_COMPONENT, GL_STENCIL_INDEX, GL_DEPTH_STENCIL, GL_DUDV_ATI. */ GLenum BaseFormat; @@ -331,15 +330,6 @@ static struct gl_format_info format_info[MESA_FORMAT_COUNT] = 1, 1, 2 /* BlockWidth/Height,Bytes */ }, { - MESA_FORMAT_CI8, /* Name */ - "MESA_FORMAT_CI8", /* StrName */ - GL_COLOR_INDEX, /* BaseFormat */ - GL_UNSIGNED_INT, /* DataType */ - 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 8, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 1 /* BlockWidth/Height,Bytes */ - }, - { MESA_FORMAT_YCBCR, /* Name */ "MESA_FORMAT_YCBCR", /* StrName */ GL_YCBCR_MESA, /* BaseFormat */ @@ -1223,10 +1213,9 @@ _mesa_get_format_datatype(gl_format format) /** - * Return the basic format for the given type. The result will be - * one of GL_RGB, GL_RGBA, GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA, - * GL_INTENSITY, GL_YCBCR_MESA, GL_COLOR_INDEX, GL_DEPTH_COMPONENT, - * GL_STENCIL_INDEX, GL_DEPTH_STENCIL. + * Return the basic format for the given type. The result will be one of + * GL_RGB, GL_RGBA, GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_INTENSITY, + * GL_YCBCR_MESA, GL_DEPTH_COMPONENT, GL_STENCIL_INDEX, GL_DEPTH_STENCIL. */ GLenum _mesa_get_format_base_format(gl_format format) @@ -1632,7 +1621,6 @@ _mesa_format_to_type_and_comps(gl_format format, case MESA_FORMAT_A8: case MESA_FORMAT_L8: case MESA_FORMAT_I8: - case MESA_FORMAT_CI8: case MESA_FORMAT_R8: case MESA_FORMAT_S8: *datatype = GL_UNSIGNED_BYTE; diff --git a/mesalib/src/mesa/main/formats.h b/mesalib/src/mesa/main/formats.h index 5b8c01781..75d93deba 100644 --- a/mesalib/src/mesa/main/formats.h +++ b/mesalib/src/mesa/main/formats.h @@ -80,7 +80,6 @@ typedef enum MESA_FORMAT_L16, /* LLLL LLLL LLLL LLLL */ MESA_FORMAT_I8, /* IIII IIII */ MESA_FORMAT_I16, /* IIII IIII IIII IIII */ - MESA_FORMAT_CI8, /* CCCC CCCC */ MESA_FORMAT_YCBCR, /* YYYY YYYY UorV UorV */ MESA_FORMAT_YCBCR_REV, /* UorV UorV YYYY YYYY */ MESA_FORMAT_R8, /* RRRR RRRR */ diff --git a/mesalib/src/mesa/main/mipmap.c b/mesalib/src/mesa/main/mipmap.c index 8a811cb72..cf9d522f2 100644 --- a/mesalib/src/mesa/main/mipmap.c +++ b/mesalib/src/mesa/main/mipmap.c @@ -1948,8 +1948,7 @@ generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target, } /* Free old image data */ - if (dstImage->Data) - ctx->Driver.FreeTexImageData(ctx, dstImage); + ctx->Driver.FreeTextureImageBuffer(ctx, dstImage); /* initialize new image */ _mesa_init_teximage_fields(ctx, target, dstImage, dstWidth, dstHeight, diff --git a/mesalib/src/mesa/main/texfetch.c b/mesalib/src/mesa/main/texfetch.c index 72283eb68..11cc8e047 100644 --- a/mesalib/src/mesa/main/texfetch.c +++ b/mesalib/src/mesa/main/texfetch.c @@ -325,13 +325,6 @@ texfetch_funcs[MESA_FORMAT_COUNT] = store_texel_i16 }, { - MESA_FORMAT_CI8, - fetch_texel_1d_f_ci8, - fetch_texel_2d_f_ci8, - fetch_texel_3d_f_ci8, - store_texel_ci8 - }, - { MESA_FORMAT_YCBCR, fetch_texel_1d_f_ycbcr, fetch_texel_2d_f_ycbcr, diff --git a/mesalib/src/mesa/main/texfetch_tmp.h b/mesalib/src/mesa/main/texfetch_tmp.h index d170adf2e..548d50c8e 100644 --- a/mesalib/src/mesa/main/texfetch_tmp.h +++ b/mesalib/src/mesa/main/texfetch_tmp.h @@ -1379,88 +1379,6 @@ static void store_texel_i16(struct gl_texture_image *texImage, #endif -/* MESA_FORMAT_CI8 ***********************************************************/ - -/* Fetch CI texel from 1D, 2D or 3D ci8 texture, lookup the index in a - * color table, and return 4 GLchans. - */ -static void FETCH(f_ci8)( const struct gl_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel ) -{ - const GLubyte *src = TEXEL_ADDR(GLubyte, texImage, i, j, k, 1); - const struct gl_color_table *palette; - GLuint index; - GET_CURRENT_CONTEXT(ctx); - - if (ctx->Texture.SharedPalette) { - palette = &ctx->Texture.Palette; - } - else { - palette = &texImage->TexObject->Palette; - } - if (palette->Size == 0) - return; /* undefined results */ - - /* Mask the index against size of palette to avoid going out of bounds */ - index = (*src) & (palette->Size - 1); - - { - const GLfloat *table = palette->TableF; - switch (palette->_BaseFormat) { - case GL_ALPHA: - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = 0.0F; - texel[ACOMP] = table[index]; - break; - case GL_LUMINANCE: - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = table[index]; - texel[ACOMP] = 1.0F; - break; - case GL_INTENSITY: - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = - texel[ACOMP] = table[index]; - break; - case GL_LUMINANCE_ALPHA: - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = table[index * 2 + 0]; - texel[ACOMP] = table[index * 2 + 1]; - break; - case GL_RGB: - texel[RCOMP] = table[index * 3 + 0]; - texel[GCOMP] = table[index * 3 + 1]; - texel[BCOMP] = table[index * 3 + 2]; - texel[ACOMP] = 1.0F; - break; - case GL_RGBA: - texel[RCOMP] = table[index * 4 + 0]; - texel[GCOMP] = table[index * 4 + 1]; - texel[BCOMP] = table[index * 4 + 2]; - texel[ACOMP] = table[index * 4 + 3]; - break; - default: - _mesa_problem(ctx, "Bad palette format in fetch_texel_ci8"); - return; - } - } -} - -#if DIM == 3 -static void store_texel_ci8(struct gl_texture_image *texImage, - GLint i, GLint j, GLint k, const void *texel) -{ - const GLubyte *index = (const GLubyte *) texel; - GLubyte *dst = TEXEL_ADDR(GLubyte, texImage, i, j, k, 1); - *dst = *index; -} -#endif - - /* Fetch texel from 1D, 2D or 3D srgb8 texture, return 4 GLfloats */ /* Note: component order is same as for MESA_FORMAT_RGB888 */ static void FETCH(srgb8)(const struct gl_texture_image *texImage, diff --git a/mesalib/src/mesa/main/texformat.c b/mesalib/src/mesa/main/texformat.c index c919a74e0..075c40c86 100644 --- a/mesalib/src/mesa/main/texformat.c +++ b/mesalib/src/mesa/main/texformat.c @@ -204,9 +204,6 @@ _mesa_choose_tex_format( struct gl_context *ctx, GLint internalFormat, case GL_COLOR_INDEX12_EXT: case GL_COLOR_INDEX16_EXT: case GL_COLOR_INDEX8_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_CI8); - break; - default: ; /* fallthrough */ } diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c index a005d2935..886e52114 100644 --- a/mesalib/src/mesa/main/teximage.c +++ b/mesalib/src/mesa/main/teximage.c @@ -595,7 +595,7 @@ _mesa_new_texture_image( struct gl_context *ctx ) /** * Free texture image data. - * This function is a fallback called via ctx->Driver.FreeTexImageData(). + * This function is a fallback called via ctx->Driver.FreeTextureImageBuffer(). * * \param texImage texture image. * @@ -630,8 +630,8 @@ _mesa_delete_texture_image(struct gl_context *ctx, /* Free texImage->Data and/or any other driver-specific texture * image storage. */ - ASSERT(ctx->Driver.FreeTexImageData); - ctx->Driver.FreeTexImageData( ctx, texImage ); + ASSERT(ctx->Driver.FreeTextureImageBuffer); + ctx->Driver.FreeTextureImageBuffer( ctx, texImage ); ASSERT(texImage->Data == NULL); if (texImage->ImageOffsets) @@ -1211,7 +1211,7 @@ void _mesa_clear_texture_image(struct gl_context *ctx, struct gl_texture_image *texImage) { - ctx->Driver.FreeTexImageData(ctx, texImage); + ctx->Driver.FreeTextureImageBuffer(ctx, texImage); clear_teximage_fields(texImage); } @@ -2456,9 +2456,7 @@ teximage(struct gl_context *ctx, GLuint dims, else { gl_format texFormat; - if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); - } + ctx->Driver.FreeTextureImageBuffer(ctx, texImage); ASSERT(texImage->Data == NULL); texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, @@ -2597,8 +2595,7 @@ _mesa_EGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image) if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glEGLImageTargetTexture2D"); } else { - if (texImage->Data) - ctx->Driver.FreeTexImageData( ctx, texImage ); + ctx->Driver.FreeTextureImageBuffer(ctx, texImage); ASSERT(texImage->Data == NULL); ctx->Driver.EGLImageTargetTexture2D(ctx, target, @@ -2804,7 +2801,7 @@ copyteximage(struct gl_context *ctx, GLuint dims, GLint srcX = x, srcY = y, dstX = 0, dstY = 0; /* Free old texture image */ - ctx->Driver.FreeTexImageData(ctx, texImage); + ctx->Driver.FreeTextureImageBuffer(ctx, texImage); _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, border, internalFormat, texFormat); @@ -3362,9 +3359,7 @@ compressedteximage(struct gl_context *ctx, GLuint dims, else { gl_format texFormat; - if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); - } + ctx->Driver.FreeTextureImageBuffer(ctx, texImage); ASSERT(texImage->Data == NULL); texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, diff --git a/mesalib/src/mesa/main/texstore.c b/mesalib/src/mesa/main/texstore.c index c4aeaa8f1..e9915a7f0 100644 --- a/mesalib/src/mesa/main/texstore.c +++ b/mesalib/src/mesa/main/texstore.c @@ -2724,50 +2724,6 @@ _mesa_texstore_unorm8(TEXSTORE_PARAMS) -static GLboolean -_mesa_texstore_ci8(TEXSTORE_PARAMS) -{ - const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); - - (void) dims; (void) baseInternalFormat; - ASSERT(dstFormat == MESA_FORMAT_CI8); - ASSERT(texelBytes == 1); - ASSERT(baseInternalFormat == GL_COLOR_INDEX); - - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - srcFormat == GL_COLOR_INDEX && - srcType == GL_UNSIGNED_BYTE) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, - dstRowStride, - dstImageOffsets, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { - /* general path */ - GLint img, row; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = (GLubyte *) dstAddr - + dstImageOffsets[dstZoffset + img] * texelBytes - + dstYoffset * dstRowStride - + dstXoffset * texelBytes; - for (row = 0; row < srcHeight; row++) { - const GLvoid *src = _mesa_image_address(dims, srcPacking, - srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0); - _mesa_unpack_index_span(ctx, srcWidth, GL_UNSIGNED_BYTE, dstRow, - srcType, src, srcPacking, - ctx->_ImageTransferState); - dstRow += dstRowStride; - } - } - } - return GL_TRUE; -} - - /** * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV. */ @@ -4392,7 +4348,6 @@ texstore_funcs[MESA_FORMAT_COUNT] = { MESA_FORMAT_L16, _mesa_texstore_unorm16 }, { MESA_FORMAT_I8, _mesa_texstore_unorm8 }, { MESA_FORMAT_I16, _mesa_texstore_unorm16 }, - { MESA_FORMAT_CI8, _mesa_texstore_ci8 }, { MESA_FORMAT_YCBCR, _mesa_texstore_ycbcr }, { MESA_FORMAT_YCBCR_REV, _mesa_texstore_ycbcr }, { MESA_FORMAT_R8, _mesa_texstore_unorm8 }, @@ -4565,17 +4520,24 @@ texture_size(const struct gl_texture_image *texImage) } -/** Return row stride in bytes */ -static GLuint -texture_row_stride(const struct gl_texture_image *texImage) +/** + * Normally, we'll only _write_ texel data to a texture when we map it. + * But if the user is providing depth or stencil values and the texture + * image is a combined depth/stencil format, we'll actually read from + * the texture buffer too (in order to insert the depth or stencil values. + * \param userFormat the user-provided image format + * \param texFormat the destination texture format + */ +static GLbitfield +get_read_write_mode(GLenum userFormat, gl_format texFormat) { - GLuint stride = _mesa_format_row_stride(texImage->TexFormat, - texImage->Width); - return stride; + if ((userFormat == GL_STENCIL_INDEX || userFormat == GL_DEPTH_COMPONENT) + && _mesa_get_format_base_format(texFormat) == GL_DEPTH_STENCIL) + return GL_MAP_READ_BIT | GL_MAP_WRITE_BIT; + else + return GL_MAP_WRITE_BIT; } - - /** * This is the software fallback for Driver.TexImage1D(). * \sa _mesa_store_teximage2d() @@ -4590,6 +4552,12 @@ _mesa_store_teximage1d(struct gl_context *ctx, GLenum target, GLint level, struct gl_texture_image *texImage) { GLuint sizeInBytes; + const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat); + const GLuint zeroImageOffset = 0; + GLubyte *dstMap; + GLint dstRowStride; + GLboolean success; + (void) border; /* allocate memory */ @@ -4608,20 +4576,26 @@ _mesa_store_teximage1d(struct gl_context *ctx, GLenum target, GLint level, */ return; } - else { - const GLint dstRowStride = 0; - GLboolean success = _mesa_texstore(ctx, 1, texImage->_BaseFormat, - texImage->TexFormat, - texImage->Data, - 0, 0, 0, /* dstX/Y/Zoffset */ - dstRowStride, - texImage->ImageOffsets, - width, 1, 1, - format, type, pixels, packing); - if (!success) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); - } - } + + /* Map dest texture buffer (write to whole region) */ + ctx->Driver.MapTextureImage(ctx, texImage, 0, + 0, 0, width, 1, + rwMode, + &dstMap, &dstRowStride); + + success = _mesa_texstore(ctx, 1, texImage->_BaseFormat, + texImage->TexFormat, + dstMap, + 0, 0, 0, /* dstX/Y/Zoffset */ + 0, /* dstRowStride */ + &zeroImageOffset, + width, 1, 1, + format, type, pixels, packing); + + ctx->Driver.UnmapTextureImage(ctx, texImage, 0); + + if (!success) + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); _mesa_unmap_teximage_pbo(ctx, packing); } @@ -4643,6 +4617,12 @@ _mesa_store_teximage2d(struct gl_context *ctx, GLenum target, GLint level, struct gl_texture_image *texImage) { GLuint sizeInBytes; + const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat); + const GLuint zeroImageOffset = 0; + GLubyte *dstMap; + GLint dstRowStride; + GLboolean success; + (void) border; /* allocate memory */ @@ -4661,20 +4641,26 @@ _mesa_store_teximage2d(struct gl_context *ctx, GLenum target, GLint level, */ return; } - else { - GLint dstRowStride = texture_row_stride(texImage); - GLboolean success = _mesa_texstore(ctx, 2, texImage->_BaseFormat, - texImage->TexFormat, - texImage->Data, - 0, 0, 0, /* dstX/Y/Zoffset */ - dstRowStride, - texImage->ImageOffsets, - width, height, 1, - format, type, pixels, packing); - if (!success) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); - } - } + + /* Map dest texture buffer (write to whole region) */ + ctx->Driver.MapTextureImage(ctx, texImage, 0, + 0, 0, width, height, + rwMode, + &dstMap, &dstRowStride); + assert(dstMap); + success = _mesa_texstore(ctx, 2, texImage->_BaseFormat, + texImage->TexFormat, + dstMap, + 0, 0, 0, /* dstX/Y/Zoffset */ + dstRowStride, + &zeroImageOffset, + width, height, 1, + format, type, pixels, packing); + + ctx->Driver.UnmapTextureImage(ctx, texImage, 0); + + if (!success) + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); _mesa_unmap_teximage_pbo(ctx, packing); } @@ -4695,40 +4681,72 @@ _mesa_store_teximage3d(struct gl_context *ctx, GLenum target, GLint level, struct gl_texture_image *texImage) { GLuint sizeInBytes; + const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat); + GLboolean success; + GLint slice; + GLubyte **sliceMaps; + GLuint *dstImageOffsets; + GLint dstRowStride; + GLuint texelSize = _mesa_get_format_bytes(texImage->TexFormat); + (void) border; /* allocate memory */ sizeInBytes = texture_size(texImage); texImage->Data = _mesa_alloc_texmemory(sizeInBytes); if (!texImage->Data) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); + /* Note: we check for a NULL image pointer here, _after_ we allocated + * memory for the texture. That's what the GL spec calls for. + */ return; } - pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format, - type, pixels, packing, "glTexImage3D"); + pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, + format, type, + pixels, packing, "glTexImage3D"); if (!pixels) { /* Note: we check for a NULL image pointer here, _after_ we allocated * memory for the texture. That's what the GL spec calls for. */ return; } - else { - GLint dstRowStride = texture_row_stride(texImage); - GLboolean success = _mesa_texstore(ctx, 3, texImage->_BaseFormat, - texImage->TexFormat, - texImage->Data, - 0, 0, 0, /* dstX/Y/Zoffset */ - dstRowStride, - texImage->ImageOffsets, - width, height, depth, - format, type, pixels, packing); - if (!success) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); - } + + sliceMaps = (GLubyte **) malloc(depth * sizeof(GLubyte *)); + dstImageOffsets = (GLuint *) malloc(depth * sizeof(GLuint)); + + /* Map dest texture buffer slices */ + for (slice = 0; slice < depth; slice++) { + ctx->Driver.MapTextureImage(ctx, texImage, slice, + 0, 0, width, height, + rwMode, + &sliceMaps[slice], &dstRowStride); + } + /* Compute image slice offsets */ + for (slice = 0; slice < depth; slice++) { + dstImageOffsets[slice] = (sliceMaps[slice] - sliceMaps[0]) / texelSize; + } + + success = _mesa_texstore(ctx, 3, texImage->_BaseFormat, + texImage->TexFormat, + sliceMaps[0], + 0, 0, 0, /* dstX/Y/Zoffset */ + dstRowStride, + dstImageOffsets, + width, height, depth, + format, type, pixels, packing); + + /* Unmap dest texture buffer slices */ + for (slice = 0; slice < depth; slice++) { + ctx->Driver.UnmapTextureImage(ctx, texImage, slice); } + if (!success) + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); + _mesa_unmap_teximage_pbo(ctx, packing); + + free(sliceMaps); + free(dstImageOffsets); } @@ -4746,26 +4764,37 @@ _mesa_store_texsubimage1d(struct gl_context *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { + const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat); + const GLuint zeroImageOffset = 0; + GLubyte *dstMap; + GLint dstRowStride; + GLboolean success; + /* get pointer to src pixels (may be in a pbo which we'll map here) */ pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type, pixels, packing, "glTexSubImage1D"); if (!pixels) return; - { - const GLint dstRowStride = 0; - GLboolean success = _mesa_texstore(ctx, 1, texImage->_BaseFormat, - texImage->TexFormat, - texImage->Data, - xoffset, 0, 0, /* offsets */ - dstRowStride, - texImage->ImageOffsets, - width, 1, 1, - format, type, pixels, packing); - if (!success) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D"); - } - } + /* Map dest texture buffer (write to whole region) */ + ctx->Driver.MapTextureImage(ctx, texImage, 0, + xoffset, 0, width, 1, + rwMode, + &dstMap, &dstRowStride); + + success = _mesa_texstore(ctx, 1, texImage->_BaseFormat, + texImage->TexFormat, + dstMap, + 0, 0, 0, /* dstX/Y/Zoffset */ + dstRowStride, + &zeroImageOffset, + width, 1, 1, + format, type, pixels, packing); + + ctx->Driver.UnmapTextureImage(ctx, texImage, 0); + + if (!success) + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D"); _mesa_unmap_teximage_pbo(ctx, packing); } @@ -4785,26 +4814,37 @@ _mesa_store_texsubimage2d(struct gl_context *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { + const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat); + const GLuint zeroImageOffset = 0; + GLubyte *dstMap; + GLint dstRowStride; + GLboolean success; + /* get pointer to src pixels (may be in a pbo which we'll map here) */ pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type, pixels, packing, "glTexSubImage2D"); if (!pixels) return; - { - GLint dstRowStride = texture_row_stride(texImage); - GLboolean success = _mesa_texstore(ctx, 2, texImage->_BaseFormat, - texImage->TexFormat, - texImage->Data, - xoffset, yoffset, 0, - dstRowStride, - texImage->ImageOffsets, - width, height, 1, - format, type, pixels, packing); - if (!success) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D"); - } - } + /* Map dest texture buffer (write to whole region) */ + ctx->Driver.MapTextureImage(ctx, texImage, 0, + xoffset, yoffset, width, height, + rwMode, + &dstMap, &dstRowStride); + + success = _mesa_texstore(ctx, 2, texImage->_BaseFormat, + texImage->TexFormat, + dstMap, + 0, 0, 0, /* dstX/Y/Zoffset */ + dstRowStride, + &zeroImageOffset, + width, height, 1, + format, type, pixels, packing); + + ctx->Driver.UnmapTextureImage(ctx, texImage, 0); + + if (!success) + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D"); _mesa_unmap_teximage_pbo(ctx, packing); } @@ -4823,6 +4863,14 @@ _mesa_store_texsubimage3d(struct gl_context *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { + const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat); + GLboolean success; + GLint slice; + GLubyte **sliceMaps; + GLuint *dstImageOffsets; + GLint dstRowStride; + GLuint texelSize = _mesa_get_format_bytes(texImage->TexFormat); + /* get pointer to src pixels (may be in a pbo which we'll map here) */ pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format, type, pixels, packing, @@ -4830,22 +4878,44 @@ _mesa_store_texsubimage3d(struct gl_context *ctx, GLenum target, GLint level, if (!pixels) return; - { - GLint dstRowStride = texture_row_stride(texImage); - GLboolean success = _mesa_texstore(ctx, 3, texImage->_BaseFormat, - texImage->TexFormat, - texImage->Data, - xoffset, yoffset, zoffset, - dstRowStride, - texImage->ImageOffsets, - width, height, depth, - format, type, pixels, packing); - if (!success) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D"); - } + sliceMaps = (GLubyte **) malloc((zoffset + depth) * sizeof(GLubyte *)); + dstImageOffsets = (GLuint *) malloc((zoffset + depth) * sizeof(GLuint)); + + /* Map dest texture buffer slices */ + for (slice = 0; slice < depth; slice++) { + ctx->Driver.MapTextureImage(ctx, texImage, zoffset + slice, + xoffset, yoffset, width, height, + rwMode, + &sliceMaps[zoffset + slice], &dstRowStride); + } + + /* Compute image slice offsets */ + for (slice = 0; slice < depth; slice++) { + dstImageOffsets[slice] = + (sliceMaps[zoffset + slice] - sliceMaps[zoffset]) / texelSize; } + success = _mesa_texstore(ctx, 3, texImage->_BaseFormat, + texImage->TexFormat, + sliceMaps[zoffset], + 0, 0, 0, /* dstX/Y/Zoffset */ + dstRowStride, + dstImageOffsets, + width, height, depth, + format, type, pixels, packing); + + /* Unmap dest texture buffer slices */ + for (slice = 0; slice < depth; slice++) { + ctx->Driver.UnmapTextureImage(ctx, texImage, zoffset + slice); + } + + if (!success) + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D"); + _mesa_unmap_teximage_pbo(ctx, packing); + + free(sliceMaps); + free(dstImageOffsets); } @@ -4885,7 +4955,8 @@ _mesa_store_compressed_teximage2d(struct gl_context *ctx, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - (void) width; (void) height; (void) border; + GLubyte *dstMap; + GLint dstRowStride; /* This is pretty simple, basically just do a memcpy without worrying * about the usual image unpacking or image transfer operations. @@ -4910,8 +4981,17 @@ _mesa_store_compressed_teximage2d(struct gl_context *ctx, if (!data) return; + + /* Map dest texture buffer (write to whole region) */ + ctx->Driver.MapTextureImage(ctx, texImage, 0, + 0, 0, width, height, + GL_MAP_WRITE_BIT, + &dstMap, &dstRowStride); + /* copy the data */ - memcpy(texImage->Data, data, imageSize); + memcpy(dstMap, data, imageSize); + + ctx->Driver.UnmapTextureImage(ctx, texImage, 0); _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack); } @@ -4980,19 +5060,15 @@ _mesa_store_compressed_texsubimage2d(struct gl_context *ctx, GLenum target, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - GLint bytesPerRow, destRowStride, srcRowStride; + GLint bytesPerRow, dstRowStride, srcRowStride; GLint i, rows; - GLubyte *dest; + GLubyte *dstMap; const GLubyte *src; const gl_format texFormat = texImage->TexFormat; - const GLint destWidth = texImage->Width; GLuint bw, bh; _mesa_get_format_block_size(texFormat, &bw, &bh); - (void) level; - (void) format; - /* these should have been caught sooner */ ASSERT((width % bw) == 0 || width == 2 || width == 1); ASSERT((height % bh) == 0 || height == 2 || height == 1); @@ -5009,21 +5085,24 @@ _mesa_store_compressed_texsubimage2d(struct gl_context *ctx, GLenum target, srcRowStride = _mesa_format_row_stride(texFormat, width); src = (const GLubyte *) data; - destRowStride = _mesa_format_row_stride(texFormat, destWidth); - dest = _mesa_compressed_image_address(xoffset, yoffset, 0, - texFormat, destWidth, - (GLubyte *) texImage->Data); + /* Map dest texture buffer (write to whole region) */ + ctx->Driver.MapTextureImage(ctx, texImage, 0, + xoffset, yoffset, width, height, + GL_MAP_WRITE_BIT, + &dstMap, &dstRowStride); bytesPerRow = srcRowStride; /* bytes per row of blocks */ rows = height / bh; /* rows in blocks */ /* copy rows of blocks */ for (i = 0; i < rows; i++) { - memcpy(dest, src, bytesPerRow); - dest += destRowStride; + memcpy(dstMap, src, bytesPerRow); + dstMap += dstRowStride; src += srcRowStride; } + ctx->Driver.UnmapTextureImage(ctx, texImage, 0); + _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack); } diff --git a/mesalib/src/mesa/sources.mak b/mesalib/src/mesa/sources.mak index 5e77e0f59..deff7bd78 100644 --- a/mesalib/src/mesa/sources.mak +++ b/mesalib/src/mesa/sources.mak @@ -145,6 +145,7 @@ SWRAST_SOURCES = \ swrast/s_texcombine.c \ swrast/s_texfilter.c \ swrast/s_texrender.c \ + swrast/s_texture.c \ swrast/s_triangle.c \ swrast/s_zoom.c diff --git a/mesalib/src/mesa/state_tracker/st_cb_texture.c b/mesalib/src/mesa/state_tracker/st_cb_texture.c index a3b2ba9e7..e4be7fba4 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_texture.c +++ b/mesalib/src/mesa/state_tracker/st_cb_texture.c @@ -142,9 +142,9 @@ st_DeleteTextureObject(struct gl_context *ctx, } -/** called via ctx->Driver.FreeTexImageData() */ +/** called via ctx->Driver.FreeTextureImageBuffer() */ static void -st_FreeTextureImageData(struct gl_context * ctx, struct gl_texture_image *texImage) +st_FreeTextureImageBuffer(struct gl_context * ctx, struct gl_texture_image *texImage) { struct st_texture_image *stImage = st_texture_image(texImage); @@ -161,6 +161,49 @@ st_FreeTextureImageData(struct gl_context * ctx, struct gl_texture_image *texIma } +/** called via ctx->Driver.MapTextureImage() */ +static void +st_MapTextureImage(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLuint slice, GLuint x, GLuint y, GLuint w, GLuint h, + GLbitfield mode, + GLubyte **mapOut, GLint *rowStrideOut) +{ + struct st_context *st = st_context(ctx); + struct st_texture_image *stImage = st_texture_image(texImage); + unsigned pipeMode; + GLubyte *map; + + pipeMode = 0x0; + if (mode & GL_MAP_READ_BIT) + pipeMode |= PIPE_TRANSFER_READ; + if (mode & GL_MAP_WRITE_BIT) + pipeMode |= PIPE_TRANSFER_WRITE; + + map = st_texture_image_map(st, stImage, slice, pipeMode, x, y, w, h); + if (map) { + *mapOut = map; + *rowStrideOut = stImage->transfer->stride; + } + else { + *mapOut = NULL; + *rowStrideOut = 0; + } +} + + +/** called via ctx->Driver.UnmapTextureImage() */ +static void +st_UnmapTextureImage(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLuint slice) +{ + struct st_context *st = st_context(ctx); + struct st_texture_image *stImage = st_texture_image(texImage); + st_texture_image_unmap(st, stImage); +} + + /** * From linux kernel i386 header files, copes with odd sizes better * than COPY_DWORDS would: @@ -1880,7 +1923,9 @@ st_init_texture_functions(struct dd_function_table *functions) functions->NewTextureObject = st_NewTextureObject; functions->NewTextureImage = st_NewTextureImage; functions->DeleteTexture = st_DeleteTextureObject; - functions->FreeTexImageData = st_FreeTextureImageData; + functions->FreeTextureImageBuffer = st_FreeTextureImageBuffer; + functions->MapTextureImage = st_MapTextureImage; + functions->UnmapTextureImage = st_UnmapTextureImage; functions->TextureMemCpy = do_memcpy; diff --git a/mesalib/src/mesa/state_tracker/st_gen_mipmap.c b/mesalib/src/mesa/state_tracker/st_gen_mipmap.c index 82ca4af7f..e53da5fd4 100644 --- a/mesalib/src/mesa/state_tracker/st_gen_mipmap.c +++ b/mesalib/src/mesa/state_tracker/st_gen_mipmap.c @@ -444,8 +444,7 @@ st_generate_mipmap(struct gl_context *ctx, GLenum target, } /* Free old image data */ - if (dstImage->Data) - ctx->Driver.FreeTexImageData(ctx, dstImage); + ctx->Driver.FreeTextureImageBuffer(ctx, dstImage); /* initialize new image */ _mesa_init_teximage_fields(ctx, target, dstImage, dstWidth, dstHeight, diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index 22660830a..3fbb0cdd2 100644 --- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -5050,6 +5050,7 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) break; } if (!ok) { + _mesa_reference_program(ctx, &linked_prog, NULL); return GL_FALSE; } } diff --git a/mesalib/src/mesa/swrast/s_texture.c b/mesalib/src/mesa/swrast/s_texture.c new file mode 100644 index 000000000..6cc72c582 --- /dev/null +++ b/mesalib/src/mesa/swrast/s_texture.c @@ -0,0 +1,109 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 2011 VMware, Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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. + */ + +/** + * Functions for mapping/unmapping texture images. + */ + + +#include "main/context.h" +#include "main/fbobject.h" +#include "swrast/swrast.h" +#include "swrast/s_context.h" + +/** + * Error checking for debugging only. + */ +static void +_mesa_check_map_teximage(struct gl_texture_image *texImage, + GLuint slice, GLuint x, GLuint y, GLuint w, GLuint h) +{ + + if (texImage->TexObject->Target == GL_TEXTURE_1D) + assert(y == 0 && h == 1); + + assert(x < texImage->Width || texImage->Width == 0); + assert(y < texImage->Height || texImage->Height == 0); + assert(x + w <= texImage->Width); + assert(y + h <= texImage->Height); +} + +/** + * Map a 2D slice of a texture image into user space. + * (x,y,w,h) defines a region of interest (ROI). Reading/writing texels + * outside of the ROI is undefined. + * + * \param texImage the texture image + * \param slice the 3D image slice or array texture slice + * \param x, y, w, h region of interest + * \param mode bitmask of GL_MAP_READ_BIT, GL_MAP_WRITE_BIT + * \param mapOut returns start of mapping of region of interest + * \param rowStrideOut returns row stride (in bytes) + */ +void +_swrast_map_teximage(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLuint slice, + GLuint x, GLuint y, GLuint w, GLuint h, + GLbitfield mode, + GLubyte **mapOut, + GLint *rowStrideOut) +{ + GLubyte *map; + GLint stride, texelSize; + GLuint bw, bh; + + _mesa_check_map_teximage(texImage, slice, x, y, w, h); + + texelSize = _mesa_get_format_bytes(texImage->TexFormat); + stride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width); + _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh); + + assert(texImage->Data); + + map = texImage->Data; + + if (texImage->TexObject->Target == GL_TEXTURE_3D || + texImage->TexObject->Target == GL_TEXTURE_2D_ARRAY) { + GLuint sliceSize = _mesa_format_image_size(texImage->TexFormat, + texImage->Width, + texImage->Height, + 1); + assert(slice < texImage->Depth); + map += slice * sliceSize; + } + + /* apply x/y offset to map address */ + map += stride * (y / bh) + texelSize * (x / bw); + + *mapOut = map; + *rowStrideOut = stride; +} + +void +_swrast_unmap_teximage(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLuint slice) +{ + /* nop */ +} diff --git a/mesalib/src/mesa/swrast/swrast.h b/mesalib/src/mesa/swrast/swrast.h index 27b74c324..c8b998635 100644 --- a/mesalib/src/mesa/swrast/swrast.h +++ b/mesalib/src/mesa/swrast/swrast.h @@ -182,6 +182,20 @@ _swrast_render_start( struct gl_context *ctx ); extern void _swrast_render_finish( struct gl_context *ctx ); +extern void +_swrast_map_teximage(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLuint slice, + GLuint x, GLuint y, GLuint w, GLuint h, + GLbitfield mode, + GLubyte **mapOut, + GLint *rowStrideOut); + +extern void +_swrast_unmap_teximage(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLuint slice); + /* Tell the software rasterizer about core state changes. */ extern void |