#include "st_texture.h"
#include "st_cb_texture.h"
#include "pipe/p_context.h"
-#include "pipe/p_inlines.h"
#include "cso_cache/cso_context.h"
-#include "util/u_simple_shaders.h"
-static void *
-get_passthrough_fs(struct st_context *st)
+static void
+update_textures(struct st_context *st)
{
- struct pipe_shader_state shader;
+ struct gl_vertex_program *vprog = st->ctx->VertexProgram._Current;
+ struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current;
+ const GLbitfield samplersUsed = (vprog->Base.SamplersUsed |
+ fprog->Base.SamplersUsed);
+ GLuint su;
+
+ st->state.num_textures = 0;
+
+ /* loop over sampler units (aka tex image units) */
+ for (su = 0; su < st->ctx->Const.MaxTextureImageUnits; su++) {
+ struct pipe_texture *pt = NULL;
+
+ if (samplersUsed & (1 << su)) {
+ struct gl_texture_object *texObj;
+ struct st_texture_object *stObj;
+ GLboolean flush, retval;
+ GLuint texUnit;
+
+ if (fprog->Base.SamplersUsed & (1 << su))
+ texUnit = fprog->Base.SamplerUnits[su];
+ else
+ texUnit = vprog->Base.SamplerUnits[su];
+
+ texObj = st->ctx->Texture.Unit[texUnit]._Current;
+
+ if (!texObj) {
+ texObj = st_get_default_texture(st);
+ }
+ stObj = st_texture_object(texObj);
+
+ retval = st_finalize_texture(st->ctx, st->pipe, texObj, &flush);
+ if (!retval) {
+ /* out of mem */
+ continue;
+ }
- if (!st->passthrough_fs) {
- st->passthrough_fs =
- util_make_fragment_passthrough_shader(st->pipe, &shader);
- free((void *) shader.tokens);
+ st->state.num_textures = su + 1;
+
+ pt = st_get_stobj_texture(stObj);
+ }
+
+ /*
+ if (pt) {
+ printf("%s su=%u non-null\n", __FUNCTION__, su);
+ }
+ else {
+ printf("%s su=%u null\n", __FUNCTION__, su);
+ }
+ */
+
+ pipe_texture_reference(&st->state.sampler_texture[su], pt);
}
- return st->passthrough_fs;
+ cso_set_sampler_textures(st->cso_context,
+ st->state.num_textures,
+ st->state.sampler_texture);
}
-/**
- * XXX This needs some work yet....
- * Need to "upload" texture images at appropriate times.
- */
+const struct st_tracked_state st_update_texture = {
+ "st_update_texture", /* name */
+ { /* dirty */
+ _NEW_TEXTURE, /* mesa */
+ ST_NEW_FRAGMENT_PROGRAM, /* st */
+ },
+ update_textures /* update */
+};
+
+
+
+
static void
-update_textures(struct st_context *st)
+finalize_textures(struct st_context *st)
{
struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current;
+ const GLboolean prev_missing_textures = st->missing_textures;
GLuint su;
- GLboolean missing_textures = GL_FALSE;
- st->state.num_textures = 0;
+ st->missing_textures = GL_FALSE;
for (su = 0; su < st->ctx->Const.MaxTextureCoordUnits; su++) {
- struct pipe_texture *pt = NULL;
-
if (fprog->Base.SamplersUsed & (1 << su)) {
const GLuint texUnit = fprog->Base.SamplerUnits[su];
struct gl_texture_object *texObj
retval = st_finalize_texture(st->ctx, st->pipe, texObj, &flush);
if (!retval) {
/* out of mem */
- missing_textures = GL_TRUE;
+ st->missing_textures = GL_TRUE;
continue;
}
- st->state.num_textures = su + 1;
-
stObj->teximage_realloc = TRUE;
}
-
- pt = st_get_stobj_texture(stObj);
}
-
- pipe_texture_reference(&st->state.sampler_texture[su], pt);
}
- cso_set_sampler_textures(st->cso_context,
- st->state.num_textures,
- st->state.sampler_texture);
-
- if (missing_textures) {
- /* use a pass-through frag shader that uses no textures */
- void *fs = get_passthrough_fs(st);
- cso_set_fragment_shader_handle(st->cso_context, fs);
- }
+ if (prev_missing_textures != st->missing_textures)
+ st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
}
-const struct st_tracked_state st_update_texture = {
- "st_update_texture", /* name */
- { /* dirty */
- _NEW_TEXTURE, /* mesa */
- ST_NEW_FRAGMENT_PROGRAM, /* st */
+
+const struct st_tracked_state st_finalize_textures = {
+ "st_finalize_textures", /* name */
+ { /* dirty */
+ _NEW_TEXTURE, /* mesa */
+ 0, /* st */
},
- update_textures /* update */
+ finalize_textures /* update */
};