Merge commit 'origin/gallium-master-merge'
[mesa.git] / src / mesa / state_tracker / st_atom_texture.c
1 /**************************************************************************
2 *
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 /*
29 * Authors:
30 * Keith Whitwell <keith@tungstengraphics.com>
31 * Brian Paul
32 */
33
34
35 #include "st_context.h"
36 #include "st_atom.h"
37 #include "st_texture.h"
38 #include "st_cb_texture.h"
39 #include "pipe/p_context.h"
40 #include "pipe/p_inlines.h"
41 #include "cso_cache/cso_context.h"
42
43
44 static void
45 update_textures(struct st_context *st)
46 {
47 struct gl_vertex_program *vprog = st->ctx->VertexProgram._Current;
48 struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current;
49 const GLbitfield samplersUsed = (vprog->Base.SamplersUsed |
50 fprog->Base.SamplersUsed);
51 GLuint su;
52
53 st->state.num_textures = 0;
54
55 /* loop over sampler units (aka tex image units) */
56 for (su = 0; su < st->ctx->Const.MaxTextureImageUnits; su++) {
57 struct pipe_texture *pt = NULL;
58
59 if (samplersUsed & (1 << su)) {
60 struct gl_texture_object *texObj;
61 struct st_texture_object *stObj;
62 GLboolean flush, retval;
63 GLuint texUnit;
64
65 if (fprog->Base.SamplersUsed & (1 << su))
66 texUnit = fprog->Base.SamplerUnits[su];
67 else
68 texUnit = vprog->Base.SamplerUnits[su];
69
70 texObj = st->ctx->Texture.Unit[texUnit]._Current;
71
72 if (!texObj) {
73 texObj = st_get_default_texture(st);
74 }
75 stObj = st_texture_object(texObj);
76
77 retval = st_finalize_texture(st->ctx, st->pipe, texObj, &flush);
78 if (!retval) {
79 /* out of mem */
80 continue;
81 }
82
83 st->state.num_textures = su + 1;
84
85 pt = st_get_stobj_texture(stObj);
86 }
87
88 /*
89 if (pt) {
90 printf("%s su=%u non-null\n", __FUNCTION__, su);
91 }
92 else {
93 printf("%s su=%u null\n", __FUNCTION__, su);
94 }
95 */
96
97 pipe_texture_reference(&st->state.sampler_texture[su], pt);
98 }
99
100 cso_set_sampler_textures(st->cso_context,
101 st->state.num_textures,
102 st->state.sampler_texture);
103 }
104
105
106 const struct st_tracked_state st_update_texture = {
107 "st_update_texture", /* name */
108 { /* dirty */
109 _NEW_TEXTURE, /* mesa */
110 ST_NEW_FRAGMENT_PROGRAM, /* st */
111 },
112 update_textures /* update */
113 };
114
115
116
117
118 static void
119 finalize_textures(struct st_context *st)
120 {
121 struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current;
122 const GLboolean prev_missing_textures = st->missing_textures;
123 GLuint su;
124
125 st->missing_textures = GL_FALSE;
126
127 for (su = 0; su < st->ctx->Const.MaxTextureCoordUnits; su++) {
128 if (fprog->Base.SamplersUsed & (1 << su)) {
129 const GLuint texUnit = fprog->Base.SamplerUnits[su];
130 struct gl_texture_object *texObj
131 = st->ctx->Texture.Unit[texUnit]._Current;
132 struct st_texture_object *stObj = st_texture_object(texObj);
133
134 if (texObj) {
135 GLboolean flush, retval;
136
137 retval = st_finalize_texture(st->ctx, st->pipe, texObj, &flush);
138 if (!retval) {
139 /* out of mem */
140 st->missing_textures = GL_TRUE;
141 continue;
142 }
143
144 stObj->teximage_realloc = TRUE;
145 }
146 }
147 }
148
149 if (prev_missing_textures != st->missing_textures)
150 st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
151 }
152
153
154
155 const struct st_tracked_state st_finalize_textures = {
156 "st_finalize_textures", /* name */
157 { /* dirty */
158 _NEW_TEXTURE, /* mesa */
159 0, /* st */
160 },
161 finalize_textures /* update */
162 };