X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fstate_tracker%2Fst_atom_texture.c;h=5a0f91ccb1403ee50a90cc3c88775034e9abe17b;hb=782ba8d3ae55af392da8ca829f3a185c10bbecfc;hp=58e753dab641af4d3df080e21530d6ff047ff6d7;hpb=22639a6e19f95902aef23474ad672bf489231ea7;p=mesa.git diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c index 58e753dab64..5a0f91ccb14 100644 --- a/src/mesa/state_tracker/st_atom_texture.c +++ b/src/mesa/state_tracker/st_atom_texture.c @@ -47,95 +47,115 @@ #include "st_format.h" #include "st_cb_texture.h" #include "pipe/p_context.h" -#include "util/u_format.h" +#include "util/format/u_format.h" #include "util/u_inlines.h" #include "cso_cache/cso_context.h" -static GLboolean -update_single_texture(struct st_context *st, - struct pipe_sampler_view **sampler_view, - GLuint texUnit, unsigned glsl_version) +/** + * Get a pipe_sampler_view object from a texture unit. + */ +void +st_update_single_texture(struct st_context *st, + struct pipe_sampler_view **sampler_view, + GLuint texUnit, bool glsl130_or_later, + bool ignore_srgb_decode) { struct gl_context *ctx = st->ctx; const struct gl_sampler_object *samp; struct gl_texture_object *texObj; struct st_texture_object *stObj; - GLboolean retval; samp = _mesa_get_samplerobj(ctx, texUnit); texObj = ctx->Texture.Unit[texUnit]._Current; + assert(texObj); - if (!texObj) { - texObj = _mesa_get_fallback_texture(ctx, TEXTURE_2D_INDEX); - samp = &texObj->Sampler; - } stObj = st_texture_object(texObj); - retval = st_finalize_texture(ctx, st->pipe, texObj); - if (!retval) { - /* out of mem */ - return GL_FALSE; + if (unlikely(texObj->Target == GL_TEXTURE_BUFFER)) { + *sampler_view = st_get_buffer_sampler_view_from_stobj(st, stObj); + return; } - /* Check a few pieces of state outside the texture object to see if we - * need to force revalidation. - */ - if (stObj->prev_glsl_version != glsl_version || - stObj->prev_sRGBDecode != samp->sRGBDecode) { - - st_texture_release_all_sampler_views(st, stObj); - - stObj->prev_glsl_version = glsl_version; - stObj->prev_sRGBDecode = samp->sRGBDecode; + if (!st_finalize_texture(ctx, st->pipe, texObj, 0) || + !stObj->pt) { + /* out of mem */ + *sampler_view = NULL; + return; } + if (texObj->TargetIndex == TEXTURE_EXTERNAL_INDEX && + stObj->pt->screen->resource_changed) + stObj->pt->screen->resource_changed(stObj->pt->screen, stObj->pt); + *sampler_view = - st_get_texture_sampler_view_from_stobj(st, stObj, samp, glsl_version); - return GL_TRUE; + st_get_texture_sampler_view_from_stobj(st, stObj, samp, + glsl130_or_later, + ignore_srgb_decode); } static void update_textures(struct st_context *st, - gl_shader_stage mesa_shader, + enum pipe_shader_type shader_stage, const struct gl_program *prog, - unsigned max_units, - struct pipe_sampler_view **sampler_views, - unsigned *num_textures) + struct pipe_sampler_view **sampler_views) { - const GLuint old_max = *num_textures; + const GLuint old_max = st->state.num_sampler_views[shader_stage]; GLbitfield samplers_used = prog->SamplersUsed; + GLbitfield texel_fetch_samplers = prog->info.textures_used_by_txf; 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; + unsigned num_textures = 0; + + /* prog->sh.data is NULL if it's ARB_fragment_program */ + bool glsl130 = (prog->sh.data ? prog->sh.data->Version : 0) >= 130; /* loop over sampler units (aka tex image units) */ - for (unit = 0; unit < max_units; unit++, samplers_used >>= 1) { + for (unit = 0; samplers_used || unit < old_max; + unit++, samplers_used >>= 1, texel_fetch_samplers >>= 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, - prog->sh.data->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; + /* The EXT_texture_sRGB_decode extension says: + * + * "The conversion of sRGB color space components to linear color + * space is always performed if the texel lookup function is one + * of the texelFetch builtin functions. + * + * Otherwise, if the texel lookup function is one of the texture + * builtin functions or one of the texture gather functions, the + * conversion of sRGB color space components to linear color space + * is controlled by the TEXTURE_SRGB_DECODE_EXT parameter. + * + * If the TEXTURE_SRGB_DECODE_EXT parameter is DECODE_EXT, the + * conversion of sRGB color space components to linear color space + * is performed. + * + * If the TEXTURE_SRGB_DECODE_EXT parameter is SKIP_DECODE_EXT, + * the value is returned without decoding. However, if the texture + * is also [statically] accessed with a texelFetch function, then + * the result of texture builtin functions and/or texture gather + * functions may be returned with decoding or without decoding." + * + * Note: the "statically" will be added to the language per + * https://cvs.khronos.org/bugzilla/show_bug.cgi?id=14934 + * + * So we simply ignore the setting entirely for samplers that are + * (statically) accessed with a texelFetch function. + */ + st_update_single_texture(st, &sampler_view, texUnit, glsl130, + texel_fetch_samplers & 1); + num_textures = unit + 1; } pipe_sampler_view_reference(&(sampler_views[unit]), sampler_view); @@ -162,6 +182,10 @@ update_textures(struct st_context *st, /* use original view as template: */ tmpl = *sampler_views[unit]; + /* if resource format matches then YUV wasn't lowered */ + if (st_get_view_format(stObj) == stObj->pt->format) + continue; + switch (st_get_view_format(stObj)) { case PIPE_FORMAT_NV12: /* we need one additional R8G8 view: */ @@ -171,6 +195,15 @@ update_textures(struct st_context *st, sampler_views[extra] = st->pipe->create_sampler_view(st->pipe, stObj->pt->next, &tmpl); break; + case PIPE_FORMAT_P010: + case PIPE_FORMAT_P016: + /* we need one additional R16G16 view: */ + tmpl.format = PIPE_FORMAT_RG1616_UNORM; + tmpl.swizzle_g = PIPE_SWIZZLE_Y; /* tmpl from Y plane is R16 */ + 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; @@ -181,140 +214,122 @@ update_textures(struct st_context *st, sampler_views[extra] = st->pipe->create_sampler_view(st->pipe, stObj->pt->next->next, &tmpl); break; + case PIPE_FORMAT_YUYV: + /* we need one additional BGRA8888 view: */ + tmpl.format = PIPE_FORMAT_BGRA8888_UNORM; + tmpl.swizzle_b = PIPE_SWIZZLE_Z; + tmpl.swizzle_a = PIPE_SWIZZLE_W; + extra = u_bit_scan(&free_slots); + sampler_views[extra] = + st->pipe->create_sampler_view(st->pipe, stObj->pt->next, &tmpl); + break; + case PIPE_FORMAT_UYVY: + /* we need one additional RGBA8888 view: */ + tmpl.format = PIPE_FORMAT_RGBA8888_UNORM; + tmpl.swizzle_b = PIPE_SWIZZLE_Z; + tmpl.swizzle_a = PIPE_SWIZZLE_W; + extra = u_bit_scan(&free_slots); + sampler_views[extra] = + st->pipe->create_sampler_view(st->pipe, stObj->pt->next, &tmpl); + break; default: break; } - *num_textures = MAX2(*num_textures, extra + 1); + num_textures = MAX2(num_textures, extra + 1); } cso_set_sampler_views(st->cso_context, shader_stage, - *num_textures, + num_textures, sampler_views); + st->state.num_sampler_views[shader_stage] = num_textures; } +/* Same as update_textures, but don't store the views in st_context. */ +static void +update_textures_local(struct st_context *st, + enum pipe_shader_type shader_stage, + const struct gl_program *prog) +{ + struct pipe_sampler_view *local_views[PIPE_MAX_SAMPLERS] = {0}; + update_textures(st, shader_stage, prog, local_views); -static void -update_vertex_textures(struct st_context *st) + unsigned num = st->state.num_sampler_views[shader_stage]; + for (unsigned i = 0; i < num; i++) + pipe_sampler_view_reference(&local_views[i], NULL); +} + +void +st_update_vertex_textures(struct st_context *st) { const struct gl_context *ctx = st->ctx; if (ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits > 0) { update_textures(st, - MESA_SHADER_VERTEX, + PIPE_SHADER_VERTEX, ctx->VertexProgram._Current, - ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits, - st->state.sampler_views[PIPE_SHADER_VERTEX], - &st->state.num_sampler_views[PIPE_SHADER_VERTEX]); + st->state.vert_sampler_views); } } -static void -update_fragment_textures(struct st_context *st) +void +st_update_fragment_textures(struct st_context *st) { const struct gl_context *ctx = st->ctx; update_textures(st, - MESA_SHADER_FRAGMENT, + PIPE_SHADER_FRAGMENT, ctx->FragmentProgram._Current, - ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits, - st->state.sampler_views[PIPE_SHADER_FRAGMENT], - &st->state.num_sampler_views[PIPE_SHADER_FRAGMENT]); + st->state.frag_sampler_views); } -static void -update_geometry_textures(struct st_context *st) +void +st_update_geometry_textures(struct st_context *st) { const struct gl_context *ctx = st->ctx; if (ctx->GeometryProgram._Current) { - update_textures(st, - MESA_SHADER_GEOMETRY, - ctx->GeometryProgram._Current, - ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits, - st->state.sampler_views[PIPE_SHADER_GEOMETRY], - &st->state.num_sampler_views[PIPE_SHADER_GEOMETRY]); + update_textures_local(st, PIPE_SHADER_GEOMETRY, + ctx->GeometryProgram._Current); } } -static void -update_tessctrl_textures(struct st_context *st) +void +st_update_tessctrl_textures(struct st_context *st) { const struct gl_context *ctx = st->ctx; if (ctx->TessCtrlProgram._Current) { - update_textures(st, - MESA_SHADER_TESS_CTRL, - ctx->TessCtrlProgram._Current, - ctx->Const.Program[MESA_SHADER_TESS_CTRL].MaxTextureImageUnits, - st->state.sampler_views[PIPE_SHADER_TESS_CTRL], - &st->state.num_sampler_views[PIPE_SHADER_TESS_CTRL]); + update_textures_local(st, PIPE_SHADER_TESS_CTRL, + ctx->TessCtrlProgram._Current); } } -static void -update_tesseval_textures(struct st_context *st) +void +st_update_tesseval_textures(struct st_context *st) { const struct gl_context *ctx = st->ctx; if (ctx->TessEvalProgram._Current) { - update_textures(st, - MESA_SHADER_TESS_EVAL, - ctx->TessEvalProgram._Current, - ctx->Const.Program[MESA_SHADER_TESS_EVAL].MaxTextureImageUnits, - st->state.sampler_views[PIPE_SHADER_TESS_EVAL], - &st->state.num_sampler_views[PIPE_SHADER_TESS_EVAL]); + update_textures_local(st, PIPE_SHADER_TESS_EVAL, + ctx->TessEvalProgram._Current); } } -static void -update_compute_textures(struct st_context *st) +void +st_update_compute_textures(struct st_context *st) { const struct gl_context *ctx = st->ctx; if (ctx->ComputeProgram._Current) { - update_textures(st, - MESA_SHADER_COMPUTE, - ctx->ComputeProgram._Current, - ctx->Const.Program[MESA_SHADER_COMPUTE].MaxTextureImageUnits, - st->state.sampler_views[PIPE_SHADER_COMPUTE], - &st->state.num_sampler_views[PIPE_SHADER_COMPUTE]); + update_textures_local(st, PIPE_SHADER_COMPUTE, + ctx->ComputeProgram._Current); } } - - -const struct st_tracked_state st_update_fragment_texture = { - update_fragment_textures /* update */ -}; - - -const struct st_tracked_state st_update_vertex_texture = { - update_vertex_textures /* update */ -}; - - -const struct st_tracked_state st_update_geometry_texture = { - update_geometry_textures /* update */ -}; - - -const struct st_tracked_state st_update_tessctrl_texture = { - update_tessctrl_textures /* update */ -}; - - -const struct st_tracked_state st_update_tesseval_texture = { - update_tesseval_textures /* update */ -}; - - -const struct st_tracked_state st_update_compute_texture = { - update_compute_textures /* update */ -};