Unverified Commit 01436587 authored by Mike Gabriel's avatar Mike Gabriel

Merge branch 'frantracer-mesa-squash-subtree' into 3.6.x

parents 4f216e7c 123fb7fe

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

Mesa_6.4.1
\ No newline at end of file
Mesa.patches_6.4.1
\ No newline at end of file
4001_CreatePixmap-AllocationHints.patch
4002_define-USE_IEEE-macro-for-more-platforms.patch
From 44518d07398d663448d79e4f546736b40752630c Mon Sep 17 00:00:00 2001
From: Ulrich Sibiller <uli42@gmx.de>
Date: Wed, 16 Mar 2016 14:40:08 +0100
Subject: [PATCH] Fix non-working GLX in 64bit Xorg 7.0
Found the needed patch in debian bugtracker at
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=364233
---
src/glx/x11/indirect_vertex_array.c | 2 +-
src/mesa/drivers/dri/common/glcontextmodes.c | 3 +++
src/mesa/main/glheader.h | 3 +++
3 files changed, 7 insertions(+), 1 deletion(-)
Index: Mesa/src/glx/x11/indirect_vertex_array.c
===================================================================
--- Mesa.orig/src/glx/x11/indirect_vertex_array.c
+++ Mesa/src/glx/x11/indirect_vertex_array.c
@@ -530,7 +530,7 @@ static GLubyte *
emit_DrawArrays_header_old( __GLXcontext * gc,
struct array_state_vector * arrays,
size_t * elements_per_request,
- size_t * total_requests,
+ unsigned int * total_requests,
GLenum mode, GLsizei count )
{
size_t command_size;
Index: Mesa/src/mesa/main/glheader.h
===================================================================
--- Mesa.orig/src/mesa/main/glheader.h
+++ Mesa/src/mesa/main/glheader.h
@@ -46,6 +46,9 @@
#ifndef GLHEADER_H
#define GLHEADER_H
+#ifdef HAVE_DIX_CONFIG_H
+#include "dix-config.h"
+#endif
#if defined(XFree86LOADER) && defined(IN_MODULE)
#include "xf86_ansic.h"
Index: Mesa/src/mesa/drivers/dri/common/glcontextmodes.c
===================================================================
--- Mesa.orig/src/mesa/drivers/dri/common/glcontextmodes.c
+++ Mesa/src/mesa/drivers/dri/common/glcontextmodes.c
@@ -39,6 +39,9 @@
# include "imports.h"
# define __glXMemset memset
#else
+# if defined (HAVE_DIX_CONFIG_H)
+# include <dix-config.h>
+# endif
# include <X11/X.h>
# include <GL/glx.h>
# include "GL/glxint.h"
Description: Turn glx_ansic.h into a no-op include. (by using memset, malloc, free directly)
Author: Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
Index: Mesa/src/mesa/drivers/dri/common/glcontextmodes.c
===================================================================
--- Mesa.orig/src/mesa/drivers/dri/common/glcontextmodes.c
+++ Mesa/src/mesa/drivers/dri/common/glcontextmodes.c
@@ -48,15 +48,14 @@
# ifdef XFree86Server
# include "GL/glx_ansic.h"
-extern void * __glXMalloc( size_t size );
-extern void __glXFree( void * ptr );
-# define _mesa_malloc(b) __glXMalloc(b)
-# define _mesa_free(m) __glXFree(m)
+# define __glXMemset memset
+# define _mesa_malloc(b) malloc(b)
+# define _mesa_free(m) free(m)
# else
# include <X11/Xlibint.h>
# define __glXMemset memset
-# define _mesa_malloc(b) Xmalloc(b)
-# define _mesa_free(m) Xfree(m)
+# define _mesa_malloc(b) malloc(b)
+# define _mesa_free(m) free(m)
# endif /* XFree86Server */
#endif /* !defined(IN_MINI_GLX) */
4001_Fix-non-working-GLX-in-64bit-Xorg-7.0.patch
4002_no-special-glx-memfunctions.patch
4003_CreatePixmap-AllocationHints.patch
4004_define-USE_IEEE-macro-for-more-platforms.patch
\ No newline at end of file
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul 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, 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
* BRIAN PAUL 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 slang_assemble_constructor.c
* slang constructor and vector swizzle assembler
* \author Michal Krol
*/
#include "imports.h"
#include "slang_utility.h"
#include "slang_assemble_constructor.h"
#include "slang_assemble_typeinfo.h"
#include "slang_storage.h"
/* _slang_is_swizzle() */
int _slang_is_swizzle (const char *field, unsigned int rows, slang_swizzle *swz)
{
unsigned int i;
int xyzw = 0, rgba = 0, stpq = 0;
/* the swizzle can be at most 4-component long */
swz->num_components = slang_string_length (field);
if (swz->num_components > 4)
return 0;
for (i = 0; i < swz->num_components; i++)
{
/* mark which swizzle group is used */
switch (field[i])
{
case 'x':
case 'y':
case 'z':
case 'w':
xyzw = 1;
break;
case 'r':
case 'g':
case 'b':
case 'a':
rgba = 1;
break;
case 's':
case 't':
case 'p':
case 'q':
stpq = 1;
break;
default:
return 0;
}
/* collect swizzle component */
switch (field[i])
{
case 'x':
case 'r':
case 's':
swz->swizzle[i] = 0;
break;
case 'y':
case 'g':
case 't':
if (rows < 2)
return 0;
swz->swizzle[i] = 1;
break;
case 'z':
case 'b':
case 'p':
if (rows < 3)
return 0;
swz->swizzle[i] = 2;
break;
case 'w':
case 'a':
case 'q':
if (rows < 4)
return 0;
swz->swizzle[i] = 3;
break;
}
}
/* only one swizzle group can be used */
if ((xyzw && rgba) || (xyzw && stpq) || (rgba && stpq))
return 0;
return 1;
}
/* _slang_is_swizzle_mask() */
int _slang_is_swizzle_mask (const slang_swizzle *swz, unsigned int rows)
{
unsigned int c, i;
if (swz->num_components > rows)
return 0;
c = swz->swizzle[0];
for (i = 1; i < swz->num_components; i++)
{
if (swz->swizzle[i] <= c)
return 0;
c = swz->swizzle[i];
}
return 1;
}
/* _slang_multiply_swizzles() */
void _slang_multiply_swizzles (slang_swizzle *dst, const slang_swizzle *left,
const slang_swizzle *right)
{
unsigned int i;
dst->num_components = right->num_components;
for (i = 0; i < right->num_components; i++)
dst->swizzle[i] = left->swizzle[right->swizzle[i]];
}
/* _slang_assemble_constructor() */
static int constructor_aggregate (slang_assembly_file *file, const slang_storage_aggregate *flat,
unsigned int *index, slang_operation *op, unsigned int size, slang_assembly_flow_control *flow,
slang_assembly_name_space *space, slang_assembly_local_info *info)
{
slang_assembly_typeinfo ti;
int result;
slang_storage_aggregate agg, flat_agg;
slang_assembly_stack_info stk;
unsigned int i;
slang_assembly_typeinfo_construct (&ti);
if (!(result = _slang_typeof_operation (op, space, &ti)))
goto end1;
slang_storage_aggregate_construct (&agg);
if (!(result = _slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs)))
goto end2;
slang_storage_aggregate_construct (&flat_agg);
if (!(result = _slang_flatten_aggregate (&flat_agg, &agg)))
goto end;
if (!(result = _slang_assemble_operation (file, op, 0, flow, space, info, &stk)))
goto end;
for (i = 0; i < flat_agg.count; i++)
{
const slang_storage_array *arr1 = flat_agg.arrays + i;
const slang_storage_array *arr2 = flat->arrays + *index;
if (arr1->type != arr2->type)
{
/* TODO: convert (generic) from arr1 to arr2 */
}
(*index)++;
/* TODO: watch the index, if it reaches the size, pop off the stack subsequent values */
}
result = 1;
end:
slang_storage_aggregate_destruct (&flat_agg);
end2:
slang_storage_aggregate_destruct (&agg);
end1:
slang_assembly_typeinfo_destruct (&ti);
return result;
}
/* XXX: general swizzle! */
int _slang_assemble_constructor (slang_assembly_file *file, slang_operation *op,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
slang_assembly_local_info *info)
{
slang_assembly_typeinfo ti;
int result;
slang_storage_aggregate agg, flat;
unsigned int size, index, i;
slang_assembly_typeinfo_construct (&ti);
if (!(result = _slang_typeof_operation (op, space, &ti)))
goto end1;
slang_storage_aggregate_construct (&agg);
if (!(result = _slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs)))
goto end2;
size = _slang_sizeof_aggregate (&agg);
slang_storage_aggregate_construct (&flat);
if (!(result = _slang_flatten_aggregate (&flat, &agg)))
goto end;
index = 0;
for (i = 0; i < op->num_children; i++)
{
if (!(result = constructor_aggregate (file, &flat, &index, op->children + i, size, flow,
space, info)))
goto end;
/* TODO: watch the index, if it reaches the size, raise an error */
}
result = 1;
end:
slang_storage_aggregate_destruct (&flat);
end2:
slang_storage_aggregate_destruct (&agg);
end1:
slang_assembly_typeinfo_destruct (&ti);
return result;
}
/* _slang_assemble_constructor_from_swizzle() */
/* XXX: wrong */
int _slang_assemble_constructor_from_swizzle (slang_assembly_file *file, const slang_swizzle *swz,
slang_type_specifier *spec, slang_type_specifier *master_spec, slang_assembly_local_info *info)
{
unsigned int master_rows, i;
switch (master_spec->type)
{
case slang_spec_bool:
case slang_spec_int:
case slang_spec_float:
master_rows = 1;
break;
case slang_spec_bvec2:
case slang_spec_ivec2:
case slang_spec_vec2:
master_rows = 2;
break;
case slang_spec_bvec3:
case slang_spec_ivec3:
case slang_spec_vec3:
master_rows = 3;
break;
case slang_spec_bvec4:
case slang_spec_ivec4:
case slang_spec_vec4:
master_rows = 4;
break;
default:
break;
}
for (i = 0; i < master_rows; i++)
{
switch (master_spec->type)
{
case slang_spec_bool:
case slang_spec_bvec2:
case slang_spec_bvec3:
case slang_spec_bvec4:
if (!slang_assembly_file_push_label2 (file, slang_asm_bool_copy, (master_rows - i) * 4,
i * 4))
return 0;
break;
case slang_spec_int:
case slang_spec_ivec2:
case slang_spec_ivec3:
case slang_spec_ivec4:
if (!slang_assembly_file_push_label2 (file, slang_asm_int_copy, (master_rows - i) * 4,
i * 4))
return 0;
break;
case slang_spec_float:
case slang_spec_vec2:
case slang_spec_vec3:
case slang_spec_vec4:
if (!slang_assembly_file_push_label2 (file, slang_asm_float_copy,
(master_rows - i) * 4, i * 4))
return 0;
break;
default:
break;
}
}
if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
return 0;
for (i = swz->num_components; i > 0; i--)
{
unsigned int n = i - 1;
if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->swizzle_tmp, 16))
return 0;
if (!slang_assembly_file_push_label (file, slang_asm_addr_push, swz->swizzle[n] * 4))
return 0;
if (!slang_assembly_file_push (file, slang_asm_addr_add))
return 0;
switch (master_spec->type)
{
case slang_spec_bool:
case slang_spec_bvec2:
case slang_spec_bvec3:
case slang_spec_bvec4:
if (!slang_assembly_file_push (file, slang_asm_bool_deref))
return 0;
break;
case slang_spec_int:
case slang_spec_ivec2:
case slang_spec_ivec3:
case slang_spec_ivec4:
if (!slang_assembly_file_push (file, slang_asm_int_deref))
return 0;
break;
case slang_spec_float:
case slang_spec_vec2:
case slang_spec_vec3:
case slang_spec_vec4:
if (!slang_assembly_file_push (file, slang_asm_float_deref))
return 0;
break;
default:
break;
}
}
return 1;
}
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul 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, 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
* BRIAN PAUL 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 SLANG_COMPILE_H
#define SLANG_COMPILE_H
#if defined __cplusplus
extern "C" {
#endif
typedef enum slang_type_qualifier_
{
slang_qual_none,
slang_qual_const,
slang_qual_attribute,
slang_qual_varying,
slang_qual_uniform,
slang_qual_out,
slang_qual_inout,
slang_qual_fixedoutput, /* internal */
slang_qual_fixedinput /* internal */
} slang_type_qualifier;
typedef enum slang_type_specifier_type_
{
slang_spec_void,
slang_spec_bool,
slang_spec_bvec2,
slang_spec_bvec3,
slang_spec_bvec4,
slang_spec_int,
slang_spec_ivec2,
slang_spec_ivec3,
slang_spec_ivec4,
slang_spec_float,
slang_spec_vec2,
slang_spec_vec3,
slang_spec_vec4,
slang_spec_mat2,
slang_spec_mat3,
slang_spec_mat4,
slang_spec_sampler1D,
slang_spec_sampler2D,
slang_spec_sampler3D,
slang_spec_samplerCube,
slang_spec_sampler1DShadow,
slang_spec_sampler2DShadow,
slang_spec_struct,
slang_spec_array
} slang_type_specifier_type;
slang_type_specifier_type slang_type_specifier_type_from_string (const char *);
typedef struct slang_type_specifier_
{
slang_type_specifier_type type;
struct slang_struct_ *_struct; /* spec_struct */
struct slang_type_specifier_ *_array; /* spec_array */
} slang_type_specifier;
void slang_type_specifier_construct (slang_type_specifier *);
void slang_type_specifier_destruct (slang_type_specifier *);
int slang_type_specifier_copy (slang_type_specifier *, const slang_type_specifier *);
int slang_type_specifier_equal (const slang_type_specifier *, const slang_type_specifier *);
typedef struct slang_fully_specified_type_
{
slang_type_qualifier qualifier;
slang_type_specifier specifier;
} slang_fully_specified_type;
typedef struct slang_variable_scope_
{
struct slang_variable_ *variables;
unsigned int num_variables;
struct slang_variable_scope_ *outer_scope;
} slang_variable_scope;
typedef enum slang_operation_type_
{
slang_oper_none,
slang_oper_block_no_new_scope,
slang_oper_block_new_scope,
slang_oper_variable_decl,
slang_oper_asm,
slang_oper_break,
slang_oper_continue,
slang_oper_discard,
slang_oper_return,
slang_oper_expression,
slang_oper_if,
slang_oper_while,
slang_oper_do,
slang_oper_for,
slang_oper_void,
slang_oper_literal_bool,
slang_oper_literal_int,
slang_oper_literal_float,
slang_oper_identifier,
slang_oper_sequence,
slang_oper_assign,
slang_oper_addassign,
slang_oper_subassign,
slang_oper_mulassign,
slang_oper_divassign,
/*slang_oper_modassign,*/
/*slang_oper_lshassign,*/
/*slang_oper_rshassign,*/
/*slang_oper_orassign,*/
/*slang_oper_xorassign,*/
/*slang_oper_andassign,*/
slang_oper_select,
slang_oper_logicalor,
slang_oper_logicalxor,
slang_oper_logicaland,
/*slang_oper_bitor,*/
/*slang_oper_bitxor,*/
/*slang_oper_bitand,*/
slang_oper_equal,
slang_oper_notequal,
slang_oper_less,
slang_oper_greater,
slang_oper_lessequal,
slang_oper_greaterequal,
/*slang_oper_lshift,*/
/*slang_oper_rshift,*/
slang_oper_add,
slang_oper_subtract,
slang_oper_multiply,
slang_oper_divide,
/*slang_oper_modulus,*/
slang_oper_preincrement,
slang_oper_predecrement,
slang_oper_plus,
slang_oper_minus,
/*slang_oper_complement,*/
slang_oper_not,
slang_oper_subscript,
slang_oper_call,
slang_oper_field,
slang_oper_postincrement,
slang_oper_postdecrement
} slang_operation_type;
typedef struct slang_operation_
{
slang_operation_type type;
struct slang_operation_ *children;
unsigned int num_children;
float literal; /* bool, literal_int, literal_float */
char *identifier; /* asm, identifier, call, field */
slang_variable_scope *locals;
} slang_operation;
int slang_operation_construct_a (slang_operation *);
void slang_operation_destruct (slang_operation *);
typedef struct slang_variable_
{
slang_fully_specified_type type;
char *name;
slang_operation *array_size; /* spec_array */
slang_operation *initializer;
unsigned int address;
} slang_variable;
slang_variable *_slang_locate_variable (slang_variable_scope *scope, const char *name, int all);
typedef struct slang_struct_scope_
{
struct slang_struct_ *structs;
unsigned int num_structs;
struct slang_struct_scope_ *outer_scope;
} slang_struct_scope;
struct slang_struct_ *slang_struct_scope_find (slang_struct_scope *, const char *, int);
typedef struct slang_struct_
{
char *name;
slang_variable_scope *fields;
slang_struct_scope *structs;
} slang_struct;
int slang_struct_construct_a (slang_struct *);
int slang_struct_copy (slang_struct *, const slang_struct *);
typedef enum slang_function_kind_
{
slang_func_ordinary,
slang_func_constructor,
slang_func_operator
} slang_function_kind;
typedef struct slang_function_
{
slang_function_kind kind;
slang_variable header;
slang_variable_scope *parameters;
unsigned int param_count;
slang_operation *body;
unsigned int address;
} slang_function;
typedef struct slang_function_scope_
{
slang_function *functions;
unsigned int num_functions;
struct slang_function_scope_ *outer_scope;
} slang_function_scope;
typedef enum slang_unit_type_
{
slang_unit_fragment_shader,
slang_unit_vertex_shader,
slang_unit_fragment_builtin,
slang_unit_vertex_builtin
} slang_unit_type;
typedef struct slang_translation_unit_
{
slang_variable_scope globals;
slang_function_scope functions;
slang_struct_scope structs;
slang_unit_type type;
} slang_translation_unit;
void slang_translation_unit_construct (slang_translation_unit *);
void slang_translation_unit_destruct (slang_translation_unit *);
typedef struct slang_info_log_
{
char *text;
int dont_free_text;
} slang_info_log;
void slang_info_log_construct (slang_info_log *);
void slang_info_log_destruct (slang_info_log *);
int slang_info_log_error (slang_info_log *, const char *, ...);
int slang_info_log_warning (slang_info_log *, const char *, ...);
void slang_info_log_memory (slang_info_log *);
int _slang_compile (const char *, slang_translation_unit *, slang_unit_type type, slang_info_log *);
#ifdef __cplusplus
}
#endif
#endif
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul 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, 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
* BRIAN PAUL 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 slang_execute.c
* intermediate code interpreter
* \author Michal Krol
*/
#include "imports.h"
#include "slang_utility.h"
#include "slang_assemble.h"
#include "slang_storage.h"
#include "slang_execute.h"
static void dump_instruction (FILE *f, slang_assembly *a, unsigned int i)
{
fprintf (f, "%.5u:\t", i);
switch (a->type)
{
case slang_asm_none:
fprintf (f, "none");
break;
case slang_asm_float_copy:
fprintf (f, "float_copy\t%d, %d", a->param[0], a->param[1]);
break;
case slang_asm_float_move:
fprintf (f, "float_move\t%d, %d", a->param[0], a->param[1]);
break;
case slang_asm_float_push:
fprintf (f, "float_push\t%f", a->literal);
break;
case slang_asm_float_deref:
fprintf (f, "float_deref");
break;
case slang_asm_float_add:
fprintf (f, "float_add");
break;
case slang_asm_float_multiply:
fprintf (f, "float_multiply");
break;
case slang_asm_float_divide:
fprintf (f, "float_divide");
break;
case slang_asm_float_negate:
fprintf (f, "float_negate");
break;
case slang_asm_float_less:
fprintf (f, "float_less");
break;
case slang_asm_float_equal:
fprintf (f, "float_equal\t%d, %d", a->param[0], a->param[1]);
break;
case slang_asm_float_to_int:
fprintf (f, "float_to_int");
break;
case slang_asm_int_copy:
fprintf (f, "int_copy\t%d, %d", a->param[0], a->param[1]);
break;
case slang_asm_int_move:
fprintf (f, "int_move\t%d, %d", a->param[0], a->param[1]);
break;
case slang_asm_int_push:
fprintf (f, "int_push\t%d", (GLint) a->literal);
break;
case slang_asm_int_deref:
fprintf (f, "int_deref");
break;
case slang_asm_int_to_float:
fprintf (f, "int_to_float");
break;
case slang_asm_int_to_addr:
fprintf (f, "int_to_addr");
break;
case slang_asm_bool_copy:
fprintf (f, "bool_copy\t%d, %d", a->param[0], a->param[1]);
break;
case slang_asm_bool_move:
fprintf (f, "bool_move\t%d, %d", a->param[0], a->param[1]);
break;
case slang_asm_bool_push:
fprintf (f, "bool_push\t%d", a->literal != 0.0f);
break;
case slang_asm_bool_deref:
fprintf (f, "bool_deref");
break;
case slang_asm_addr_copy:
fprintf (f, "addr_copy");
break;
case slang_asm_addr_push:
fprintf (f, "addr_push\t%u", a->param[0]);
break;
case slang_asm_addr_deref:
fprintf (f, "addr_deref");
break;
case slang_asm_addr_add:
fprintf (f, "addr_add");
break;
case slang_asm_addr_multiply:
fprintf (f, "addr_multiply");
break;
case slang_asm_jump:
fprintf (f, "jump\t%u", a->param[0]);
break;
case slang_asm_jump_if_zero:
fprintf (f, "jump_if_zero\t%u", a->param[0]);
break;
case slang_asm_enter:
fprintf (f, "enter\t%u", a->param[0]);
break;
case slang_asm_leave:
fprintf (f, "leave");
break;
case slang_asm_local_alloc:
fprintf (f, "local_alloc\t%u", a->param[0]);
break;
case slang_asm_local_free:
fprintf (f, "local_free\t%u", a->param[0]);
break;
case slang_asm_local_addr:
fprintf (f, "local_addr\t%u, %u", a->param[0], a->param[1]);
break;
case slang_asm_call:
fprintf (f, "call\t%u", a->param[0]);
break;
case slang_asm_return:
fprintf (f, "return");
break;
case slang_asm_discard:
fprintf (f, "discard");
break;
case slang_asm_exit:
fprintf (f, "exit");
break;
default:
break;
}
fprintf (f, "\n");
}
static void dump (const slang_assembly_file *file)
{
unsigned int i;
static unsigned int counter = 0;
FILE *f;
char filename[256];
counter++;
sprintf (filename, "~mesa-slang-assembly-dump-(%u).txt", counter);
f = fopen (filename, "w");
if (f == NULL)
return;
for (i = 0; i < file->count; i++)
dump_instruction (f, file->code + i, i);
fclose (f);
}
int _slang_execute (const slang_assembly_file *file)
{
slang_machine mach;
FILE *f;
mach.ip = 0;
mach.sp = SLANG_MACHINE_STACK_SIZE;
mach.bp = 0;
mach.kill = 0;
mach.exit = 0;
/* assume 32-bit machine */
/* XXX why???, disabling the pointer size assertions here.
* See bug 4021.
*/
_static_assert(sizeof (GLfloat) == 4);
/*_static_assert(sizeof (GLfloat *) == 4);*/
_static_assert(sizeof (GLuint) == 4);
/*_static_assert(sizeof (GLuint *) == 4);*/
dump (file);
f = fopen ("~mesa-slang-assembly-execution.txt", "w");
while (!mach.exit)
{
slang_assembly *a = file->code + mach.ip;
if (f != NULL)
{
unsigned int i;
dump_instruction (f, a, mach.ip);
fprintf (f, "\t\tsp=%u bp=%u\n", mach.sp, mach.bp);
for (i = mach.sp; i < SLANG_MACHINE_STACK_SIZE; i++)
fprintf (f, "\t%.5u\t%6f\t%u\n", i, mach.stack._float[i], mach.stack._addr[i]);
fflush (f);
}
mach.ip++;
switch (a->type)
{
case slang_asm_none:
break;
case slang_asm_float_copy:
case slang_asm_int_copy:
case slang_asm_bool_copy:
*(mach.stack._floatp[mach.sp + a->param[0] / 4] + a->param[1] / 4) =
mach.stack._float[mach.sp];
mach.sp++;
break;
case slang_asm_float_move:
case slang_asm_int_move:
case slang_asm_bool_move:
mach.stack._float[mach.sp + a->param[0] / 4] =
mach.stack._float[mach.sp + (mach.stack._addr[mach.sp] + a->param[1]) / 4];
break;
case slang_asm_float_push:
case slang_asm_int_push:
case slang_asm_bool_push:
mach.sp--;
mach.stack._float[mach.sp] = a->literal;
break;
case slang_asm_float_deref:
case slang_asm_int_deref:
case slang_asm_bool_deref:
mach.stack._float[mach.sp] = *mach.stack._floatp[mach.sp];
break;
case slang_asm_float_add:
mach.stack._float[mach.sp + 1] += mach.stack._float[mach.sp];
mach.sp++;
break;
case slang_asm_float_multiply:
mach.stack._float[mach.sp + 1] *= mach.stack._float[mach.sp];
mach.sp++;
break;
case slang_asm_float_divide:
mach.stack._float[mach.sp + 1] /= mach.stack._float[mach.sp];
mach.sp++;
break;
case slang_asm_float_negate:
mach.stack._float[mach.sp] = -mach.stack._float[mach.sp];
break;
case slang_asm_float_less:
mach.stack._float[mach.sp + 1] =
mach.stack._float[mach.sp + 1] < mach.stack._float[mach.sp] ? 1.0f : 0.0f;
mach.sp++;
break;
case slang_asm_float_equal:
mach.sp--;
mach.stack._float[mach.sp] = mach.stack._float[mach.sp + 1 + a->param[0] / 4] ==
mach.stack._float[mach.sp + 1 + a->param[1] / 4] ? 1.0f : 0.0f;
break;
case slang_asm_float_to_int:
mach.stack._float[mach.sp] = (GLfloat) (GLint) mach.stack._float[mach.sp];
break;
case slang_asm_int_to_float:
break;
case slang_asm_int_to_addr:
mach.stack._addr[mach.sp] = (GLuint) (GLint) mach.stack._float[mach.sp];
break;
case slang_asm_addr_copy:
*mach.stack._addrp[mach.sp + 1] = mach.stack._addr[mach.sp];
mach.sp++;
break;
case slang_asm_addr_push:
mach.sp--;
mach.stack._addr[mach.sp] = a->param[0];
break;
case slang_asm_addr_deref:
mach.stack._addr[mach.sp] = *mach.stack._addrp[mach.sp];
break;
case slang_asm_addr_add:
mach.stack._addr[mach.sp + 1] += mach.stack._addr[mach.sp];
mach.sp++;
break;
case slang_asm_addr_multiply:
mach.stack._addr[mach.sp + 1] *= mach.stack._addr[mach.sp];
mach.sp++;
break;
case slang_asm_jump:
mach.ip = a->param[0];
break;
case slang_asm_jump_if_zero:
if (mach.stack._float[mach.sp] == 0.0f)
mach.ip = a->param[0];
mach.sp++;
break;
case slang_asm_enter:
mach.sp--;
mach.stack._addr[mach.sp] = mach.bp;
mach.bp = mach.sp + a->param[0] / 4;
break;
case slang_asm_leave:
mach.bp = mach.stack._addr[mach.sp];
mach.sp++;
break;
case slang_asm_local_alloc:
mach.sp -= a->param[0] / 4;
break;
case slang_asm_local_free:
mach.sp += a->param[0] / 4;
break;
case slang_asm_local_addr:
mach.sp--;
mach.stack._addr[mach.sp] = (GLuint) mach.stack._addr + mach.bp * 4 -
(a->param[0] + a->param[1]) + 4;
break;
case slang_asm_call:
mach.sp--;
mach.stack._addr[mach.sp] = mach.ip;
mach.ip = a->param[0];
break;
case slang_asm_return:
mach.ip = mach.stack._addr[mach.sp];
mach.sp++;
break;
case slang_asm_discard:
mach.kill = 1;
break;
case slang_asm_exit:
mach.exit = 1;
break;
}
}
if (f != NULL)
fclose (f);
return 0;
}
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 2005 Brian Paul 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, 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
* BRIAN PAUL 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 slang_storage.c
* slang variable storage
* \author Michal Krol
*/
#include "imports.h"
#include "slang_utility.h"
#include "slang_storage.h"
#include "slang_assemble.h"
/* slang_storage_array */
void slang_storage_array_construct (slang_storage_array *arr)
{
arr->type = slang_stor_aggregate;
arr->aggregate = NULL;
arr->length = 0;
}
void slang_storage_array_destruct (slang_storage_array *arr)
{
if (arr->aggregate != NULL)
{
slang_storage_aggregate_destruct (arr->aggregate);
slang_alloc_free (arr->aggregate);
}
}
/* slang_storage_aggregate */
void slang_storage_aggregate_construct (slang_storage_aggregate *agg)
{
agg->arrays = NULL;
agg->count = 0;
}
void slang_storage_aggregate_destruct (slang_storage_aggregate *agg)
{
unsigned int i;
for (i = 0; i < agg->count; i++)
slang_storage_array_destruct (agg->arrays + i);
slang_alloc_free (agg->arrays);
}
static slang_storage_array *slang_storage_aggregate_push_new (slang_storage_aggregate *agg)
{
slang_storage_array *arr = NULL;
agg->arrays = (slang_storage_array *) slang_alloc_realloc (agg->arrays, agg->count * sizeof (
slang_storage_array), (agg->count + 1) * sizeof (slang_storage_array));
if (agg->arrays != NULL)
{
arr = agg->arrays + agg->count;
slang_storage_array_construct (arr);
agg->count++;
}
return arr;
}
/* _slang_aggregate_variable() */
static int aggregate_vector (slang_storage_aggregate *agg, slang_storage_type basic_type,
unsigned int row_count)
{
slang_storage_array *arr = slang_storage_aggregate_push_new (agg);
if (arr == NULL)
return 0;
arr->type = basic_type;
arr->length = row_count;
return 1;
}
static int aggregate_matrix (slang_storage_aggregate *agg, slang_storage_type basic_type,
unsigned int dimension)
{
slang_storage_array *arr = slang_storage_aggregate_push_new (agg);
if (arr == NULL)
return 0;
arr->type = slang_stor_aggregate;
arr->length = dimension;
arr->aggregate = (slang_storage_aggregate *) slang_alloc_malloc (sizeof (
slang_storage_aggregate));
if (arr->aggregate == NULL)
return 0;
slang_storage_aggregate_construct (arr->aggregate);
if (!aggregate_vector (arr->aggregate, basic_type, dimension))
return 0;
return 1;
}
static int aggregate_variables (slang_storage_aggregate *agg, const slang_variable_scope *vars,
slang_function_scope *funcs, slang_struct_scope *structs)
{
unsigned int i;
for (i = 0; i < vars->num_variables; i++)
if (!_slang_aggregate_variable (agg, &vars->variables[i].type.specifier,
vars->variables[i].array_size, funcs, structs))
return 0;
return 1;
}
int _slang_aggregate_variable (slang_storage_aggregate *agg, slang_type_specifier *spec,
slang_operation *array_size, slang_function_scope *funcs, slang_struct_scope *structs)
{
switch (spec->type)
{
case slang_spec_bool:
return aggregate_vector (agg, slang_stor_bool, 1);
case slang_spec_bvec2:
return aggregate_vector (agg, slang_stor_bool, 2);
case slang_spec_bvec3:
return aggregate_vector (agg, slang_stor_bool, 3);
case slang_spec_bvec4:
return aggregate_vector (agg, slang_stor_bool, 4);
case slang_spec_int:
return aggregate_vector (agg, slang_stor_int, 1);
case slang_spec_ivec2:
return aggregate_vector (agg, slang_stor_int, 2);
case slang_spec_ivec3:
return aggregate_vector (agg, slang_stor_int, 3);
case slang_spec_ivec4:
return aggregate_vector (agg, slang_stor_int, 4);
case slang_spec_float:
return aggregate_vector (agg, slang_stor_float, 1);
case slang_spec_vec2:
return aggregate_vector (agg, slang_stor_float, 2);
case slang_spec_vec3:
return aggregate_vector (agg, slang_stor_float, 3);
case slang_spec_vec4:
return aggregate_vector (agg, slang_stor_float, 4);
case slang_spec_mat2:
return aggregate_matrix (agg, slang_stor_float, 2);
case slang_spec_mat3:
return aggregate_matrix (agg, slang_stor_float, 3);
case slang_spec_mat4:
return aggregate_matrix (agg, slang_stor_float, 4);
case slang_spec_sampler1D:
case slang_spec_sampler2D:
case slang_spec_sampler3D:
case slang_spec_samplerCube:
case slang_spec_sampler1DShadow:
case slang_spec_sampler2DShadow:
return aggregate_vector (agg, slang_stor_int, 1);
case slang_spec_struct:
return aggregate_variables (agg, spec->_struct->fields, funcs, structs);
case slang_spec_array:
{
slang_storage_array *arr;
slang_assembly_file file;
slang_assembly_flow_control flow;
slang_assembly_name_space space;
slang_assembly_local_info info;
slang_assembly_stack_info stk;
arr = slang_storage_aggregate_push_new (agg);
if (arr == NULL)
return 0;
arr->type = slang_stor_aggregate;
arr->aggregate = (slang_storage_aggregate *) slang_alloc_malloc (sizeof (
slang_storage_aggregate));
if (arr->aggregate == NULL)
return 0;
slang_storage_aggregate_construct (arr->aggregate);
if (!_slang_aggregate_variable (arr->aggregate, spec->_array, NULL, funcs, structs))
return 0;
slang_assembly_file_construct (&file);
space.funcs = funcs;
space.structs = structs;
/* XXX: vars! */
space.vars = NULL;
if (!_slang_assemble_operation (&file, array_size, 0, &flow, &space, &info, &stk))
{
slang_assembly_file_destruct (&file);
return 0;
}
/* TODO: evaluate array size */
slang_assembly_file_destruct (&file);
arr->length = 256;
}
return 1;
default:
return 0;
}
}
/* _slang_sizeof_aggregate() */
unsigned int _slang_sizeof_aggregate (const slang_storage_aggregate *agg)
{
unsigned int i, size = 0;
for (i = 0; i < agg->count; i++)
{
unsigned int element_size;
if (agg->arrays[i].type == slang_stor_aggregate)
element_size = _slang_sizeof_aggregate (agg->arrays[i].aggregate);
else
element_size = sizeof (GLfloat);
size += element_size * agg->arrays[i].length;
}
return size;
}
/* _slang_flatten_aggregate () */
int _slang_flatten_aggregate (slang_storage_aggregate *flat, const slang_storage_aggregate *agg)
{
unsigned int i;
for (i = 0; i < agg->count; i++)
{
unsigned int j;
for (j = 0; j < agg->arrays[i].length; j++)
{
if (agg->arrays[i].type == slang_stor_aggregate)
{
if (!_slang_flatten_aggregate (flat, agg->arrays[i].aggregate))
return 0;
}
else
{
slang_storage_array *arr;
arr = slang_storage_aggregate_push_new (flat);
if (arr == NULL)
return 0;
arr->type = agg->arrays[i].type;
arr->length = 1;
}
}
}
return 1;
}
/*
* Mesa 3-D graphics library
* Version: 4.1
*
* Copyright (C) 1999-2002 Brian Paul 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, 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
* BRIAN PAUL 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 swrast/s_alpha.c
* \brief Functions to apply alpha test.
*/
#include "glheader.h"
#include "context.h"
#include "colormac.h"
#include "macros.h"
#include "s_alpha.h"
#include "s_context.h"
/**
* \fn GLint _swrast_alpha_test( const GLcontext *ctx, struct sw_span *span )
* \brief Apply the alpha test to a span of pixels.
* \return
* - "0" = all pixels in the span failed the alpha test.
* - "1" = one or more pixels passed the alpha test.
*/
GLint
_swrast_alpha_test( const GLcontext *ctx, struct sw_span *span )
{
const GLchan (*rgba)[4] = (const GLchan (*)[4]) span->array->rgba;
GLchan ref;
const GLuint n = span->end;
GLubyte *mask = span->array->mask;
GLuint i;
CLAMPED_FLOAT_TO_CHAN(ref, ctx->Color.AlphaRef);
if (span->arrayMask & SPAN_RGBA) {
/* Use the array values */
switch (ctx->Color.AlphaFunc) {
case GL_LESS:
for (i = 0; i < n; i++)
mask[i] &= (rgba[i][ACOMP] < ref);
break;
case GL_LEQUAL:
for (i = 0; i < n; i++)
mask[i] &= (rgba[i][ACOMP] <= ref);
break;
case GL_GEQUAL:
for (i = 0; i < n; i++)
mask[i] &= (rgba[i][ACOMP] >= ref);
break;
case GL_GREATER:
for (i = 0; i < n; i++)
mask[i] &= (rgba[i][ACOMP] > ref);
break;
case GL_NOTEQUAL:
for (i = 0; i < n; i++)
mask[i] &= (rgba[i][ACOMP] != ref);
break;
case GL_EQUAL:
for (i = 0; i < n; i++)
mask[i] &= (rgba[i][ACOMP] == ref);
break;
case GL_ALWAYS:
/* do nothing */
return 1;
case GL_NEVER:
/* caller should check for zero! */
span->writeAll = GL_FALSE;
return 0;
default:
_mesa_problem( ctx, "Invalid alpha test in _swrast_alpha_test" );
return 0;
}
}
else {
/* Use the interpolation values */
#if CHAN_TYPE == GL_FLOAT
const GLfloat alphaStep = span->alphaStep;
GLfloat alpha = span->alpha;
ASSERT(span->interpMask & SPAN_RGBA);
switch (ctx->Color.AlphaFunc) {
case GL_LESS:
for (i = 0; i < n; i++) {
mask[i] &= (alpha < ref);
alpha += alphaStep;
}
break;
case GL_LEQUAL:
for (i = 0; i < n; i++) {
mask[i] &= (alpha <= ref);
alpha += alphaStep;
}
break;
case GL_GEQUAL:
for (i = 0; i < n; i++) {
mask[i] &= (alpha >= ref);
alpha += alphaStep;
}
break;
case GL_GREATER:
for (i = 0; i < n; i++) {
mask[i] &= (alpha > ref);
alpha += alphaStep;
}
break;
case GL_NOTEQUAL:
for (i = 0; i < n; i++) {
mask[i] &= (alpha != ref);
alpha += alphaStep;
}
break;
case GL_EQUAL:
for (i = 0; i < n; i++) {
mask[i] &= (alpha == ref);
alpha += alphaStep;
}
break;
case GL_ALWAYS:
/* do nothing */
return 1;
case GL_NEVER:
/* caller should check for zero! */
span->writeAll = GL_FALSE;
return 0;
default:
_mesa_problem( ctx, "Invalid alpha test in gl_alpha_test" );
return 0;
}
#else
/* 8 or 16-bit channel interpolation */
const GLfixed alphaStep = span->alphaStep;
GLfixed alpha = span->alpha;
ASSERT(span->interpMask & SPAN_RGBA);
switch (ctx->Color.AlphaFunc) {
case GL_LESS:
for (i = 0; i < n; i++) {
mask[i] &= (FixedToChan(alpha) < ref);
alpha += alphaStep;
}
break;
case GL_LEQUAL:
for (i = 0; i < n; i++) {
mask[i] &= (FixedToChan(alpha) <= ref);
alpha += alphaStep;
}
break;
case GL_GEQUAL:
for (i = 0; i < n; i++) {
mask[i] &= (FixedToChan(alpha) >= ref);
alpha += alphaStep;
}
break;
case GL_GREATER:
for (i = 0; i < n; i++) {
mask[i] &= (FixedToChan(alpha) > ref);
alpha += alphaStep;
}
break;
case GL_NOTEQUAL:
for (i = 0; i < n; i++) {
mask[i] &= (FixedToChan(alpha) != ref);
alpha += alphaStep;
}
break;
case GL_EQUAL:
for (i = 0; i < n; i++) {
mask[i] &= (FixedToChan(alpha) == ref);
alpha += alphaStep;
}
break;
case GL_ALWAYS:
/* do nothing */
return 1;
case GL_NEVER:
/* caller should check for zero! */
span->writeAll = GL_FALSE;
return 0;
default:
_mesa_problem( ctx, "Invalid alpha test in gl_alpha_test" );
return 0;
}
#endif /* CHAN_TYPE */
}
#if 0
/* XXXX This causes conformance failures!!!! */
while ((span->start <= span->end) &&
(mask[span->start] == 0))
span->start ++;
while ((span->end >= span->start) &&
(mask[span->end] == 0))
span->end --;
#endif
span->writeAll = GL_FALSE;
if (span->start >= span->end)
return 0;
else
return 1;
}
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 1999-2004 Brian Paul 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, 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
* BRIAN PAUL 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 swrast/s_bitmap.c
* \brief glBitmap rendering.
* \author Brian Paul
*/
#include "glheader.h"
#include "bufferobj.h"
#include "image.h"
#include "macros.h"
#include "pixel.h"
#include "s_context.h"
#include "s_span.h"
/*
* Render a bitmap.
*/
void
_swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
GLsizei width, GLsizei height,
const struct gl_pixelstore_attrib *unpack,
const GLubyte *bitmap )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLint row, col;
GLuint count = 0;
struct sw_span span;
ASSERT(ctx->RenderMode == GL_RENDER);
if (unpack->BufferObj->Name) {
/* unpack from PBO */
GLubyte *buf;
if (!_mesa_validate_pbo_access(2, unpack, width, height, 1,
GL_COLOR_INDEX, GL_BITMAP,
(GLvoid *) bitmap)) {
_mesa_error(ctx, GL_INVALID_OPERATION,"glBitmap(invalid PBO access)");
return;
}
buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
GL_READ_ONLY_ARB,
unpack->BufferObj);
if (!buf) {
/* buffer is already mapped - that's an error */
_mesa_error(ctx, GL_INVALID_OPERATION, "glBitmap(PBO is mapped)");
return;
}
bitmap = ADD_POINTERS(buf, bitmap);
}
RENDER_START(swrast,ctx);
if (SWRAST_CONTEXT(ctx)->NewState)
_swrast_validate_derived( ctx );
INIT_SPAN(span, GL_BITMAP, width, 0, SPAN_XY);
if (ctx->Visual.rgbMode) {
span.interpMask |= SPAN_RGBA;
span.red = FloatToFixed(ctx->Current.RasterColor[0] * CHAN_MAXF);
span.green = FloatToFixed(ctx->Current.RasterColor[1] * CHAN_MAXF);
span.blue = FloatToFixed(ctx->Current.RasterColor[2] * CHAN_MAXF);
span.alpha = FloatToFixed(ctx->Current.RasterColor[3] * CHAN_MAXF);
span.redStep = span.greenStep = span.blueStep = span.alphaStep = 0;
}
else {
span.interpMask |= SPAN_INDEX;
span.index = FloatToFixed(ctx->Current.RasterIndex);
span.indexStep = 0;
}
if (ctx->Depth.Test)
_swrast_span_default_z(ctx, &span);
if (swrast->_FogEnabled)
_swrast_span_default_fog(ctx, &span);
if (ctx->Texture._EnabledCoordUnits)
_swrast_span_default_texcoords(ctx, &span);
for (row = 0; row < height; row++) {
const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack,
bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0);
if (unpack->LsbFirst) {
/* Lsb first */
GLubyte mask = 1U << (unpack->SkipPixels & 0x7);
for (col = 0; col < width; col++) {
if (*src & mask) {
span.array->x[count] = px + col;
span.array->y[count] = py + row;
count++;
}
if (mask == 128U) {
src++;
mask = 1U;
}
else {
mask = mask << 1;
}
}
/* get ready for next row */
if (mask != 1)
src++;
}
else {
/* Msb first */
GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
for (col = 0; col < width; col++) {
if (*src & mask) {
span.array->x[count] = px + col;
span.array->y[count] = py + row;
count++;
}
if (mask == 1U) {
src++;
mask = 128U;
}
else {
mask = mask >> 1;
}
}
/* get ready for next row */
if (mask != 128)
src++;
}
if (count + width >= MAX_WIDTH || row + 1 == height) {
/* flush the span */
span.end = count;
if (ctx->Visual.rgbMode)
_swrast_write_rgba_span(ctx, &span);
else
_swrast_write_index_span(ctx, &span);
span.end = 0;
count = 0;
}
}
RENDER_FINISH(swrast,ctx);
if (unpack->BufferObj->Name) {
/* done with PBO so unmap it now */
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
unpack->BufferObj);
}
}
#if 0
/*
* XXX this is another way to implement Bitmap. Use horizontal runs of
* fragments, initializing the mask array to indicate which fragmens to
* draw or skip.
*/
void
_swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
GLsizei width, GLsizei height,
const struct gl_pixelstore_attrib *unpack,
const GLubyte *bitmap )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLint row, col;
struct sw_span span;
ASSERT(ctx->RenderMode == GL_RENDER);
ASSERT(bitmap);
RENDER_START(swrast,ctx);
if (SWRAST_CONTEXT(ctx)->NewState)
_swrast_validate_derived( ctx );
INIT_SPAN(span, GL_BITMAP, width, 0, SPAN_MASK);
/*span.arrayMask |= SPAN_MASK;*/ /* we'll init span.mask[] */
span.x = px;
span.y = py;
/*span.end = width;*/
if (ctx->Visual.rgbMode) {
span.interpMask |= SPAN_RGBA;
span.red = FloatToFixed(ctx->Current.RasterColor[0] * CHAN_MAXF);
span.green = FloatToFixed(ctx->Current.RasterColor[1] * CHAN_MAXF);
span.blue = FloatToFixed(ctx->Current.RasterColor[2] * CHAN_MAXF);
span.alpha = FloatToFixed(ctx->Current.RasterColor[3] * CHAN_MAXF);
span.redStep = span.greenStep = span.blueStep = span.alphaStep = 0;
}
else {
span.interpMask |= SPAN_INDEX;
span.index = FloatToFixed(ctx->Current.RasterIndex);
span.indexStep = 0;
}
if (ctx->Depth.Test)
_swrast_span_default_z(ctx, &span);
if (swrast->_FogEnabled)
_swrast_span_default_fog(ctx, &span);
if (ctx->Texture._EnabledCoordUnits)
_swrast_span_default_texcoords(ctx, &span);
for (row=0; row<height; row++, span.y++) {
const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack,
bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0);
if (unpack->LsbFirst) {
/* Lsb first */
GLubyte mask = 1U << (unpack->SkipPixels & 0x7);
for (col=0; col<width; col++) {
span.array->mask[col] = (*src & mask) ? GL_TRUE : GL_FALSE;
if (mask == 128U) {
src++;
mask = 1U;
}
else {
mask = mask << 1;
}
}
if (ctx->Visual.rgbMode)
_swrast_write_rgba_span(ctx, &span);
else
_swrast_write_index_span(ctx, &span);
/* get ready for next row */
if (mask != 1)
src++;
}
else {
/* Msb first */
GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
for (col=0; col<width; col++) {
span.array->mask[col] = (*src & mask) ? GL_TRUE : GL_FALSE;
if (mask == 1U) {
src++;
mask = 128U;
}
else {
mask = mask >> 1;
}
}
if (ctx->Visual.rgbMode)
_swrast_write_rgba_span(ctx, &span);
else
_swrast_write_index_span(ctx, &span);
/* get ready for next row */
if (mask != 128)
src++;
}
}
RENDER_FINISH(swrast,ctx);
}
#endif
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 1999-2005 Brian Paul 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, 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
* BRIAN PAUL 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 "glheader.h"
#include "colormac.h"
#include "context.h"
#include "enums.h"
#include "feedback.h"
#include "macros.h"
#include "s_context.h"
#include "s_feedback.h"
#include "s_triangle.h"
#define FB_3D 0x01
#define FB_4D 0x02
#define FB_INDEX 0x04
#define FB_COLOR 0x08
#define FB_TEXTURE 0X10
static void feedback_vertex( GLcontext *ctx,
const SWvertex *v, const SWvertex *pv )
{
const GLuint texUnit = 0; /* See section 5.3 of 1.2.1 spec */
GLfloat win[4];
GLfloat color[4];
GLfloat tc[4];
win[0] = v->win[0];
win[1] = v->win[1];
win[2] = v->win[2] / ctx->DrawBuffer->_DepthMaxF;
win[3] = 1.0F / v->win[3];
color[0] = CHAN_TO_FLOAT(pv->color[0]);
color[1] = CHAN_TO_FLOAT(pv->color[1]);
color[2] = CHAN_TO_FLOAT(pv->color[2]);
color[3] = CHAN_TO_FLOAT(pv->color[3]);
if (v->texcoord[texUnit][3] != 1.0 &&
v->texcoord[texUnit][3] != 0.0) {
GLfloat invq = 1.0F / v->texcoord[texUnit][3];
tc[0] = v->texcoord[texUnit][0] * invq;
tc[1] = v->texcoord[texUnit][1] * invq;
tc[2] = v->texcoord[texUnit][2] * invq;
tc[3] = v->texcoord[texUnit][3];
}
else {
COPY_4V(tc, v->texcoord[texUnit]);
}
_mesa_feedback_vertex( ctx, win, color, (GLfloat) v->index, tc );
}
/*
* Put triangle in feedback buffer.
*/
void _swrast_feedback_triangle( GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1,
const SWvertex *v2)
{
if (_swrast_culltriangle( ctx, v0, v1, v2 )) {
FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_POLYGON_TOKEN );
FEEDBACK_TOKEN( ctx, (GLfloat) 3 ); /* three vertices */
if (ctx->Light.ShadeModel == GL_SMOOTH) {
feedback_vertex( ctx, v0, v0 );
feedback_vertex( ctx, v1, v1 );
feedback_vertex( ctx, v2, v2 );
} else {
feedback_vertex( ctx, v0, v2 );
feedback_vertex( ctx, v1, v2 );
feedback_vertex( ctx, v2, v2 );
}
}
}
void _swrast_feedback_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 )
{
GLenum token = GL_LINE_TOKEN;
SWcontext *swrast = SWRAST_CONTEXT(ctx);
if (swrast->StippleCounter==0)
token = GL_LINE_RESET_TOKEN;
FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) token );
if (ctx->Light.ShadeModel == GL_SMOOTH) {
feedback_vertex( ctx, v0, v0 );
feedback_vertex( ctx, v1, v1 );
} else {
feedback_vertex( ctx, v0, v1 );
feedback_vertex( ctx, v1, v1 );
}
swrast->StippleCounter++;
}
void _swrast_feedback_point( GLcontext *ctx, const SWvertex *v )
{
FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_POINT_TOKEN );
feedback_vertex( ctx, v, v );
}
void _swrast_select_triangle( GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1,
const SWvertex *v2)
{
if (_swrast_culltriangle( ctx, v0, v1, v2 )) {
const GLfloat zs = 1.0F / ctx->DrawBuffer->_DepthMaxF;
_mesa_update_hitflag( ctx, v0->win[2] * zs );
_mesa_update_hitflag( ctx, v1->win[2] * zs );
_mesa_update_hitflag( ctx, v2->win[2] * zs );
}
}
void _swrast_select_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 )
{
const GLfloat zs = 1.0F / ctx->DrawBuffer->_DepthMaxF;
_mesa_update_hitflag( ctx, v0->win[2] * zs );
_mesa_update_hitflag( ctx, v1->win[2] * zs );
}
void _swrast_select_point( GLcontext *ctx, const SWvertex *v )
{
const GLfloat zs = 1.0F / ctx->DrawBuffer->_DepthMaxF;
_mesa_update_hitflag( ctx, v->win[2] * zs );
}
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 1999-2004 Brian Paul 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, 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
* BRIAN PAUL 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.
*/
/* KW: Moved these here to remove knowledge of swrast from core mesa.
* Should probably pull the entire software implementation of these
* extensions into either swrast or a sister module.
*/
#include "s_context.h"
#include "s_span.h"
#include "colortab.h"
#include "convolve.h"
void
_swrast_CopyColorTable( GLcontext *ctx,
GLenum target, GLenum internalformat,
GLint x, GLint y, GLsizei width)
{
GLchan data[MAX_WIDTH][4];
struct gl_buffer_object *bufferSave;
if (!ctx->ReadBuffer->_ColorReadBuffer) {
/* no readbuffer - OK */
return;
}
/* Select buffer to read from */
_swrast_use_read_buffer(ctx);
if (width > MAX_WIDTH)
width = MAX_WIDTH;
/* read the data from framebuffer */
_swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer,
width, x, y, data );
/* Restore reading from draw buffer (the default) */
_swrast_use_draw_buffer(ctx);
/* save PBO binding */
bufferSave = ctx->Unpack.BufferObj;
ctx->Unpack.BufferObj = ctx->Array.NullBufferObj;
_mesa_ColorTable(target, internalformat, width, GL_RGBA, CHAN_TYPE, data);
/* restore PBO binding */
ctx->Unpack.BufferObj = bufferSave;
}
void
_swrast_CopyColorSubTable( GLcontext *ctx,GLenum target, GLsizei start,
GLint x, GLint y, GLsizei width)
{
GLchan data[MAX_WIDTH][4];
struct gl_buffer_object *bufferSave;
if (!ctx->ReadBuffer->_ColorReadBuffer) {
/* no readbuffer - OK */
return;
}
/* Select buffer to read from */
_swrast_use_read_buffer(ctx);
if (width > MAX_WIDTH)
width = MAX_WIDTH;
/* read the data from framebuffer */
_swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer,
width, x, y, data );
/* Restore reading from draw buffer (the default) */
_swrast_use_draw_buffer(ctx);
/* save PBO binding */
bufferSave = ctx->Unpack.BufferObj;
ctx->Unpack.BufferObj = ctx->Array.NullBufferObj;
_mesa_ColorSubTable(target, start, width, GL_RGBA, CHAN_TYPE, data);
/* restore PBO binding */
ctx->Unpack.BufferObj = bufferSave;
}
void
_swrast_CopyConvolutionFilter1D(GLcontext *ctx, GLenum target,
GLenum internalFormat,
GLint x, GLint y, GLsizei width)
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLchan rgba[MAX_CONVOLUTION_WIDTH][4];
struct gl_buffer_object *bufferSave;
if (!ctx->ReadBuffer->_ColorReadBuffer) {
/* no readbuffer - OK */
return;
}
/* Select buffer to read from */
_swrast_use_read_buffer(ctx);
RENDER_START( swrast, ctx );
/* read the data from framebuffer */
_swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer,
width, x, y, (GLchan (*)[4]) rgba );
RENDER_FINISH( swrast, ctx );
/* Restore reading from draw buffer (the default) */
_swrast_use_draw_buffer(ctx);
/* save PBO binding */
bufferSave = ctx->Unpack.BufferObj;
ctx->Unpack.BufferObj = ctx->Array.NullBufferObj;
/* store as convolution filter */
_mesa_ConvolutionFilter1D(target, internalFormat, width,
GL_RGBA, CHAN_TYPE, rgba);
/* restore PBO binding */
ctx->Unpack.BufferObj = bufferSave;
}
void
_swrast_CopyConvolutionFilter2D(GLcontext *ctx, GLenum target,
GLenum internalFormat,
GLint x, GLint y, GLsizei width, GLsizei height)
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
struct gl_pixelstore_attrib packSave;
GLchan rgba[MAX_CONVOLUTION_HEIGHT][MAX_CONVOLUTION_WIDTH][4];
GLint i;
struct gl_buffer_object *bufferSave;
if (!ctx->ReadBuffer->_ColorReadBuffer) {
/* no readbuffer - OK */
return;
}
/* Select buffer to read from */
_swrast_use_read_buffer(ctx);
RENDER_START(swrast,ctx);
/* read pixels from framebuffer */
for (i = 0; i < height; i++) {
_swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer,
width, x, y + i, (GLchan (*)[4]) rgba[i] );
}
RENDER_FINISH(swrast,ctx);
/* Restore reading from draw buffer (the default) */
_swrast_use_draw_buffer(ctx);
/*
* HACK: save & restore context state so we can store this as a
* convolution filter via the GL api. Doesn't call any callbacks
* hanging off ctx->Unpack statechanges.
*/
packSave = ctx->Unpack; /* save pixel packing params */
ctx->Unpack.Alignment = 1;
ctx->Unpack.RowLength = MAX_CONVOLUTION_WIDTH;
ctx->Unpack.SkipPixels = 0;
ctx->Unpack.SkipRows = 0;
ctx->Unpack.ImageHeight = 0;
ctx->Unpack.SkipImages = 0;
ctx->Unpack.SwapBytes = GL_FALSE;
ctx->Unpack.LsbFirst = GL_FALSE;
ctx->Unpack.BufferObj = ctx->Array.NullBufferObj;
ctx->NewState |= _NEW_PACKUNPACK;
/* save PBO binding */
bufferSave = ctx->Unpack.BufferObj;
ctx->Unpack.BufferObj = ctx->Array.NullBufferObj;
_mesa_ConvolutionFilter2D(target, internalFormat, width, height,
GL_RGBA, CHAN_TYPE, rgba);
/* restore PBO binding */
ctx->Unpack.BufferObj = bufferSave;
ctx->Unpack = packSave; /* restore pixel packing params */
ctx->NewState |= _NEW_PACKUNPACK;
}
/*
* Mesa 3-D graphics library
* Version: 6.5
*
* Copyright (C) 1999-2005 Brian Paul 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, 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
* BRIAN PAUL 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 "glheader.h"
#include "context.h"
#include "colormac.h"
#include "macros.h"
#include "nvfragprog.h"
#include "s_aaline.h"
#include "s_context.h"
#include "s_depth.h"
#include "s_feedback.h"
#include "s_lines.h"
#include "s_span.h"
/*
* Init the mask[] array to implement a line stipple.
*/
static void
compute_stipple_mask( GLcontext *ctx, GLuint len, GLubyte mask[] )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLuint i;
for (i = 0; i < len; i++) {
GLuint bit = (swrast->StippleCounter / ctx->Line.StippleFactor) & 0xf;
if ((1 << bit) & ctx->Line.StipplePattern) {
mask[i] = GL_TRUE;
}
else {
mask[i] = GL_FALSE;
}
swrast->StippleCounter++;
}
}
/*
* To draw a wide line we can simply redraw the span N times, side by side.
*/
static void
draw_wide_line( GLcontext *ctx, struct sw_span *span, GLboolean xMajor )
{
GLint width, start;
ASSERT(span->end < MAX_WIDTH);
width = (GLint) CLAMP( ctx->Line._Width, MIN_LINE_WIDTH, MAX_LINE_WIDTH );
if (width & 1)
start = width / 2;
else
start = width / 2 - 1;
if (xMajor) {
GLint *y = span->array->y;
GLuint i;
GLint w;
for (w = 0; w < width; w++) {
if (w == 0) {
for (i = 0; i < span->end; i++)
y[i] -= start;
}
else {
for (i = 0; i < span->end; i++)
y[i]++;
}
if (ctx->Visual.rgbMode)
_swrast_write_rgba_span(ctx, span);
else
_swrast_write_index_span(ctx, span);
}
}
else {
GLint *x = span->array->x;
GLuint i;
GLint w;
for (w = 0; w < width; w++) {
if (w == 0) {
for (i = 0; i < span->end; i++)
x[i] -= start;
}
else {
for (i = 0; i < span->end; i++)
x[i]++;
}
if (ctx->Visual.rgbMode)
_swrast_write_rgba_span(ctx, span);
else
_swrast_write_index_span(ctx, span);
}
}
}
/**********************************************************************/
/***** Rasterization *****/
/**********************************************************************/
/* Simple color index line (no stipple, width=1, no Z, no fog, no tex)*/
#define NAME simple_ci_line
#define INTERP_INDEX
#define RENDER_SPAN(span) _swrast_write_index_span(ctx, &span)
#include "s_linetemp.h"
/* Simple RGBA index line (no stipple, width=1, no Z, no fog, no tex)*/
#define NAME simple_rgba_line
#define INTERP_RGBA
#define RENDER_SPAN(span) _swrast_write_rgba_span(ctx, &span);
#include "s_linetemp.h"
/* Z, fog, wide, stipple color index line */
#define NAME general_ci_line
#define INTERP_INDEX
#define INTERP_Z
#define INTERP_FOG
#define RENDER_SPAN(span) \
if (ctx->Line.StippleFlag) { \
span.arrayMask |= SPAN_MASK; \
compute_stipple_mask(ctx, span.end, span.array->mask); \
} \
if (ctx->Line._Width > 1.0) { \
draw_wide_line(ctx, &span, (GLboolean)(dx > dy)); \
} \
else { \
_swrast_write_index_span(ctx, &span); \
}
#include "s_linetemp.h"
/* Z, fog, wide, stipple RGBA line */
#define NAME general_rgba_line
#define INTERP_RGBA
#define INTERP_Z
#define INTERP_FOG
#define RENDER_SPAN(span) \
if (ctx->Line.StippleFlag) { \
span.arrayMask |= SPAN_MASK; \
compute_stipple_mask(ctx, span.end, span.array->mask); \
} \
if (ctx->Line._Width > 1.0) { \
draw_wide_line(ctx, &span, (GLboolean)(dx > dy)); \
} \
else { \
_swrast_write_rgba_span(ctx, &span); \
}
#include "s_linetemp.h"
/* Single-texture line, w/ fog, Z, specular, etc. */
#define NAME textured_line
#define INTERP_RGBA
#define INTERP_Z
#define INTERP_FOG
#define INTERP_TEX
#define RENDER_SPAN(span) \
if (ctx->Line.StippleFlag) { \
span.arrayMask |= SPAN_MASK; \
compute_stipple_mask(ctx, span.end, span.array->mask); \
} \
if (ctx->Line._Width > 1.0) { \
draw_wide_line(ctx, &span, (GLboolean)(dx > dy)); \
} \
else { \
_swrast_write_rgba_span(ctx, &span); \
}
#include "s_linetemp.h"
/* Multi-texture or separate specular line, w/ fog, Z, specular, etc. */
#define NAME multitextured_line
#define INTERP_RGBA
#define INTERP_SPEC
#define INTERP_Z
#define INTERP_FOG
#define INTERP_MULTITEX
#define RENDER_SPAN(span) \
if (ctx->Line.StippleFlag) { \
span.arrayMask |= SPAN_MASK; \
compute_stipple_mask(ctx, span.end, span.array->mask); \
} \
if (ctx->Line._Width > 1.0) { \
draw_wide_line(ctx, &span, (GLboolean)(dx > dy)); \
} \
else { \
_swrast_write_rgba_span(ctx, &span); \
}
#include "s_linetemp.h"
void
_swrast_add_spec_terms_line( GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1 )
{
SWvertex *ncv0 = (SWvertex *)v0;
SWvertex *ncv1 = (SWvertex *)v1;
GLchan c[2][4];
COPY_CHAN4( c[0], ncv0->color );
COPY_CHAN4( c[1], ncv1->color );
ACC_3V( ncv0->color, ncv0->specular );
ACC_3V( ncv1->color, ncv1->specular );
SWRAST_CONTEXT(ctx)->SpecLine( ctx, ncv0, ncv1 );
COPY_CHAN4( ncv0->color, c[0] );
COPY_CHAN4( ncv1->color, c[1] );
}
#ifdef DEBUG
extern void
_mesa_print_line_function(GLcontext *ctx); /* silence compiler warning */
void
_mesa_print_line_function(GLcontext *ctx)
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
_mesa_printf("Line Func == ");
if (swrast->Line == simple_ci_line)
_mesa_printf("simple_ci_line\n");
else if (swrast->Line == simple_rgba_line)
_mesa_printf("simple_rgba_line\n");
else if (swrast->Line == general_ci_line)
_mesa_printf("general_ci_line\n");
else if (swrast->Line == general_rgba_line)
_mesa_printf("general_rgba_line\n");
else if (swrast->Line == textured_line)
_mesa_printf("textured_line\n");
else if (swrast->Line == multitextured_line)
_mesa_printf("multitextured_line\n");
else
_mesa_printf("Driver func %p\n", (void *(*)()) swrast->Line);
}
#endif
#ifdef DEBUG
/* record the current line function name */
static const char *lineFuncName = NULL;
#define USE(lineFunc) \
do { \
lineFuncName = #lineFunc; \
/*_mesa_printf("%s\n", lineFuncName);*/ \
swrast->Line = lineFunc; \
} while (0)
#else
#define USE(lineFunc) swrast->Line = lineFunc
#endif
/*
* Determine which line drawing function to use given the current
* rendering context.
*
* Please update the summary flag _SWRAST_NEW_LINE if you add or remove
* tests to this code.
*/
void
_swrast_choose_line( GLcontext *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLboolean rgbmode = ctx->Visual.rgbMode;
if (ctx->RenderMode == GL_RENDER) {
if (ctx->Line.SmoothFlag) {
/* antialiased lines */
_swrast_choose_aa_line_function(ctx);
ASSERT(swrast->Line);
}
else if (ctx->Texture._EnabledCoordUnits) {
/* textured lines */
if (ctx->Texture._EnabledCoordUnits > 0x1
|| NEED_SECONDARY_COLOR(ctx)) {
/* multi-texture and/or separate specular color */
USE(multitextured_line);
}
else {
USE(textured_line);
}
}
else if (ctx->Depth.Test || swrast->_FogEnabled || ctx->Line._Width != 1.0
|| ctx->Line.StippleFlag) {
/* no texture, but Z, fog, width>1, stipple, etc. */
if (rgbmode)
USE(general_rgba_line);
else
USE(general_ci_line);
}
else {
/* simplest lines */
if (rgbmode)
USE(simple_rgba_line);
else
USE(simple_ci_line);
}
}
else if (ctx->RenderMode == GL_FEEDBACK) {
USE(_swrast_feedback_line);
}
else {
ASSERT(ctx->RenderMode == GL_SELECT);
USE(_swrast_select_line);
}
/*_mesa_print_line_function(ctx);*/
}
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 1999-2005 Brian Paul 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, 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
* BRIAN PAUL 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 "glheader.h"
#include "context.h"
#include "imports.h"
#include "macros.h"
#include "s_context.h"
#include "s_logic.h"
#include "s_span.h"
#define LOGIC_OP_LOOP(MODE) \
do { \
GLuint i; \
switch (MODE) { \
case GL_CLEAR: \
for (i = 0; i < n; i++) { \
if (mask[i]) { \
src[i] = 0; \
} \
} \
break; \
case GL_SET: \
for (i = 0; i < n; i++) { \
if (mask[i]) { \
src[i] = ~0; \
} \
} \
break; \
case GL_COPY: \
/* do nothing */ \
break; \
case GL_COPY_INVERTED: \
for (i = 0; i < n; i++) { \
if (mask[i]) { \
src[i] = ~src[i]; \
} \
} \
break; \
case GL_NOOP: \
for (i = 0; i < n; i++) { \
if (mask[i]) { \
src[i] = dest[i]; \
} \
} \
break; \
case GL_INVERT: \
for (i = 0; i < n; i++) { \
if (mask[i]) { \
src[i] = ~dest[i]; \
} \
} \
break; \
case GL_AND: \
for (i = 0; i < n; i++) { \
if (mask[i]) { \
src[i] &= dest[i]; \
} \
} \
break; \
case GL_NAND: \
for (i = 0; i < n; i++) { \
if (mask[i]) { \
src[i] = ~(src[i] & dest[i]); \
} \
} \
break; \
case GL_OR: \
for (i = 0; i < n; i++) { \
if (mask[i]) { \
src[i] |= dest[i]; \
} \
} \
break; \
case GL_NOR: \
for (i = 0; i < n; i++) { \
if (mask[i]) { \
src[i] = ~(src[i] | dest[i]); \
} \
} \
break; \
case GL_XOR: \
for (i = 0; i < n; i++) { \
if (mask[i]) { \
src[i] ^= dest[i]; \
} \
} \
break; \
case GL_EQUIV: \
for (i = 0; i < n; i++) { \
if (mask[i]) { \
src[i] = ~(src[i] ^ dest[i]); \
} \
} \
break; \
case GL_AND_REVERSE: \
for (i = 0; i < n; i++) { \
if (mask[i]) { \
src[i] = src[i] & ~dest[i]; \
} \
} \
break; \
case GL_AND_INVERTED: \
for (i = 0; i < n; i++) { \
if (mask[i]) { \
src[i] = ~src[i] & dest[i]; \
} \
} \
break; \
case GL_OR_REVERSE: \
for (i = 0; i < n; i++) { \
if (mask[i]) { \
src[i] = src[i] | ~dest[i]; \
} \
} \
break; \
case GL_OR_INVERTED: \
for (i = 0; i < n; i++) { \
if (mask[i]) { \
src[i] = ~src[i] | dest[i]; \
} \
} \
break; \
default: \
_mesa_problem(ctx, "bad logicop mode");\
} \
} while (0)
static void
logicop_ubyte(GLcontext *ctx, GLuint n, GLubyte src[], const GLubyte dest[],
const GLubyte mask[])
{
LOGIC_OP_LOOP(ctx->Color.LogicOp);
}
static void
logicop_ushort(GLcontext *ctx, GLuint n, GLushort src[], const GLushort dest[],
const GLubyte mask[])
{
LOGIC_OP_LOOP(ctx->Color.LogicOp);
}
static void
logicop_uint(GLcontext *ctx, GLuint n, GLuint src[], const GLuint dest[],
const GLubyte mask[])
{
LOGIC_OP_LOOP(ctx->Color.LogicOp);
}
/*
* Apply the current logic operator to a span of CI pixels. This is only
* used if the device driver can't do logic ops.
*/
void
_swrast_logicop_ci_span(GLcontext *ctx, struct gl_renderbuffer *rb,
const struct sw_span *span, GLuint index[])
{
GLuint dest[MAX_WIDTH];
ASSERT(span->end < MAX_WIDTH);
ASSERT(rb->DataType == GL_UNSIGNED_INT);
/* Read dest values from frame buffer */
if (span->arrayMask & SPAN_XY) {
_swrast_get_values(ctx, rb, span->end, span->array->x, span->array->y,
dest, sizeof(GLuint));
}
else {
rb->GetRow(ctx, rb, span->end, span->x, span->y, dest);
}
logicop_uint(ctx, span->end, index, dest, span->array->mask);
}
/**
* Apply the current logic operator to a span of RGBA pixels.
* We can handle horizontal runs of pixels (spans) or arrays of x/y
* pixel coordinates.
*/
void
_swrast_logicop_rgba_span(GLcontext *ctx, struct gl_renderbuffer *rb,
const struct sw_span *span, GLchan rgba[][4])
{
GLchan dest[MAX_WIDTH][4];
ASSERT(span->end < MAX_WIDTH);
ASSERT(span->arrayMask & SPAN_RGBA);
ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
if (span->arrayMask & SPAN_XY) {
_swrast_get_values(ctx, rb, span->end, span->array->x, span->array->y,
dest, 4 * sizeof(GLchan));
}
else {
_swrast_read_rgba_span(ctx, rb, span->end, span->x, span->y, dest);
}
/* XXX make this a runtime test */
#if CHAN_TYPE == GL_UNSIGNED_BYTE
/* treat 4*GLubyte as GLuint */
logicop_uint(ctx, span->end, (GLuint *) rgba,
(const GLuint *) dest, span->array->mask);
#elif CHAN_TYPE == GL_UNSIGNED_SHORT
logicop_ushort(ctx, 4 * span->end, (GLushort *) rgba,
(const GLushort *) dest, span->array->mask);
#elif CHAN_TYPE == GL_FLOAT
logicop_uint(ctx, 4 * span->end, (GLuint *) rgba,
(const GLuint *) dest, span->array->mask);
#endif
(void) logicop_ubyte;
(void) logicop_ushort;
(void) logicop_uint;
}
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 1999-2005 Brian Paul 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, 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
* BRIAN PAUL 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.
*/
/*
* Implement the effect of glColorMask and glIndexMask in software.
*/
#include "glheader.h"
#include "enums.h"
#include "macros.h"
#include "s_context.h"
#include "s_masking.h"
#include "s_span.h"
void
_swrast_mask_rgba_span(GLcontext *ctx, struct gl_renderbuffer *rb,
const struct sw_span *span, GLchan rgba[][4])
{
GLchan dest[MAX_WIDTH][4];
#if CHAN_BITS == 8
GLuint srcMask = *((GLuint*)ctx->Color.ColorMask);
GLuint dstMask = ~srcMask;
GLuint *rgba32 = (GLuint *) rgba;
GLuint *dest32 = (GLuint *) dest;
#else
const GLboolean rMask = ctx->Color.ColorMask[RCOMP];
const GLboolean gMask = ctx->Color.ColorMask[GCOMP];
const GLboolean bMask = ctx->Color.ColorMask[BCOMP];
const GLboolean aMask = ctx->Color.ColorMask[ACOMP];
#endif
const GLuint n = span->end;
GLuint i;
ASSERT(n < MAX_WIDTH);
ASSERT(span->arrayMask & SPAN_RGBA);
if (span->arrayMask & SPAN_XY) {
_swrast_get_values(ctx, rb, n, span->array->x, span->array->y,
dest, 4 * sizeof(GLchan));
}
else {
_swrast_read_rgba_span(ctx, rb, n, span->x, span->y, dest);
}
#if CHAN_BITS == 8
for (i = 0; i < n; i++) {
rgba32[i] = (rgba32[i] & srcMask) | (dest32[i] & dstMask);
}
#else
for (i = 0; i < n; i++) {
if (!rMask) rgba[i][RCOMP] = dest[i][RCOMP];
if (!gMask) rgba[i][GCOMP] = dest[i][GCOMP];
if (!bMask) rgba[i][BCOMP] = dest[i][BCOMP];
if (!aMask) rgba[i][ACOMP] = dest[i][ACOMP];
}
#endif
}
/*
* Apply glColorMask to a span of RGBA pixels.
*/
void
_swrast_mask_rgba_array(GLcontext *ctx, struct gl_renderbuffer *rb,
GLuint n, GLint x, GLint y, GLchan rgba[][4])
{
GLchan dest[MAX_WIDTH][4];
GLuint i;
#if CHAN_BITS == 8
GLuint srcMask = *((GLuint*)ctx->Color.ColorMask);
GLuint dstMask = ~srcMask;
GLuint *rgba32 = (GLuint *) rgba;
GLuint *dest32 = (GLuint *) dest;
_swrast_read_rgba_span( ctx, rb, n, x, y, dest );
for (i = 0; i < n; i++) {
rgba32[i] = (rgba32[i] & srcMask) | (dest32[i] & dstMask);
}
#else
const GLint rMask = ctx->Color.ColorMask[RCOMP];
const GLint gMask = ctx->Color.ColorMask[GCOMP];
const GLint bMask = ctx->Color.ColorMask[BCOMP];
const GLint aMask = ctx->Color.ColorMask[ACOMP];
_swrast_read_rgba_span( ctx, rb, n, x, y, dest );
for (i = 0; i < n; i++) {
if (!rMask) rgba[i][RCOMP] = dest[i][RCOMP];
if (!gMask) rgba[i][GCOMP] = dest[i][GCOMP];
if (!bMask) rgba[i][BCOMP] = dest[i][BCOMP];
if (!aMask) rgba[i][ACOMP] = dest[i][ACOMP];
}
#endif
}
void
_swrast_mask_ci_span(GLcontext *ctx, struct gl_renderbuffer *rb,
const struct sw_span *span, GLuint index[])
{
const GLuint srcMask = ctx->Color.IndexMask;
const GLuint dstMask = ~srcMask;
GLuint dest[MAX_WIDTH];
GLuint i;
ASSERT(span->arrayMask & SPAN_INDEX);
ASSERT(span->end <= MAX_WIDTH);
ASSERT(rb->DataType == GL_UNSIGNED_INT);
if (span->arrayMask & SPAN_XY) {
_swrast_get_values(ctx, rb, span->end, span->array->x, span->array->y,
dest, sizeof(GLuint));
}
else {
_swrast_read_index_span(ctx, rb, span->end, span->x, span->y, dest);
}
for (i = 0; i < span->end; i++) {
index[i] = (index[i] & srcMask) | (dest[i] & dstMask);
}
}
/*
* Apply glIndexMask to an array of CI pixels.
*/
void
_swrast_mask_ci_array(GLcontext *ctx, struct gl_renderbuffer *rb,
GLuint n, GLint x, GLint y, GLuint index[])
{
const GLuint srcMask = ctx->Color.IndexMask;
const GLuint dstMask = ~srcMask;
GLuint dest[MAX_WIDTH];
GLuint i;
_swrast_read_index_span(ctx, rb, n, x, y, dest);
for (i=0;i<n;i++) {
index[i] = (index[i] & srcMask) | (dest[i] & dstMask);
}
}
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 1999-2004 Brian Paul 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, 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
* BRIAN PAUL 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.
*/
/*
* This file implements both the GL_SGIX_pixel_texture and
* GL_SIGS_pixel_texture extensions. Luckily, they pretty much
* overlap in functionality so we use the same state variables
* and execution code for both.
*/
#include "glheader.h"
#include "colormac.h"
#include "imports.h"
#include "s_context.h"
#include "s_pixeltex.h"
#include "s_texture.h"
/*
* Convert RGBA values into strq texture coordinates.
*/
static void
pixeltexgen(GLcontext *ctx, GLuint n, const GLchan rgba[][4],
GLfloat texcoord[][4])
{
if (ctx->Pixel.FragmentRgbSource == GL_CURRENT_RASTER_COLOR) {
GLuint i;
for (i = 0; i < n; i++) {
texcoord[i][0] = ctx->Current.RasterColor[RCOMP];
texcoord[i][1] = ctx->Current.RasterColor[GCOMP];
texcoord[i][2] = ctx->Current.RasterColor[BCOMP];
}
}
else {
GLuint i;
ASSERT(ctx->Pixel.FragmentRgbSource == GL_PIXEL_GROUP_COLOR_SGIS);
for (i = 0; i < n; i++) {
texcoord[i][0] = CHAN_TO_FLOAT(rgba[i][RCOMP]);
texcoord[i][1] = CHAN_TO_FLOAT(rgba[i][GCOMP]);
texcoord[i][2] = CHAN_TO_FLOAT(rgba[i][BCOMP]);
}
}
if (ctx->Pixel.FragmentAlphaSource == GL_CURRENT_RASTER_COLOR) {
GLuint i;
for (i = 0; i < n; i++) {
texcoord[i][3] = ctx->Current.RasterColor[ACOMP];
}
}
else {
GLuint i;
ASSERT(ctx->Pixel.FragmentAlphaSource == GL_PIXEL_GROUP_COLOR_SGIS);
for (i = 0; i < n; i++) {
texcoord[i][3] = CHAN_TO_FLOAT(rgba[i][ACOMP]);
}
}
}
/*
* Used by glDraw/CopyPixels: the incoming image colors are treated
* as texture coordinates. Use those coords to texture the image.
* This is for GL_SGIS_pixel_texture / GL_SGIX_pixel_texture.
*/
void
_swrast_pixel_texture(GLcontext *ctx, struct sw_span *span)
{
GLuint unit;
ASSERT(!(span->arrayMask & SPAN_TEXTURE));
span->arrayMask |= SPAN_TEXTURE;
span->interpMask &= ~SPAN_TEXTURE;
/* convert colors into texture coordinates */
pixeltexgen( ctx, span->end,
(const GLchan (*)[4]) span->array->rgba,
span->array->texcoords[0] );
/* copy the new texture units for all enabled units */
for (unit = 1; unit < ctx->Const.MaxTextureUnits; unit++) {
if (ctx->Texture.Unit[unit]._ReallyEnabled) {
MEMCPY( span->array->texcoords[unit], span->array->texcoords[0],
span->end * 4 * sizeof(GLfloat) );
}
}
}
/*
* Mesa 3-D graphics library
* Version: 6.1
*
* Copyright (C) 1999-2004 Brian Paul 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, 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
* BRIAN PAUL 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 "glheader.h"
#include "colormac.h"
#include "context.h"
#include "macros.h"
#include "texstate.h"
#include "s_context.h"
#include "s_feedback.h"
#include "s_points.h"
#include "s_span.h"
#define RGBA 0x1
#define INDEX 0x2
#define SMOOTH 0x4
#define TEXTURE 0x8
#define SPECULAR 0x10
#define LARGE 0x20
#define ATTENUATE 0x40
#define SPRITE 0x80
/*
* CI points with size == 1.0
*/
#define FLAGS (INDEX)
#define NAME size1_ci_point
#include "s_pointtemp.h"
/*
* General CI points.
*/
#define FLAGS (INDEX | LARGE)
#define NAME general_ci_point
#include "s_pointtemp.h"
/*
* Antialiased CI points.
*/
#define FLAGS (INDEX | SMOOTH)
#define NAME antialiased_ci_point
#include "s_pointtemp.h"
/*
* Distance attenuated, general CI points.
*/
#define FLAGS (INDEX | ATTENUATE)
#define NAME atten_general_ci_point
#include "s_pointtemp.h"
/*
* RGBA points with size == 1.0
*/
#define FLAGS (RGBA)
#define NAME size1_rgba_point
#include "s_pointtemp.h"
/*
* General RGBA points.
*/
#define FLAGS (RGBA | LARGE)
#define NAME general_rgba_point
#include "s_pointtemp.h"
/*
* Antialiased RGBA points.
*/
#define FLAGS (RGBA | SMOOTH)
#define NAME antialiased_rgba_point
#include "s_pointtemp.h"
/*
* Textured RGBA points.
*/
#define FLAGS (RGBA | LARGE | TEXTURE | SPECULAR)
#define NAME textured_rgba_point
#include "s_pointtemp.h"
/*
* Antialiased points with texture mapping.
*/
#define FLAGS (RGBA | SMOOTH | TEXTURE | SPECULAR)
#define NAME antialiased_tex_rgba_point
#include "s_pointtemp.h"
/*
* Distance attenuated, general RGBA points.
*/
#define FLAGS (RGBA | ATTENUATE)
#define NAME atten_general_rgba_point
#include "s_pointtemp.h"
/*
* Distance attenuated, textured RGBA points.
*/
#define FLAGS (RGBA | ATTENUATE | TEXTURE | SPECULAR)
#define NAME atten_textured_rgba_point
#include "s_pointtemp.h"
/*
* Distance attenuated, antialiased points with or without texture mapping.
*/
#define FLAGS (RGBA | ATTENUATE | TEXTURE | SMOOTH)
#define NAME atten_antialiased_rgba_point
#include "s_pointtemp.h"
/*
* Sprite (textured point)
*/
#define FLAGS (RGBA | SPRITE | SPECULAR)
#define NAME sprite_point
#include "s_pointtemp.h"
#define FLAGS (RGBA | SPRITE | SPECULAR | ATTENUATE)
#define NAME atten_sprite_point
#include "s_pointtemp.h"
void _swrast_add_spec_terms_point( GLcontext *ctx,
const SWvertex *v0 )
{
SWvertex *ncv0 = (SWvertex *)v0;
GLchan c[1][4];
COPY_CHAN4( c[0], ncv0->color );
ACC_3V( ncv0->color, ncv0->specular );
SWRAST_CONTEXT(ctx)->SpecPoint( ctx, ncv0 );
COPY_CHAN4( ncv0->color, c[0] );
}
/* record the current point function name */
#ifdef DEBUG
static const char *pntFuncName = NULL;
#define USE(pntFunc) \
do { \
pntFuncName = #pntFunc; \
/*printf("%s\n", pntFuncName);*/ \
swrast->Point = pntFunc; \
} while (0)
#else
#define USE(pntFunc) swrast->Point = pntFunc
#endif
/*
* Examine the current context to determine which point drawing function
* should be used.
*/
void
_swrast_choose_point( GLcontext *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLboolean rgbMode = ctx->Visual.rgbMode;
if (ctx->RenderMode==GL_RENDER) {
if (ctx->Point.PointSprite) {
/* GL_ARB_point_sprite / GL_NV_point_sprite */
/* XXX this might not be good enough */
if (ctx->Point._Attenuated)
USE(atten_sprite_point);
else
USE(sprite_point);
}
else if (ctx->Point.SmoothFlag) {
/* Smooth points */
if (rgbMode) {
if (ctx->Point._Attenuated || ctx->VertexProgram.PointSizeEnabled) {
USE(atten_antialiased_rgba_point);
}
else if (ctx->Texture._EnabledCoordUnits) {
USE(antialiased_tex_rgba_point);
}
else {
USE(antialiased_rgba_point);
}
}
else {
USE(antialiased_ci_point);
}
}
else if (ctx->Point._Attenuated || ctx->VertexProgram.PointSizeEnabled) {
if (rgbMode) {
if (ctx->Texture._EnabledCoordUnits) {
if (ctx->Point.SmoothFlag) {
USE(atten_antialiased_rgba_point);
}
else {
USE(atten_textured_rgba_point);
}
}
else {
USE(atten_general_rgba_point);
}
}
else {
/* ci, atten */
USE(atten_general_ci_point);
}
}
else if (ctx->Texture._EnabledCoordUnits && rgbMode) {
/* textured */
USE(textured_rgba_point);
}
else if (ctx->Point._Size != 1.0) {
/* large points */
if (rgbMode) {
USE(general_rgba_point);
}
else {
USE(general_ci_point);
}
}
else {
/* single pixel points */
if (rgbMode) {
USE(size1_rgba_point);
}
else {
USE(size1_ci_point);
}
}
}
else if (ctx->RenderMode==GL_FEEDBACK) {
USE(_swrast_feedback_point);
}
else {
/* GL_SELECT mode */
USE(_swrast_select_point);
}
}
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 1999-2005 Brian Paul 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, 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
* BRIAN PAUL 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.
*/
/*
* Templates for the span/pixel-array write/read functions called via
* the gl_renderbuffer's GetRow, GetValues, PutRow, PutMonoRow, PutValues
* and PutMonoValues functions.
*
* Define the following macros before including this file:
* NAME(PREFIX) to generate the function name
* FORMAT must be either GL_RGBA, GL_RGBA8 or GL_COLOR_INDEX8_EXT
* SPAN_VARS to declare any local variables
* INIT_PIXEL_PTR(P, X, Y) to initialize a pointer to a pixel
* INC_PIXEL_PTR(P) to increment a pixel pointer by one pixel
* STORE_PIXEL(DST, X, Y, VALUE) to store pixel values in buffer
* FETCH_PIXEL(DST, SRC) to fetch pixel values from buffer
*
* Note that in the STORE_PIXEL macros, we also pass in the (X,Y) coordinates
* for the pixels to be stored. This is useful when dithering and probably
* ignored otherwise.
*/
#include "macros.h"
static void
NAME(get_row)( GLcontext *ctx, struct gl_renderbuffer *rb,
GLuint count, GLint x, GLint y, void *values )
{
#ifdef SPAN_VARS
SPAN_VARS
#endif
#if FORMAT == GL_RGBA
GLchan (*dest)[4] = (GLchan (*)[4]) values;
#elif FORMAT == GL_RGBA8
GLubyte (*dest)[4] = (GLubyte (*)[4]) values;
#elif FORMAT == GL_COLOR_INDEX8_EXT
GLubyte *dest = (GLubyte *) values;
#else
#error FORMAT must be set!!!!
#endif
GLuint i;
INIT_PIXEL_PTR(pixel, x, y);
for (i = 0; i < count; i++) {
FETCH_PIXEL(dest[i], pixel);
INC_PIXEL_PTR(pixel);
}
}
static void
NAME(get_values)( GLcontext *ctx, struct gl_renderbuffer *rb,
GLuint count, const GLint x[], const GLint y[], void *values )
{
#ifdef SPAN_VARS
SPAN_VARS
#endif
#if FORMAT == GL_RGBA
GLchan (*dest)[4] = (GLchan (*)[4]) values;
#elif FORMAT == GL_RGBA8
GLubyte (*dest)[4] = (GLubyte (*)[4]) values;
#elif FORMAT == GL_COLOR_INDEX8_EXT
GLubyte *dest = (GLubyte *) values;
#endif
GLuint i;
for (i = 0; i < count; i++) {
INIT_PIXEL_PTR(pixel, x[i], y[i]);
FETCH_PIXEL(dest[i], pixel);
}
}
static void
NAME(put_row)( GLcontext *ctx, struct gl_renderbuffer *rb,
GLuint count, GLint x, GLint y,
const void *values, const GLubyte mask[] )
{
#ifdef SPAN_VARS
SPAN_VARS
#endif
#if FORMAT == GL_RGBA
const GLchan (*src)[4] = (const GLchan (*)[4]) values;
#elif FORMAT == GL_RGBA8
const GLubyte (*src)[4] = (const GLubyte (*)[4]) values;
#elif FORMAT == GL_COLOR_INDEX8_EXT
const GLubyte (*src)[1] = (const GLubyte (*)[1]) values;
#endif
GLuint i;
INIT_PIXEL_PTR(pixel, x, y);
if (mask) {
for (i = 0; i < count; i++) {
if (mask[i]) {
STORE_PIXEL(pixel, x + i, y, src[i]);
}
INC_PIXEL_PTR(pixel);
}
}
else {
for (i = 0; i < count; i++) {
STORE_PIXEL(pixel, x + i, y, src[i]);
INC_PIXEL_PTR(pixel);
}
}
}
#if (FORMAT == GL_RGBA) || (FORMAT == GL_RGBA8)
static void
NAME(put_row_rgb)( GLcontext *ctx, struct gl_renderbuffer *rb,
GLuint count, GLint x, GLint y,
const void *values, const GLubyte mask[] )
{
#ifdef SPAN_VARS
SPAN_VARS
#endif
#if FORMAT == GL_RGBA
const GLchan (*src)[3] = (const GLchan (*)[3]) values;
#elif FORMAT == GL_RGBA8
const GLubyte (*src)[3] = (const GLubyte (*)[3]) values;
#else
#error bad format
#endif
GLuint i;
INIT_PIXEL_PTR(pixel, x, y);
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
#ifdef STORE_PIXEL_RGB
STORE_PIXEL_RGB(pixel, x + i, y, src[i]);
#else
STORE_PIXEL(pixel, x + i, y, src[i]);
#endif
}
INC_PIXEL_PTR(pixel);
}
}
#endif
static void
NAME(put_mono_row)( GLcontext *ctx, struct gl_renderbuffer *rb,
GLuint count, GLint x, GLint y,
const void *value, const GLubyte mask[] )
{
#ifdef SPAN_VARS
SPAN_VARS
#endif
#if FORMAT == GL_RGBA
const GLchan *src = (const GLchan *) value;
#elif FORMAT == GL_RGBA8
const GLubyte *src = (const GLubyte *) value;
#elif FORMAT == GL_COLOR_INDEX8_EXT
const GLubyte *src = (const GLubyte *) value;
#endif
GLuint i;
INIT_PIXEL_PTR(pixel, x, y);
if (mask) {
for (i = 0; i < count; i++) {
if (mask[i]) {
STORE_PIXEL(pixel, x + i, y, src);
}
INC_PIXEL_PTR(pixel);
}
}
else {
for (i = 0; i < count; i++) {
STORE_PIXEL(pixel, x + i, y, src);
INC_PIXEL_PTR(pixel);
}
}
}
static void
NAME(put_values)( GLcontext *ctx, struct gl_renderbuffer *rb,
GLuint count, const GLint x[], const GLint y[],
const void *values, const GLubyte mask[] )
{
#ifdef SPAN_VARS
SPAN_VARS
#endif
#if FORMAT == GL_RGBA
const GLchan (*src)[4] = (const GLchan (*)[4]) values;
#elif FORMAT == GL_RGBA8
const GLubyte (*src)[4] = (const GLubyte (*)[4]) values;
#elif FORMAT == GL_COLOR_INDEX8_EXT
const GLubyte (*src)[1] = (const GLubyte (*)[1]) values;
#endif
GLuint i;
ASSERT(mask);
for (i = 0; i < count; i++) {
if (mask[i]) {
INIT_PIXEL_PTR(pixel, x[i], y[i]);
STORE_PIXEL(pixel, x[i], y[i], src[i]);
}
}
}
static void
NAME(put_mono_values)( GLcontext *ctx, struct gl_renderbuffer *rb,
GLuint count, const GLint x[], const GLint y[],
const void *value, const GLubyte mask[] )
{
#ifdef SPAN_VARS
SPAN_VARS
#endif
#if FORMAT == GL_RGBA
const GLchan *src = (const GLchan *) value;
#elif FORMAT == GL_RGBA8
const GLubyte *src = (const GLubyte *) value;
#elif FORMAT == GL_COLOR_INDEX8_EXT
const GLubyte *src = (const GLubyte *) value;
#endif
GLuint i;
ASSERT(mask);
for (i = 0; i < count; i++) {
if (mask[i]) {
INIT_PIXEL_PTR(pixel, x[i], y[i]);
STORE_PIXEL(pixel, x[i], y[i], src);
}
}
}
#undef NAME
#undef SPAN_VARS
#undef INIT_PIXEL_PTR
#undef INC_PIXEL_PTR
#undef STORE_PIXEL
#undef STORE_PIXEL_RGB
#undef FETCH_PIXEL
#undef FORMAT
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 1999-2005 Brian Paul 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, 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
* BRIAN PAUL 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 swrast/swrast.h
* \brief Public interface to the software rasterization functions.
* \author Keith Whitwell <keith@tungstengraphics.com>
*/
#ifndef SWRAST_H
#define SWRAST_H
#include "mtypes.h"
/**
* \struct SWvertex
* \brief Data-structure to handle vertices in the software rasterizer.
*
* The software rasterizer now uses this format for vertices. Thus a
* 'RasterSetup' stage or other translation is required between the
* tnl module and the swrast rasterization functions. This serves to
* isolate the swrast module from the internals of the tnl module, and
* improve its usefulness as a fallback mechanism for hardware
* drivers.
*
* Full software drivers:
* - Register the rastersetup and triangle functions from
* utils/software_helper.
* - On statechange, update the rasterization pointers in that module.
*
* Rasterization hardware drivers:
* - Keep native rastersetup.
* - Implement native twoside,offset and unfilled triangle setup.
* - Implement a translator from native vertices to swrast vertices.
* - On partial fallback (mix of accelerated and unaccelerated
* prims), call a pass-through function which translates native
* vertices to SWvertices and calls the appropriate swrast function.
* - On total fallback (vertex format insufficient for state or all
* primitives unaccelerated), hook in swrast_setup instead.
*/
typedef struct {
/** win[0], win[1] are the screen-coords of SWvertex.
* win[2] is the z-buffer coord (if 16-bit Z buffer, in range [0,65535]).
* win[3] is 1/w where w is the clip-space W coord. This is the value
* that clip{XYZ} were multiplied by to get ndc{XYZ}.
*/
GLfloat win[4];
GLfloat texcoord[MAX_TEXTURE_COORD_UNITS][4];
GLchan color[4];
GLchan specular[4];
GLfloat fog;
GLfloat index;
GLfloat pointSize;
} SWvertex;
struct swrast_device_driver;
/* These are the public-access functions exported from swrast.
*/
extern void
_swrast_use_read_buffer( GLcontext *ctx );
extern void
_swrast_use_draw_buffer( GLcontext *ctx );
extern GLboolean
_swrast_CreateContext( GLcontext *ctx );
extern void
_swrast_DestroyContext( GLcontext *ctx );
/* Get a (non-const) reference to the device driver struct for swrast.
*/
extern struct swrast_device_driver *
_swrast_GetDeviceDriverReference( GLcontext *ctx );
extern void
_swrast_Bitmap( GLcontext *ctx,
GLint px, GLint py,
GLsizei width, GLsizei height,
const struct gl_pixelstore_attrib *unpack,
const GLubyte *bitmap );
extern void
_swrast_CopyPixels( GLcontext *ctx,
GLint srcx, GLint srcy,
GLint destx, GLint desty,
GLsizei width, GLsizei height,
GLenum type );
extern void
_swrast_DrawPixels( GLcontext *ctx,
GLint x, GLint y,
GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels );
extern void
_swrast_ReadPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *unpack,
GLvoid *pixels );
extern void
_swrast_Clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
GLint x, GLint y, GLint width, GLint height );
extern void
_swrast_Accum( GLcontext *ctx, GLenum op,
GLfloat value, GLint xpos, GLint ypos,
GLint width, GLint height );
extern void
_swrast_DrawBuffer( GLcontext *ctx, GLenum mode );
extern void
_swrast_DrawBuffers( GLcontext *ctx, GLsizei n, const GLenum *buffers );
/* Reset the stipple counter
*/
extern void
_swrast_ResetLineStipple( GLcontext *ctx );
/* These will always render the correct point/line/triangle for the
* current state.
*
* For flatshaded primitives, the provoking vertex is the final one.
*/
extern void
_swrast_Point( GLcontext *ctx, const SWvertex *v );
extern void
_swrast_Line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 );
extern void
_swrast_Triangle( GLcontext *ctx, const SWvertex *v0,
const SWvertex *v1, const SWvertex *v2 );
extern void
_swrast_Quad( GLcontext *ctx,
const SWvertex *v0, const SWvertex *v1,
const SWvertex *v2, const SWvertex *v3);
extern void
_swrast_flush( GLcontext *ctx );
extern void
_swrast_render_primitive( GLcontext *ctx, GLenum mode );
extern void
_swrast_render_start( GLcontext *ctx );
extern void
_swrast_render_finish( GLcontext *ctx );
/* Tell the software rasterizer about core state changes.
*/
extern void
_swrast_InvalidateState( GLcontext *ctx, GLuint new_state );
/* Configure software rasterizer to match hardware rasterizer characteristics:
*/
extern void
_swrast_allow_vertex_fog( GLcontext *ctx, GLboolean value );
extern void
_swrast_allow_pixel_fog( GLcontext *ctx, GLboolean value );
/* Debug:
*/
extern void
_swrast_print_vertex( GLcontext *ctx, const SWvertex *v );
/*
* Imaging fallbacks (a better solution should be found, perhaps
* moving all the imaging fallback code to a new module)
*/
extern void
_swrast_CopyConvolutionFilter2D(GLcontext *ctx, GLenum target,
GLenum internalFormat,
GLint x, GLint y, GLsizei width,
GLsizei height);
extern void
_swrast_CopyConvolutionFilter1D(GLcontext *ctx, GLenum target,
GLenum internalFormat,
GLint x, GLint y, GLsizei width);
extern void
_swrast_CopyColorSubTable( GLcontext *ctx,GLenum target, GLsizei start,
GLint x, GLint y, GLsizei width);
extern void
_swrast_CopyColorTable( GLcontext *ctx,
GLenum target, GLenum internalformat,
GLint x, GLint y, GLsizei width);
/*
* Texture fallbacks. Could also live in a new module
* with the rest of the texture store fallbacks?
*/
extern void
_swrast_copy_teximage1d(GLcontext *ctx, GLenum target, GLint level,
GLenum internalFormat,
GLint x, GLint y, GLsizei width, GLint border);
extern void
_swrast_copy_teximage2d(GLcontext *ctx, GLenum target, GLint level,
GLenum internalFormat,
GLint x, GLint y, GLsizei width, GLsizei height,
GLint border);
extern void
_swrast_copy_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
GLint xoffset, GLint x, GLint y, GLsizei width);
extern void
_swrast_copy_texsubimage2d(GLcontext *ctx,
GLenum target, GLint level,
GLint xoffset, GLint yoffset,
GLint x, GLint y, GLsizei width, GLsizei height);
extern void
_swrast_copy_texsubimage3d(GLcontext *ctx,
GLenum target, GLint level,
GLint xoffset, GLint yoffset, GLint zoffset,
GLint x, GLint y, GLsizei width, GLsizei height);
/* The driver interface for the software rasterizer.
* Unless otherwise noted, all functions are mandatory.
*/
struct swrast_device_driver {
#if OLD_RENDERBUFFER
void (*SetBuffer)(GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit);
/*
* Specifies the current color buffer for span/pixel writing/reading.
* buffer indicates which window to write to / read from. Normally,
* this'll be the buffer currently bound to the context, but it doesn't
* have to be!
* bufferBit indicates which color buffer, exactly one of:
* DD_FRONT_LEFT_BIT - this buffer always exists
* DD_BACK_LEFT_BIT - when double buffering
* DD_FRONT_RIGHT_BIT - when using stereo
* DD_BACK_RIGHT_BIT - when using stereo and double buffering
* DD_AUXn_BIT - if aux buffers are implemented
*/
#endif
/***
*** Functions for synchronizing access to the framebuffer:
***/
void (*SpanRenderStart)(GLcontext *ctx);
void (*SpanRenderFinish)(GLcontext *ctx);
/* OPTIONAL.
*
* Called before and after all rendering operations, including DrawPixels,
* ReadPixels, Bitmap, span functions, and CopyTexImage, etc commands.
* These are a suitable place for grabbing/releasing hardware locks.
*
* NOTE: The swrast triangle/line/point routines *DO NOT* call
* these functions. Locking in that case must be organized by the
* driver by other mechanisms.
*/
};
#endif
/*
* Mesa 3-D graphics library
* Version: 6.1
*
* Copyright (C) 1999-2004 Brian Paul 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, 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
* BRIAN PAUL 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.
*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*/
#include "glheader.h"
#include "imports.h"
#include "colormac.h"
#include "ss_context.h"
#include "ss_triangle.h"
#include "swrast_setup.h"
#include "tnl/tnl.h"
#include "tnl/t_context.h"
#include "tnl/t_pipeline.h"
#include "tnl/t_vertex.h"
/* Need to check lighting state and vertex program state to know
* if two-sided lighting is in effect.
*/
#define _SWSETUP_NEW_RENDERINDEX (_NEW_POLYGON|_NEW_LIGHT|_NEW_PROGRAM)
GLboolean
_swsetup_CreateContext( GLcontext *ctx )
{
SScontext *swsetup = (SScontext *)CALLOC(sizeof(SScontext));
if (!swsetup)
return GL_FALSE;
ctx->swsetup_context = swsetup;
swsetup->NewState = ~0;
_swsetup_trifuncs_init( ctx );
_tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12,
sizeof(SWvertex) );
return GL_TRUE;
}
void
_swsetup_DestroyContext( GLcontext *ctx )
{
SScontext *swsetup = SWSETUP_CONTEXT(ctx);
if (swsetup) {
FREE(swsetup);
ctx->swsetup_context = 0;
}
_tnl_free_vertices( ctx );
}
static void
_swsetup_RenderPrimitive( GLcontext *ctx, GLenum mode )
{
SWSETUP_CONTEXT(ctx)->render_prim = mode;
_swrast_render_primitive( ctx, mode );
}
#define SWZ ((SWvertex *)0)
#define SWOffset(MEMBER) (((char *)&(SWZ->MEMBER)) - ((char *)SWZ))
#define EMIT_ATTR( ATTR, STYLE, MEMBER ) \
do { \
map[e].attrib = (ATTR); \
map[e].format = (STYLE); \
map[e].offset = SWOffset(MEMBER); \
e++; \
} while (0)
/*
* We patch this function into tnl->Driver.Render.Start.
* It's called when we start rendering a vertex buffer.
*/
static void
_swsetup_RenderStart( GLcontext *ctx )
{
SScontext *swsetup = SWSETUP_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
GLuint new_state = swsetup->NewState;
if (new_state & _SWSETUP_NEW_RENDERINDEX) {
_swsetup_choose_trifuncs( ctx );
}
swsetup->NewState = 0;
_swrast_render_start( ctx );
/* Important:
*/
VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
if (tnl->render_inputs != swsetup->last_index) {
GLuint index = tnl->render_inputs;
struct tnl_attr_map map[_TNL_ATTRIB_MAX];
int i, e = 0;
EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, win );
if (index & _TNL_BIT_COLOR0)
EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4CHAN_4F_RGBA, color );
if (index & _TNL_BIT_COLOR1)
EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_4CHAN_4F_RGBA, specular);
if (index & _TNL_BIT_FOG)
EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1F, fog);
if (index & _TNL_BITS_TEX_ANY) {
for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) {
if (index & _TNL_BIT_TEX(i)) {
EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_4F, texcoord[i] );
}
}
}
if (index & _TNL_BIT_INDEX)
EMIT_ATTR( _TNL_ATTRIB_INDEX, EMIT_1F, index );
if (index & _TNL_BIT_POINTSIZE)
EMIT_ATTR( _TNL_ATTRIB_POINTSIZE, EMIT_1F, pointSize );
_tnl_install_attrs( ctx, map, e,
ctx->Viewport._WindowMap.m,
sizeof(SWvertex) );
swsetup->last_index = index;
}
}
/*
* We patch this function into tnl->Driver.Render.Finish.
* It's called when we finish rendering a vertex buffer.
*/
static void
_swsetup_RenderFinish( GLcontext *ctx )
{
_swrast_render_finish( ctx );
}
void
_swsetup_InvalidateState( GLcontext *ctx, GLuint new_state )
{
SScontext *swsetup = SWSETUP_CONTEXT(ctx);
swsetup->NewState |= new_state;
_tnl_invalidate_vertex_state( ctx, new_state );
}
void
_swsetup_Wakeup( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
SScontext *swsetup = SWSETUP_CONTEXT(ctx);
tnl->Driver.Render.Start = _swsetup_RenderStart;
tnl->Driver.Render.Finish = _swsetup_RenderFinish;
tnl->Driver.Render.PrimitiveNotify = _swsetup_RenderPrimitive;
tnl->Driver.Render.Interp = _tnl_interp;
tnl->Driver.Render.CopyPV = _tnl_copy_pv;
tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; /* new */
tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine; /* new */
/* points */
/* line */
/* triangle */
/* quad */
tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple;
tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
tnl->Driver.Render.Multipass = 0;
_tnl_invalidate_vertices( ctx, ~0 );
_tnl_need_projected_coords( ctx, GL_TRUE );
_swsetup_InvalidateState( ctx, ~0 );
swsetup->verts = (SWvertex *)tnl->clipspace.vertex_buf;
swsetup->last_index = 0;
}
/* Populate a swrast SWvertex from an attrib-style vertex.
*/
void
_swsetup_Translate( GLcontext *ctx, const void *vertex, SWvertex *dest )
{
const GLfloat *m = ctx->Viewport._WindowMap.m;
GLfloat tmp[4];
GLuint i;
_tnl_get_attr( ctx, vertex, _TNL_ATTRIB_POS, tmp );
dest->win[0] = m[0] * tmp[0] + m[12];
dest->win[1] = m[5] * tmp[1] + m[13];
dest->win[2] = m[10] * tmp[2] + m[14];
dest->win[3] = tmp[3];
for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
_tnl_get_attr( ctx, vertex, _TNL_ATTRIB_TEX0+i, dest->texcoord[i] );
_tnl_get_attr( ctx, vertex, _TNL_ATTRIB_COLOR0, tmp );
UNCLAMPED_FLOAT_TO_RGBA_CHAN( dest->color, tmp );
_tnl_get_attr( ctx, vertex, _TNL_ATTRIB_COLOR1, tmp );
UNCLAMPED_FLOAT_TO_RGBA_CHAN( dest->specular, tmp );
_tnl_get_attr( ctx, vertex, _TNL_ATTRIB_FOG, tmp );
dest->fog = tmp[0];
_tnl_get_attr( ctx, vertex, _TNL_ATTRIB_INDEX, tmp );
dest->index = (GLuint) tmp[0];
_tnl_get_attr( ctx, vertex, _TNL_ATTRIB_POINTSIZE, tmp );
dest->pointSize = tmp[0];
}
/*
* Mesa 3-D graphics library
* Version: 6.1
*
* Copyright (C) 1999-2004 Brian Paul 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, 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
* BRIAN PAUL 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.
*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*/
#include "glheader.h"
#include "colormac.h"
#include "macros.h"
#include "mtypes.h"
#include "tnl/t_context.h"
#include "ss_triangle.h"
#include "ss_context.h"
#define SS_RGBA_BIT 0x1
#define SS_OFFSET_BIT 0x2
#define SS_TWOSIDE_BIT 0x4
#define SS_UNFILLED_BIT 0x8
#define SS_MAX_TRIFUNC 0x10
static tnl_triangle_func tri_tab[SS_MAX_TRIFUNC];
static tnl_quad_func quad_tab[SS_MAX_TRIFUNC];
static void _swsetup_render_line_tri( GLcontext *ctx,
GLuint e0, GLuint e1, GLuint e2,
GLuint facing )
{
SScontext *swsetup = SWSETUP_CONTEXT(ctx);
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
GLubyte *ef = VB->EdgeFlag;
SWvertex *verts = swsetup->verts;
SWvertex *v0 = &verts[e0];
SWvertex *v1 = &verts[e1];
SWvertex *v2 = &verts[e2];
GLchan c[2][4];
GLchan s[2][4];
GLfloat i[2];
/* cull testing */
if (ctx->Polygon.CullFlag) {
if (facing == 1 && ctx->Polygon.CullFaceMode != GL_FRONT)
return;
if (facing == 0 && ctx->Polygon.CullFaceMode != GL_BACK)
return;
}
if (ctx->Light.ShadeModel == GL_FLAT) {
COPY_CHAN4(c[0], v0->color);
COPY_CHAN4(c[1], v1->color);
COPY_CHAN4(s[0], v0->specular);
COPY_CHAN4(s[1], v1->specular);
i[0] = v0->index;
i[1] = v1->index;
COPY_CHAN4(v0->color, v2->color);
COPY_CHAN4(v1->color, v2->color);
COPY_CHAN4(v0->specular, v2->specular);
COPY_CHAN4(v1->specular, v2->specular);
v0->index = v2->index;
v1->index = v2->index;
}
if (swsetup->render_prim == GL_POLYGON) {
if (ef[e2]) _swrast_Line( ctx, v2, v0 );
if (ef[e0]) _swrast_Line( ctx, v0, v1 );
if (ef[e1]) _swrast_Line( ctx, v1, v2 );
} else {
if (ef[e0]) _swrast_Line( ctx, v0, v1 );
if (ef[e1]) _swrast_Line( ctx, v1, v2 );
if (ef[e2]) _swrast_Line( ctx, v2, v0 );
}
if (ctx->Light.ShadeModel == GL_FLAT) {
COPY_CHAN4(v0->color, c[0]);
COPY_CHAN4(v1->color, c[1]);
COPY_CHAN4(v0->specular, s[0]);
COPY_CHAN4(v1->specular, s[1]);
v0->index = i[0];
v1->index = i[1];
}
}
static void _swsetup_render_point_tri( GLcontext *ctx,
GLuint e0, GLuint e1, GLuint e2,
GLuint facing )
{
SScontext *swsetup = SWSETUP_CONTEXT(ctx);
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
GLubyte *ef = VB->EdgeFlag;
SWvertex *verts = swsetup->verts;
SWvertex *v0 = &verts[e0];
SWvertex *v1 = &verts[e1];
SWvertex *v2 = &verts[e2];
GLchan c[2][4];
GLchan s[2][4];
GLfloat i[2];
/* cull testing */
if (ctx->Polygon.CullFlag) {
if (facing == 1 && ctx->Polygon.CullFaceMode != GL_FRONT)
return;
if (facing == 0 && ctx->Polygon.CullFaceMode != GL_BACK)
return;
}
if (ctx->Light.ShadeModel == GL_FLAT) {
/* save colors/indexes for v0, v1 vertices */
COPY_CHAN4(c[0], v0->color);
COPY_CHAN4(c[1], v1->color);
COPY_CHAN4(s[0], v0->specular);
COPY_CHAN4(s[1], v1->specular);
i[0] = v0->index;
i[1] = v1->index;
/* copy v2 color/indexes to v0, v1 indexes */
COPY_CHAN4(v0->color, v2->color);
COPY_CHAN4(v1->color, v2->color);
COPY_CHAN4(v0->specular, v2->specular);
COPY_CHAN4(v1->specular, v2->specular);
v0->index = v2->index;
v1->index = v2->index;
}
if (ef[e0]) _swrast_Point( ctx, v0 );
if (ef[e1]) _swrast_Point( ctx, v1 );
if (ef[e2]) _swrast_Point( ctx, v2 );
if (ctx->Light.ShadeModel == GL_FLAT) {
/* restore v0, v1 colores/indexes */
COPY_CHAN4(v0->color, c[0]);
COPY_CHAN4(v1->color, c[1]);
COPY_CHAN4(v0->specular, s[0]);
COPY_CHAN4(v1->specular, s[1]);
v0->index = i[0];
v1->index = i[1];
}
_swrast_flush(ctx);
}
#define SS_COLOR(a,b) UNCLAMPED_FLOAT_TO_RGBA_CHAN(a,b)
#define SS_SPEC(a,b) UNCLAMPED_FLOAT_TO_RGB_CHAN(a,b)
#define SS_IND(a,b) (a = b)
#define IND (0)
#define TAG(x) x
#include "ss_tritmp.h"
#define IND (SS_OFFSET_BIT)
#define TAG(x) x##_offset
#include "ss_tritmp.h"
#define IND (SS_TWOSIDE_BIT)
#define TAG(x) x##_twoside
#include "ss_tritmp.h"
#define IND (SS_OFFSET_BIT|SS_TWOSIDE_BIT)
#define TAG(x) x##_offset_twoside
#include "ss_tritmp.h"
#define IND (SS_UNFILLED_BIT)
#define TAG(x) x##_unfilled
#include "ss_tritmp.h"
#define IND (SS_OFFSET_BIT|SS_UNFILLED_BIT)
#define TAG(x) x##_offset_unfilled
#include "ss_tritmp.h"
#define IND (SS_TWOSIDE_BIT|SS_UNFILLED_BIT)
#define TAG(x) x##_twoside_unfilled
#include "ss_tritmp.h"
#define IND (SS_OFFSET_BIT|SS_TWOSIDE_BIT|SS_UNFILLED_BIT)
#define TAG(x) x##_offset_twoside_unfilled
#include "ss_tritmp.h"
#define IND (0|SS_RGBA_BIT)
#define TAG(x) x##_rgba
#include "ss_tritmp.h"
#define IND (SS_OFFSET_BIT|SS_RGBA_BIT)
#define TAG(x) x##_offset_rgba
#include "ss_tritmp.h"
#define IND (SS_TWOSIDE_BIT|SS_RGBA_BIT)
#define TAG(x) x##_twoside_rgba
#include "ss_tritmp.h"
#define IND (SS_OFFSET_BIT|SS_TWOSIDE_BIT|SS_RGBA_BIT)
#define TAG(x) x##_offset_twoside_rgba
#include "ss_tritmp.h"
#define IND (SS_UNFILLED_BIT|SS_RGBA_BIT)
#define TAG(x) x##_unfilled_rgba
#include "ss_tritmp.h"
#define IND (SS_OFFSET_BIT|SS_UNFILLED_BIT|SS_RGBA_BIT)
#define TAG(x) x##_offset_unfilled_rgba
#include "ss_tritmp.h"
#define IND (SS_TWOSIDE_BIT|SS_UNFILLED_BIT|SS_RGBA_BIT)
#define TAG(x) x##_twoside_unfilled_rgba
#include "ss_tritmp.h"
#define IND (SS_OFFSET_BIT|SS_TWOSIDE_BIT|SS_UNFILLED_BIT|SS_RGBA_BIT)
#define TAG(x) x##_offset_twoside_unfilled_rgba
#include "ss_tritmp.h"
void _swsetup_trifuncs_init( GLcontext *ctx )
{
(void) ctx;
init();
init_offset();
init_twoside();
init_offset_twoside();
init_unfilled();
init_offset_unfilled();
init_twoside_unfilled();
init_offset_twoside_unfilled();
init_rgba();
init_offset_rgba();
init_twoside_rgba();
init_offset_twoside_rgba();
init_unfilled_rgba();
init_offset_unfilled_rgba();
init_twoside_unfilled_rgba();
init_offset_twoside_unfilled_rgba();
}
static void swsetup_points( GLcontext *ctx, GLuint first, GLuint last )
{
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
SWvertex *verts = SWSETUP_CONTEXT(ctx)->verts;
GLuint i;
if (VB->Elts) {
for (i = first; i < last; i++)
if (VB->ClipMask[VB->Elts[i]] == 0)
_swrast_Point( ctx, &verts[VB->Elts[i]] );
}
else {
for (i = first; i < last; i++)
if (VB->ClipMask[i] == 0)
_swrast_Point( ctx, &verts[i] );
}
}
static void swsetup_line( GLcontext *ctx, GLuint v0, GLuint v1 )
{
SWvertex *verts = SWSETUP_CONTEXT(ctx)->verts;
_swrast_Line( ctx, &verts[v0], &verts[v1] );
}
void _swsetup_choose_trifuncs( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLuint ind = 0;
if (ctx->Polygon.OffsetPoint ||
ctx->Polygon.OffsetLine ||
ctx->Polygon.OffsetFill)
ind |= SS_OFFSET_BIT;
if ((ctx->Light.Enabled && ctx->Light.Model.TwoSide) ||
(ctx->VertexProgram._Enabled && ctx->VertexProgram.TwoSideEnabled))
ind |= SS_TWOSIDE_BIT;
/* We piggyback the two-sided stencil front/back determination on the
* unfilled triangle path.
*/
if (ctx->Polygon.FrontMode != GL_FILL ||
ctx->Polygon.BackMode != GL_FILL ||
(ctx->Stencil.Enabled && ctx->Stencil.TestTwoSide))
ind |= SS_UNFILLED_BIT;
if (ctx->Visual.rgbMode)
ind |= SS_RGBA_BIT;
tnl->Driver.Render.Triangle = tri_tab[ind];
tnl->Driver.Render.Quad = quad_tab[ind];
tnl->Driver.Render.Line = swsetup_line;
tnl->Driver.Render.Points = swsetup_points;
ctx->_Facing = 0;
}
/*
* Mesa 3-D graphics library
* Version: 6.1
*
* Copyright (C) 1999-2004 Brian Paul 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, 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
* BRIAN PAUL 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.
*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*/
static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 )
{
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
SWvertex *verts = SWSETUP_CONTEXT(ctx)->verts;
SWvertex *v[3];
GLfloat z[3];
GLfloat offset;
GLenum mode = GL_FILL;
GLuint facing = 0;
GLchan saved_color[3][4];
GLchan saved_spec[3][4];
GLfloat saved_index[3];
v[0] = &verts[e0];
v[1] = &verts[e1];
v[2] = &verts[e2];
if (IND & (SS_TWOSIDE_BIT | SS_OFFSET_BIT | SS_UNFILLED_BIT))
{
GLfloat ex = v[0]->win[0] - v[2]->win[0];
GLfloat ey = v[0]->win[1] - v[2]->win[1];
GLfloat fx = v[1]->win[0] - v[2]->win[0];
GLfloat fy = v[1]->win[1] - v[2]->win[1];
GLfloat cc = ex*fy - ey*fx;
if (IND & (SS_TWOSIDE_BIT | SS_UNFILLED_BIT))
{
facing = (cc < 0.0) ^ ctx->Polygon._FrontBit;
if (ctx->Stencil.TestTwoSide)
ctx->_Facing = facing; /* for 2-sided stencil test */
if (IND & SS_UNFILLED_BIT)
mode = facing ? ctx->Polygon.BackMode : ctx->Polygon.FrontMode;
if (facing == 1) {
if (IND & SS_TWOSIDE_BIT) {
if (IND & SS_RGBA_BIT) {
GLfloat (*vbcolor)[4] = VB->ColorPtr[1]->data;
COPY_CHAN4(saved_color[0], v[0]->color);
COPY_CHAN4(saved_color[1], v[1]->color);
COPY_CHAN4(saved_color[2], v[2]->color);
if (VB->ColorPtr[1]->stride) {
SS_COLOR(v[0]->color, vbcolor[e0]);
SS_COLOR(v[1]->color, vbcolor[e1]);
SS_COLOR(v[2]->color, vbcolor[e2]);
}
else {
SS_COLOR(v[0]->color, vbcolor[0]);
SS_COLOR(v[1]->color, vbcolor[0]);
SS_COLOR(v[2]->color, vbcolor[0]);
}
if (VB->SecondaryColorPtr[1]) {
GLfloat (*vbspec)[4] = VB->SecondaryColorPtr[1]->data;
COPY_CHAN4(saved_spec[0], v[0]->specular);
COPY_CHAN4(saved_spec[1], v[1]->specular);
COPY_CHAN4(saved_spec[2], v[2]->specular);
if (VB->SecondaryColorPtr[1]->stride) {
SS_SPEC(v[0]->specular, vbspec[e0]);
SS_SPEC(v[1]->specular, vbspec[e1]);
SS_SPEC(v[2]->specular, vbspec[e2]);
}
else {
SS_SPEC(v[0]->specular, vbspec[0]);
SS_SPEC(v[1]->specular, vbspec[0]);
SS_SPEC(v[2]->specular, vbspec[0]);
}
}
} else {
GLfloat *vbindex = (GLfloat *)VB->IndexPtr[1]->data;
saved_index[0] = v[0]->index;
saved_index[1] = v[1]->index;
saved_index[2] = v[2]->index;
SS_IND(v[0]->index, (GLuint) vbindex[e0]);
SS_IND(v[1]->index, (GLuint) vbindex[e1]);
SS_IND(v[2]->index, (GLuint) vbindex[e2]);
}
}
}
}
if (IND & SS_OFFSET_BIT)
{
offset = ctx->Polygon.OffsetUnits * ctx->DrawBuffer->_MRD;
z[0] = v[0]->win[2];
z[1] = v[1]->win[2];
z[2] = v[2]->win[2];
if (cc * cc > 1e-16) {
const GLfloat ez = z[0] - z[2];
const GLfloat fz = z[1] - z[2];
const GLfloat oneOverArea = 1.0F / cc;
const GLfloat dzdx = FABSF((ey * fz - ez * fy) * oneOverArea);
const GLfloat dzdy = FABSF((ez * fx - ex * fz) * oneOverArea);
offset += MAX2(dzdx, dzdy) * ctx->Polygon.OffsetFactor;
/* Unfortunately, we need to clamp to prevent negative Zs below.
* Technically, we should do the clamping per-fragment.
*/
offset = MAX2(offset, -v[0]->win[2]);
offset = MAX2(offset, -v[1]->win[2]);
offset = MAX2(offset, -v[2]->win[2]);
}
}
}
if (mode == GL_POINT) {
if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetPoint) {
v[0]->win[2] += offset;
v[1]->win[2] += offset;
v[2]->win[2] += offset;
}
_swsetup_render_point_tri( ctx, e0, e1, e2, facing );
} else if (mode == GL_LINE) {
if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetLine) {
v[0]->win[2] += offset;
v[1]->win[2] += offset;
v[2]->win[2] += offset;
}
_swsetup_render_line_tri( ctx, e0, e1, e2, facing );
} else {
if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetFill) {
v[0]->win[2] += offset;
v[1]->win[2] += offset;
v[2]->win[2] += offset;
}
_swrast_Triangle( ctx, v[0], v[1], v[2] );
}
if (IND & SS_OFFSET_BIT) {
v[0]->win[2] = z[0];
v[1]->win[2] = z[1];
v[2]->win[2] = z[2];
}
if (IND & SS_TWOSIDE_BIT) {
if (facing == 1) {
if (IND & SS_RGBA_BIT) {
COPY_CHAN4(v[0]->color, saved_color[0]);
COPY_CHAN4(v[1]->color, saved_color[1]);
COPY_CHAN4(v[2]->color, saved_color[2]);
if (VB->SecondaryColorPtr[1]) {
COPY_CHAN4(v[0]->specular, saved_spec[0]);
COPY_CHAN4(v[1]->specular, saved_spec[1]);
COPY_CHAN4(v[2]->specular, saved_spec[2]);
}
} else {
v[0]->index = saved_index[0];
v[1]->index = saved_index[1];
v[2]->index = saved_index[2];
}
}
}
}
/* Need to fixup edgeflags when decomposing to triangles:
*/
static void TAG(quadfunc)( GLcontext *ctx, GLuint v0,
GLuint v1, GLuint v2, GLuint v3 )
{
if (IND & SS_UNFILLED_BIT) {
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
GLubyte ef1 = VB->EdgeFlag[v1];
GLubyte ef3 = VB->EdgeFlag[v3];
VB->EdgeFlag[v1] = 0;
TAG(triangle)( ctx, v0, v1, v3 );
VB->EdgeFlag[v1] = ef1;
VB->EdgeFlag[v3] = 0;
TAG(triangle)( ctx, v1, v2, v3 );
VB->EdgeFlag[v3] = ef3;
} else {
TAG(triangle)( ctx, v0, v1, v3 );
TAG(triangle)( ctx, v1, v2, v3 );
}
}
static void TAG(init)( void )
{
tri_tab[IND] = TAG(triangle);
quad_tab[IND] = TAG(quadfunc);
}
#undef IND
#undef TAG
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 1999-2005 Brian Paul 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, 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
* BRIAN PAUL 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.
*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*/
#include "api_arrayelt.h"
#include "glheader.h"
#include "imports.h"
#include "context.h"
#include "macros.h"
#include "mtypes.h"
#include "dlist.h"
#include "light.h"
#include "vtxfmt.h"
#include "nvfragprog.h"
#include "tnl.h"
#include "t_array_api.h"
#include "t_context.h"
#include "t_pipeline.h"
#include "t_save_api.h"
#include "t_vp_build.h"
#include "t_vtx_api.h"
void
_tnl_MakeCurrent( GLcontext *ctx,
GLframebuffer *drawBuffer,
GLframebuffer *readBuffer )
{
(void) ctx; (void) drawBuffer; (void) readBuffer;
}
static void
install_driver_callbacks( GLcontext *ctx )
{
ctx->Driver.NewList = _tnl_NewList;
ctx->Driver.EndList = _tnl_EndList;
ctx->Driver.FlushVertices = _tnl_FlushVertices;
ctx->Driver.SaveFlushVertices = _tnl_SaveFlushVertices;
ctx->Driver.MakeCurrent = _tnl_MakeCurrent;
ctx->Driver.BeginCallList = _tnl_BeginCallList;
ctx->Driver.EndCallList = _tnl_EndCallList;
}
GLboolean
_tnl_CreateContext( GLcontext *ctx )
{
TNLcontext *tnl;
/* Create the TNLcontext structure
*/
ctx->swtnl_context = tnl = (TNLcontext *) CALLOC( sizeof(TNLcontext) );
if (!tnl) {
return GL_FALSE;
}
if (getenv("MESA_CODEGEN"))
tnl->AllowCodegen = GL_TRUE;
/* Initialize the VB.
*/
tnl->vb.Size = ctx->Const.MaxArrayLockSize + MAX_CLIPPED_VERTICES;
/* Initialize tnl state and tnl->vtxfmt.
*/
_tnl_save_init( ctx );
_tnl_array_init( ctx );
_tnl_vtx_init( ctx );
if (ctx->_MaintainTnlProgram)
_tnl_install_pipeline( ctx, _tnl_vp_pipeline );
else
_tnl_install_pipeline( ctx, _tnl_default_pipeline );
/* Initialize the arrayelt helper
*/
if (!_ae_create_context( ctx ))
return GL_FALSE;
tnl->NeedNdcCoords = GL_TRUE;
tnl->LoopbackDListCassettes = GL_FALSE;
tnl->CalcDListNormalLengths = GL_TRUE;
tnl->AllowVertexFog = GL_TRUE;
tnl->AllowPixelFog = GL_TRUE;
/* Hook our functions into exec and compile dispatch tables.
*/
_mesa_install_exec_vtxfmt( ctx, &tnl->exec_vtxfmt );
/* Set a few default values in the driver struct.
*/
install_driver_callbacks(ctx);
ctx->Driver.NeedFlush = 0;
ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;
ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN;
tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
tnl->Driver.NotifyMaterialChange = _mesa_validate_all_lighting_tables;
return GL_TRUE;
}
void
_tnl_DestroyContext( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
_tnl_array_destroy( ctx );
_tnl_vtx_destroy( ctx );
_tnl_save_destroy( ctx );
_tnl_destroy_pipeline( ctx );
_ae_destroy_context( ctx );
_tnl_ProgramCacheDestroy( ctx );
FREE(tnl);
ctx->swtnl_context = NULL;
}
void
_tnl_InvalidateState( GLcontext *ctx, GLuint new_state )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
if (new_state & (_NEW_HINT)) {
ASSERT(tnl->AllowVertexFog || tnl->AllowPixelFog);
tnl->_DoVertexFog = (tnl->AllowVertexFog && (ctx->Hint.Fog != GL_NICEST))
|| !tnl->AllowPixelFog;
}
_ae_invalidate_state(ctx, new_state);
tnl->pipeline.new_state |= new_state;
tnl->vtx.eval.new_state |= new_state;
/* Calculate tnl->render_inputs:
*/
if (ctx->Visual.rgbMode) {
tnl->render_inputs = (_TNL_BIT_POS|
_TNL_BIT_COLOR0|
(ctx->Texture._EnabledCoordUnits << _TNL_ATTRIB_TEX0));
if (NEED_SECONDARY_COLOR(ctx))
tnl->render_inputs |= _TNL_BIT_COLOR1;
}
else {
tnl->render_inputs |= (_TNL_BIT_POS|_TNL_BIT_INDEX);
}
if (ctx->Fog.Enabled ||
(ctx->FragmentProgram._Active &&
ctx->FragmentProgram._Current->FogOption != GL_NONE))
tnl->render_inputs |= _TNL_BIT_FOG;
if (ctx->Polygon.FrontMode != GL_FILL ||
ctx->Polygon.BackMode != GL_FILL)
tnl->render_inputs |= _TNL_BIT_EDGEFLAG;
if (ctx->RenderMode == GL_FEEDBACK)
tnl->render_inputs |= _TNL_BIT_TEX0;
if (ctx->Point._Attenuated ||
(ctx->VertexProgram._Enabled && ctx->VertexProgram.PointSizeEnabled))
tnl->render_inputs |= _TNL_BIT_POINTSIZE;
}
void
_tnl_wakeup_exec( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
install_driver_callbacks(ctx);
ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT;
/* Hook our functions into exec and compile dispatch tables.
*/
_mesa_install_exec_vtxfmt( ctx, &tnl->exec_vtxfmt );
/* Call all appropriate driver callbacks to revive state.
*/
_tnl_MakeCurrent( ctx, ctx->DrawBuffer, ctx->ReadBuffer );
/* Assume we haven't been getting state updates either:
*/
_tnl_InvalidateState( ctx, ~0 );
if (ctx->Light.ColorMaterialEnabled) {
_mesa_update_color_material( ctx,
ctx->Current.Attrib[VERT_ATTRIB_COLOR0] );
}
}
void
_tnl_wakeup_save_exec( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
_tnl_wakeup_exec( ctx );
_mesa_install_save_vtxfmt( ctx, &tnl->save_vtxfmt );
}
/**
* Drivers call this function to tell the TCL module whether or not
* it wants Normalized Device Coords (NDC) computed. I.e. whether
* we should "Divide-by-W". Software renders will want that.
*/
void
_tnl_need_projected_coords( GLcontext *ctx, GLboolean mode )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
if (tnl->NeedNdcCoords != mode) {
tnl->NeedNdcCoords = mode;
_tnl_InvalidateState( ctx, _NEW_PROJECTION );
}
}
void
_tnl_need_dlist_loopback( GLcontext *ctx, GLboolean mode )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
tnl->LoopbackDListCassettes = mode;
}
void
_tnl_need_dlist_norm_lengths( GLcontext *ctx, GLboolean mode )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
tnl->CalcDListNormalLengths = mode;
}
void
_tnl_isolate_materials( GLcontext *ctx, GLboolean mode )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
tnl->IsolateMaterials = mode;
}
void
_tnl_allow_vertex_fog( GLcontext *ctx, GLboolean value )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
tnl->AllowVertexFog = value;
tnl->_DoVertexFog = (tnl->AllowVertexFog && (ctx->Hint.Fog != GL_NICEST))
|| !tnl->AllowPixelFog;
}
void
_tnl_allow_pixel_fog( GLcontext *ctx, GLboolean value )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
tnl->AllowPixelFog = value;
tnl->_DoVertexFog = (tnl->AllowVertexFog && (ctx->Hint.Fog != GL_NICEST))
|| !tnl->AllowPixelFog;
}
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment