static void update_textures(struct st_context *st, unsigned shader_stage, const struct gl_program *prog, unsigned max_units, struct pipe_sampler_view **sampler_views, unsigned *num_textures) { const GLuint old_max = *num_textures; GLbitfield samplers_used = prog->SamplersUsed; GLuint unit, new_count; if (samplers_used == 0x0 && old_max == 0) return; *num_textures = 0; /* loop over sampler units (aka tex image units) */ for (unit = 0; unit < max_units; unit++, samplers_used >>= 1) { struct pipe_sampler_view *sampler_view = NULL; if (samplers_used & 1) { const GLuint texUnit = prog->SamplerUnits[unit]; GLboolean retval; retval = update_single_texture(st, &sampler_view, texUnit); if (retval == GL_FALSE) continue; *num_textures = unit + 1; } else if (samplers_used == 0 && unit >= old_max) { /* if we've reset all the old views and we have no more new ones */ break; } pipe_sampler_view_reference(&(sampler_views[unit]), sampler_view); } /* Ex: if old_max = 3 and *num_textures = 1, we need to pass an * array of views={X, NULL, NULL} to unref the old texture views * at positions [1] and [2]. */ new_count = MAX2(*num_textures, old_max); assert(new_count <= max_units); cso_set_sampler_views(st->cso_context, shader_stage, new_count, sampler_views); }
static void update_textures(struct st_context *st, gl_shader_stage mesa_shader, const struct gl_program *prog, unsigned max_units, struct pipe_sampler_view **sampler_views, unsigned *num_textures) { const GLuint old_max = *num_textures; GLbitfield samplers_used = prog->SamplersUsed; GLuint unit; struct gl_shader_program *shader = st->ctx->_Shader->CurrentProgram[mesa_shader]; unsigned glsl_version = shader ? shader->Version : 0; unsigned shader_stage = st_shader_stage_to_ptarget(mesa_shader); if (samplers_used == 0x0 && old_max == 0) return; *num_textures = 0; /* loop over sampler units (aka tex image units) */ for (unit = 0; unit < max_units; unit++, samplers_used >>= 1) { struct pipe_sampler_view *sampler_view = NULL; if (samplers_used & 1) { const GLuint texUnit = prog->SamplerUnits[unit]; GLboolean retval; retval = update_single_texture(st, &sampler_view, texUnit, glsl_version); if (retval == GL_FALSE) continue; *num_textures = unit + 1; } else if (samplers_used == 0 && unit >= old_max) { /* if we've reset all the old views and we have no more new ones */ break; } pipe_sampler_view_reference(&(sampler_views[unit]), sampler_view); } cso_set_sampler_views(st->cso_context, shader_stage, *num_textures, sampler_views); }
static void update_vertex_textures(struct st_context *st) { const struct gl_context *ctx = st->ctx; struct gl_vertex_program *vprog = ctx->VertexProgram._Current; GLuint su; if (!vprog->Base.SamplersUsed && st->state.num_vertex_textures == 0) return; st->state.num_vertex_textures = 0; /* loop over sampler units (aka tex image units) */ for (su = 0; su < ctx->Const.MaxTextureImageUnits; su++) { struct pipe_sampler_view *sampler_view = NULL; if (vprog->Base.SamplersUsed & (1 << su)) { GLboolean retval; GLuint texUnit; texUnit = vprog->Base.SamplerUnits[su]; retval = update_single_texture(st, &sampler_view, texUnit); if (retval == GL_FALSE) continue; st->state.num_vertex_textures = su + 1; } pipe_sampler_view_reference(&st->state.sampler_vertex_views[su], sampler_view); } if (ctx->Const.MaxVertexTextureImageUnits > 0) { GLuint numUnits = MIN2(st->state.num_vertex_textures, ctx->Const.MaxVertexTextureImageUnits); cso_set_vertex_sampler_views(st->cso_context, numUnits, st->state.sampler_vertex_views); } }
static void update_fragment_textures(struct st_context *st) { const struct gl_context *ctx = st->ctx; struct gl_fragment_program *fprog = ctx->FragmentProgram._Current; GLuint su; int old_max = st->state.num_textures; GLbitfield samplers_used = fprog->Base.SamplersUsed; st->state.num_textures = 0; /* loop over sampler units (aka tex image units) */ for (su = 0; su < ctx->Const.MaxTextureImageUnits; su++, samplers_used >>= 1) { struct pipe_sampler_view *sampler_view = NULL; if (samplers_used & 1) { GLboolean retval; GLuint texUnit; texUnit = fprog->Base.SamplerUnits[su]; retval = update_single_texture(st, &sampler_view, texUnit); if (retval == GL_FALSE) continue; st->state.num_textures = su + 1; } else if (samplers_used == 0 && su >= old_max) { /* if we've reset all the old views and we have no more new ones */ break; } pipe_sampler_view_reference(&st->state.sampler_views[su], sampler_view); } cso_set_fragment_sampler_views(st->cso_context, st->state.num_textures, st->state.sampler_views); }
static void update_textures(struct st_context *st, gl_shader_stage mesa_shader, const struct gl_program *prog, unsigned max_units, struct pipe_sampler_view **sampler_views, unsigned *num_textures) { const GLuint old_max = *num_textures; GLbitfield samplers_used = prog->SamplersUsed; GLbitfield free_slots = ~prog->SamplersUsed; GLbitfield external_samplers_used = prog->ExternalSamplersUsed; GLuint unit; enum pipe_shader_type shader_stage = st_shader_stage_to_ptarget(mesa_shader); if (samplers_used == 0x0 && old_max == 0) return; *num_textures = 0; /* loop over sampler units (aka tex image units) */ for (unit = 0; unit < max_units; unit++, samplers_used >>= 1) { struct pipe_sampler_view *sampler_view = NULL; if (samplers_used & 1) { /* prog->sh.data is NULL if it's ARB_fragment_program */ unsigned glsl_version = prog->sh.data ? prog->sh.data->Version : 0; const GLuint texUnit = prog->SamplerUnits[unit]; GLboolean retval; retval = update_single_texture(st, &sampler_view, texUnit, glsl_version); if (retval == GL_FALSE) continue; *num_textures = unit + 1; } else if (samplers_used == 0 && unit >= old_max) { /* if we've reset all the old views and we have no more new ones */ break; } pipe_sampler_view_reference(&(sampler_views[unit]), sampler_view); } /* For any external samplers with multiplaner YUV, stuff the additional * sampler views we need at the end. * * Trying to cache the sampler view in the stObj looks painful, so just * re-create the sampler view for the extra planes each time. Main use * case is video playback (ie. fps games wouldn't be using this) so I * guess no point to try to optimize this feature. */ while (unlikely(external_samplers_used)) { GLuint unit = u_bit_scan(&external_samplers_used); GLuint extra = 0; struct st_texture_object *stObj = st_get_texture_object(st->ctx, prog, unit); struct pipe_sampler_view tmpl; if (!stObj) continue; /* use original view as template: */ tmpl = *sampler_views[unit]; switch (st_get_view_format(stObj)) { case PIPE_FORMAT_NV12: /* we need one additional R8G8 view: */ tmpl.format = PIPE_FORMAT_RG88_UNORM; tmpl.swizzle_g = PIPE_SWIZZLE_Y; /* tmpl from Y plane is R8 */ extra = u_bit_scan(&free_slots); sampler_views[extra] = st->pipe->create_sampler_view(st->pipe, stObj->pt->next, &tmpl); break; case PIPE_FORMAT_IYUV: /* we need two additional R8 views: */ tmpl.format = PIPE_FORMAT_R8_UNORM; extra = u_bit_scan(&free_slots); sampler_views[extra] = st->pipe->create_sampler_view(st->pipe, stObj->pt->next, &tmpl); extra = u_bit_scan(&free_slots); sampler_views[extra] = st->pipe->create_sampler_view(st->pipe, stObj->pt->next->next, &tmpl); break; default: break; } *num_textures = MAX2(*num_textures, extra + 1); } cso_set_sampler_views(st->cso_context, shader_stage, *num_textures, sampler_views); }