#include "st_context.h"
#include "st_atom.h"
+#include "st_texture.h"
#include "st_cb_texture.h"
#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
+#include "cso_cache/cso_context.h"
-/**
- * XXX This needs some work yet....
- * Need to "upload" texture images at appropriate times.
- */
static void
update_textures(struct st_context *st)
{
- GLuint u;
+ 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;
- for (u = 0; u < st->ctx->Const.MaxTextureImageUnits; u++) {
- struct gl_texture_object *texObj
- = st->ctx->Texture.Unit[u]._Current;
- struct pipe_mipmap_tree *mt;
- if (texObj) {
+ 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;
+ }
- retval = st_finalize_mipmap_tree(st->ctx, st->pipe, u, &flush);
-#if 0
- printf("finalize_mipmap_tree returned %d, flush = %d\n",
- retval, flush);
-#endif
+ st->state.num_textures = su + 1;
- mt = st_get_texobj_mipmap_tree(texObj);
+ pt = st_get_stobj_texture(stObj);
+ }
+
+ /*
+ if (pt) {
+ printf("%s su=%u non-null\n", __FUNCTION__, su);
}
else {
- mt = NULL;
+ printf("%s su=%u null\n", __FUNCTION__, su);
}
+ */
- st->state.texture[u] = mt;
- st->pipe->set_texture_state(st->pipe, u, mt);
+ pipe_texture_reference(&st->state.sampler_texture[su], pt);
}
+
+ cso_set_sampler_textures(st->cso_context,
+ st->state.num_textures,
+ st->state.sampler_texture);
}
const struct st_tracked_state st_update_texture = {
- .name = "st_update_texture",
- .dirty = {
- .mesa = _NEW_TEXTURE,
- .st = 0,
+ "st_update_texture", /* name */
+ { /* dirty */
+ _NEW_TEXTURE, /* mesa */
+ ST_NEW_FRAGMENT_PROGRAM, /* st */
},
- .update = update_textures
+ update_textures /* update */
};
+static void
+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;
+
+ st->missing_textures = GL_FALSE;
+
+ for (su = 0; su < st->ctx->Const.MaxTextureCoordUnits; su++) {
+ if (fprog->Base.SamplersUsed & (1 << su)) {
+ const GLuint texUnit = fprog->Base.SamplerUnits[su];
+ struct gl_texture_object *texObj
+ = st->ctx->Texture.Unit[texUnit]._Current;
+ struct st_texture_object *stObj = st_texture_object(texObj);
+
+ if (texObj) {
+ GLboolean flush, retval;
+
+ retval = st_finalize_texture(st->ctx, st->pipe, texObj, &flush);
+ if (!retval) {
+ /* out of mem */
+ st->missing_textures = GL_TRUE;
+ continue;
+ }
+
+ stObj->teximage_realloc = TRUE;
+ }
+ }
+ }
+
+ if (prev_missing_textures != st->missing_textures)
+ st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
+}
+
+
+const struct st_tracked_state st_finalize_textures = {
+ "st_finalize_textures", /* name */
+ { /* dirty */
+ _NEW_TEXTURE, /* mesa */
+ 0, /* st */
+ },
+ finalize_textures /* update */
+};