summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/i915/i915_tex.c
blob: 8d371516616baf3692da9b84fb9b1ab1ad62a882 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/**************************************************************************
 * 
 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
 * All Rights Reserved.
 * 
 **************************************************************************/

#include "glheader.h"
#include "mtypes.h"
#include "imports.h"
#include "simple_list.h"
#include "enums.h"
#include "image.h"
#include "texstore.h"
#include "texformat.h"
#include "texmem.h"
#include "swrast/swrast.h"

#include "mm.h"

#include "intel_ioctl.h"

#include "i915_context.h"
#include "i915_reg.h"






/**
 * Allocate space for and load the mesa images into the texture memory block.
 * This will happen before drawing with a new texture, or drawing with a
 * texture after it was swapped out or teximaged again.
 */

intelTextureObjectPtr i915AllocTexObj( struct gl_texture_object *texObj )
{
   i915TextureObjectPtr t = CALLOC_STRUCT( i915_texture_object );
   if ( !t ) 
      return NULL;

   texObj->DriverData = t;
   t->intel.base.tObj = texObj;
   t->intel.dirty = I915_UPLOAD_TEX_ALL;
   make_empty_list( &t->intel.base );
   return &t->intel;
}


static void i915TexParameter( GLcontext *ctx, GLenum target,
			     struct gl_texture_object *tObj,
			     GLenum pname, const GLfloat *params )
{
   i915TextureObjectPtr t = (i915TextureObjectPtr) tObj->DriverData;
 
   switch (pname) {
   case GL_TEXTURE_MIN_FILTER:
   case GL_TEXTURE_MAG_FILTER:
   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
   case GL_TEXTURE_WRAP_S:
   case GL_TEXTURE_WRAP_T:
   case GL_TEXTURE_WRAP_R:
   case GL_TEXTURE_BORDER_COLOR:
      t->intel.dirty = I915_UPLOAD_TEX_ALL;
      break;

   case GL_TEXTURE_BASE_LEVEL:
   case GL_TEXTURE_MAX_LEVEL:
   case GL_TEXTURE_MIN_LOD:
   case GL_TEXTURE_MAX_LOD:
      /* The i915 and its successors can do a lot of this without
       * reloading the textures.  A project for someone?
       */
      intelFlush( ctx );
      driSwapOutTextureObject( (driTextureObject *) t );
      t->intel.dirty = I915_UPLOAD_TEX_ALL;
      break;

   default:
      return;
   }
}


static void i915TexEnv( GLcontext *ctx, GLenum target, 
			GLenum pname, const GLfloat *param )
{
   i915ContextPtr i915 = I915_CONTEXT( ctx );
   GLuint unit = ctx->Texture.CurrentUnit;

   switch (pname) {
   case GL_TEXTURE_ENV_COLOR: 	/* Should be a tracked param */
   case GL_TEXTURE_ENV_MODE:
   case GL_COMBINE_RGB:
   case GL_COMBINE_ALPHA:
   case GL_SOURCE0_RGB:
   case GL_SOURCE1_RGB:
   case GL_SOURCE2_RGB:
   case GL_SOURCE0_ALPHA:
   case GL_SOURCE1_ALPHA:
   case GL_SOURCE2_ALPHA:
   case GL_OPERAND0_RGB:
   case GL_OPERAND1_RGB:
   case GL_OPERAND2_RGB:
   case GL_OPERAND0_ALPHA:
   case GL_OPERAND1_ALPHA:
   case GL_OPERAND2_ALPHA:
   case GL_RGB_SCALE:
   case GL_ALPHA_SCALE:
      i915->tex_program.translated = 0; 
      break;

   case GL_TEXTURE_LOD_BIAS: {
      int b = (int) ((*param) * 16.0);
      if (b > 255) b = 255;
      if (b < -256) b = -256;
      I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit));
      i915->state.Tex[unit][I915_TEXREG_SS2] &= ~SS2_LOD_BIAS_MASK;
      i915->state.Tex[unit][I915_TEXREG_SS2] |= 
	 ((b << SS2_LOD_BIAS_SHIFT) & SS2_LOD_BIAS_MASK);
      break;
   }

   default:
      break;
   }
}


static void i915BindTexture( GLcontext *ctx, GLenum target,
			    struct gl_texture_object *texObj )
{
   i915TextureObjectPtr tex = (i915TextureObjectPtr)texObj->DriverData;

   if (tex->lastTarget != texObj->Target) {
      tex->intel.dirty = I915_UPLOAD_TEX_ALL;
      tex->lastTarget = texObj->Target;
   }

   /* Need this if image format changes between bound textures.
    * Could try and shortcircuit by checking for differences in
    * state between incoming and outgoing textures:
    */
   I915_CONTEXT(ctx)->tex_program.translated = 0; 
}



void i915InitTextureFuncs( struct dd_function_table *functions )
{
   functions->BindTexture = i915BindTexture;
   functions->TexEnv = i915TexEnv;
   functions->TexParameter = i915TexParameter;
}