X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fstate_tracker%2Fst_atom_sampler.c;h=b74d47b691fed88ca8f981942bd97bb42fb6aa8d;hb=013d9e40feed336d983b728357e4ce77b871c36d;hp=5f3f852ab3b3c85beaa4c5a56e152595d1662040;hpb=18d498a1ae5eb8c3186847c96a6934ef5a82c6ab;p=mesa.git diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c index 5f3f852ab3b..b74d47b691f 100644 --- a/src/mesa/state_tracker/st_atom_sampler.c +++ b/src/mesa/state_tracker/st_atom_sampler.c @@ -43,13 +43,14 @@ #include "st_cb_texture.h" #include "st_format.h" #include "st_atom.h" +#include "st_sampler_view.h" #include "st_texture.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "cso_cache/cso_context.h" -#include "util/u_format.h" +#include "util/format/u_format.h" /** @@ -58,71 +59,43 @@ static GLuint gl_wrap_xlate(GLenum wrap) { - switch (wrap) { - case GL_REPEAT: - return PIPE_TEX_WRAP_REPEAT; - case GL_CLAMP: - return PIPE_TEX_WRAP_CLAMP; - case GL_CLAMP_TO_EDGE: - return PIPE_TEX_WRAP_CLAMP_TO_EDGE; - case GL_CLAMP_TO_BORDER: - return PIPE_TEX_WRAP_CLAMP_TO_BORDER; - case GL_MIRRORED_REPEAT: - return PIPE_TEX_WRAP_MIRROR_REPEAT; - case GL_MIRROR_CLAMP_EXT: - return PIPE_TEX_WRAP_MIRROR_CLAMP; - case GL_MIRROR_CLAMP_TO_EDGE_EXT: - return PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE; - case GL_MIRROR_CLAMP_TO_BORDER_EXT: - return PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER; - default: - assert(0); - return 0; - } + /* Take advantage of how the enums are defined. */ + static const unsigned table[32] = { + [GL_REPEAT & 0x1f] = PIPE_TEX_WRAP_REPEAT, + [GL_CLAMP & 0x1f] = PIPE_TEX_WRAP_CLAMP, + [GL_CLAMP_TO_EDGE & 0x1f] = PIPE_TEX_WRAP_CLAMP_TO_EDGE, + [GL_CLAMP_TO_BORDER & 0x1f] = PIPE_TEX_WRAP_CLAMP_TO_BORDER, + [GL_MIRRORED_REPEAT & 0x1f] = PIPE_TEX_WRAP_MIRROR_REPEAT, + [GL_MIRROR_CLAMP_EXT & 0x1f] = PIPE_TEX_WRAP_MIRROR_CLAMP, + [GL_MIRROR_CLAMP_TO_EDGE & 0x1f] = PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE, + [GL_MIRROR_CLAMP_TO_BORDER_EXT & 0x1f] = PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER, + }; + + return table[wrap & 0x1f]; } static GLuint gl_filter_to_mip_filter(GLenum filter) { - switch (filter) { - case GL_NEAREST: - case GL_LINEAR: + /* Take advantage of how the enums are defined. */ + if (filter <= GL_LINEAR) return PIPE_TEX_MIPFILTER_NONE; - - case GL_NEAREST_MIPMAP_NEAREST: - case GL_LINEAR_MIPMAP_NEAREST: + if (filter <= GL_LINEAR_MIPMAP_NEAREST) return PIPE_TEX_MIPFILTER_NEAREST; - case GL_NEAREST_MIPMAP_LINEAR: - case GL_LINEAR_MIPMAP_LINEAR: - return PIPE_TEX_MIPFILTER_LINEAR; - - default: - assert(0); - return PIPE_TEX_MIPFILTER_NONE; - } + return PIPE_TEX_MIPFILTER_LINEAR; } static GLuint gl_filter_to_img_filter(GLenum filter) { - switch (filter) { - case GL_NEAREST: - case GL_NEAREST_MIPMAP_NEAREST: - case GL_NEAREST_MIPMAP_LINEAR: - return PIPE_TEX_FILTER_NEAREST; - - case GL_LINEAR: - case GL_LINEAR_MIPMAP_NEAREST: - case GL_LINEAR_MIPMAP_LINEAR: + /* Take advantage of how the enums are defined. */ + if (filter & 1) return PIPE_TEX_FILTER_LINEAR; - default: - assert(0); - return PIPE_TEX_FILTER_NEAREST; - } + return PIPE_TEX_FILTER_NEAREST; } @@ -133,12 +106,9 @@ void st_convert_sampler(const struct st_context *st, const struct gl_texture_object *texobj, const struct gl_sampler_object *msamp, + float tex_unit_lod_bias, struct pipe_sampler_state *sampler) { - GLenum texBaseFormat; - - texBaseFormat = _mesa_texture_base_format(texobj); - memset(sampler, 0, sizeof(*sampler)); sampler->wrap_s = gl_wrap_xlate(msamp->WrapS); sampler->wrap_t = gl_wrap_xlate(msamp->WrapT); @@ -151,7 +121,7 @@ st_convert_sampler(const struct st_context *st, if (texobj->Target != GL_TEXTURE_RECTANGLE_ARB) sampler->normalized_coords = 1; - sampler->lod_bias = msamp->LodBias; + sampler->lod_bias = msamp->LodBias + tex_unit_lod_bias; /* Reduce the number of states by allowing only the values that AMD GCN * can represent. Apps use lod_bias for smooth transitions to bigger mipmap * levels. @@ -171,42 +141,57 @@ st_convert_sampler(const struct st_context *st, assert(sampler->min_lod <= sampler->max_lod); } + /* Check that only wrap modes using the border color have the first bit + * set. + */ + STATIC_ASSERT(PIPE_TEX_WRAP_CLAMP & 0x1); + STATIC_ASSERT(PIPE_TEX_WRAP_CLAMP_TO_BORDER & 0x1); + STATIC_ASSERT(PIPE_TEX_WRAP_MIRROR_CLAMP & 0x1); + STATIC_ASSERT(PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER & 0x1); + STATIC_ASSERT(((PIPE_TEX_WRAP_REPEAT | + PIPE_TEX_WRAP_CLAMP_TO_EDGE | + PIPE_TEX_WRAP_MIRROR_REPEAT | + PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE) & 0x1) == 0); + /* For non-black borders... */ - if (msamp->BorderColor.ui[0] || - msamp->BorderColor.ui[1] || - msamp->BorderColor.ui[2] || - msamp->BorderColor.ui[3]) { - const struct st_texture_object *stobj = st_texture_object_const(texobj); + if (/* This is true if wrap modes are using the border color: */ + (sampler->wrap_s | sampler->wrap_t | sampler->wrap_r) & 0x1 && + (msamp->BorderColor.ui[0] || + msamp->BorderColor.ui[1] || + msamp->BorderColor.ui[2] || + msamp->BorderColor.ui[3])) { const GLboolean is_integer = texobj->_IsIntegerFormat; - const struct pipe_sampler_view *sv = NULL; - union pipe_color_union border_color; - GLuint i; - - /* Just search for the first used view. We can do this because the - swizzle is per-texture, not per context. */ - /* XXX: clean that up to not use the sampler view at all */ - for (i = 0; i < stobj->num_sampler_views; ++i) { - if (stobj->sampler_views[i]) { - sv = stobj->sampler_views[i]; - break; + GLenum texBaseFormat = _mesa_base_tex_image(texobj)->_BaseFormat; + + if (texobj->StencilSampling) + texBaseFormat = GL_STENCIL_INDEX; + + if (st->apply_texture_swizzle_to_border_color) { + const struct st_texture_object *stobj = st_texture_object_const(texobj); + /* XXX: clean that up to not use the sampler view at all */ + const struct st_sampler_view *sv = st_texture_get_current_sampler_view(st, stobj); + + if (sv) { + struct pipe_sampler_view *view = sv->view; + union pipe_color_union tmp; + const unsigned char swz[4] = + { + view->swizzle_r, + view->swizzle_g, + view->swizzle_b, + view->swizzle_a, + }; + + st_translate_color(&msamp->BorderColor, &tmp, + texBaseFormat, is_integer); + + util_format_apply_color_swizzle(&sampler->border_color, + &tmp, swz, is_integer); + } else { + st_translate_color(&msamp->BorderColor, + &sampler->border_color, + texBaseFormat, is_integer); } - } - - if (st->apply_texture_swizzle_to_border_color && sv) { - const unsigned char swz[4] = - { - sv->swizzle_r, - sv->swizzle_g, - sv->swizzle_b, - sv->swizzle_a, - }; - - st_translate_color(&msamp->BorderColor, - &border_color, - texBaseFormat, is_integer); - - util_format_apply_color_swizzle(&sampler->border_color, - &border_color, swz, is_integer); } else { st_translate_color(&msamp->BorderColor, &sampler->border_color, @@ -218,11 +203,14 @@ st_convert_sampler(const struct st_context *st, 0 : (GLuint) msamp->MaxAnisotropy); /* If sampling a depth texture and using shadow comparison */ - if ((texBaseFormat == GL_DEPTH_COMPONENT || - (texBaseFormat == GL_DEPTH_STENCIL && !texobj->StencilSampling)) && - msamp->CompareMode == GL_COMPARE_R_TO_TEXTURE) { - sampler->compare_mode = PIPE_TEX_COMPARE_R_TO_TEXTURE; - sampler->compare_func = st_compare_func_to_pipe(msamp->CompareFunc); + if (msamp->CompareMode == GL_COMPARE_R_TO_TEXTURE) { + GLenum texBaseFormat = _mesa_base_tex_image(texobj)->_BaseFormat; + + if (texBaseFormat == GL_DEPTH_COMPONENT || + (texBaseFormat == GL_DEPTH_STENCIL && !texobj->StencilSampling)) { + sampler->compare_mode = PIPE_TEX_COMPARE_R_TO_TEXTURE; + sampler->compare_func = st_compare_func_to_pipe(msamp->CompareFunc); + } } /* Only set the seamless cube map texture parameter because the per-context @@ -246,12 +234,13 @@ st_convert_sampler_from_unit(const struct st_context *st, texobj = ctx->Texture.Unit[texUnit]._Current; assert(texobj); + assert(texobj->Target != GL_TEXTURE_BUFFER); msamp = _mesa_get_samplerobj(ctx, texUnit); - st_convert_sampler(st, texobj, msamp, sampler); + st_convert_sampler(st, texobj, msamp, ctx->Texture.Unit[texUnit].LodBias, + sampler); - sampler->lod_bias += ctx->Texture.Unit[texUnit].LodBias; sampler->seamless_cube_map |= ctx->Texture.CubeMapSeamless; } @@ -265,38 +254,42 @@ update_shader_samplers(struct st_context *st, enum pipe_shader_type shader_stage, const struct gl_program *prog, struct pipe_sampler_state *samplers, - unsigned *num_samplers) + unsigned *out_num_samplers) { + struct gl_context *ctx = st->ctx; GLbitfield samplers_used = prog->SamplersUsed; GLbitfield free_slots = ~prog->SamplersUsed; GLbitfield external_samplers_used = prog->ExternalSamplersUsed; - GLuint unit; - const GLuint old_max = *num_samplers; + unsigned unit, num_samplers; + struct pipe_sampler_state local_samplers[PIPE_MAX_SAMPLERS]; const struct pipe_sampler_state *states[PIPE_MAX_SAMPLERS]; - if (samplers_used == 0x0) + if (samplers_used == 0x0) { + if (out_num_samplers) + *out_num_samplers = 0; return; + } + + if (!samplers) + samplers = local_samplers; - *num_samplers = 0; + num_samplers = util_last_bit(samplers_used); /* loop over sampler units (aka tex image units) */ for (unit = 0; samplers_used; unit++, samplers_used >>= 1) { struct pipe_sampler_state *sampler = samplers + unit; + unsigned tex_unit = prog->SamplerUnits[unit]; - if (samplers_used & 1) { - const GLuint texUnit = prog->SamplerUnits[unit]; - - st_convert_sampler_from_unit(st, sampler, texUnit); + /* Don't update the sampler for TBOs. cso_context will not bind sampler + * states that are NULL. + */ + if (samplers_used & 1 && + ctx->Texture.Unit[tex_unit]._Current->Target != GL_TEXTURE_BUFFER) { + st_convert_sampler_from_unit(st, sampler, tex_unit); states[unit] = sampler; - *num_samplers = unit + 1; - } - else if (samplers_used != 0 || unit < old_max) { + } else { states[unit] = NULL; } - else { - /* if we've reset all the old samplers and we have no more new ones */ - break; - } } /* For any external samplers with multiplaner YUV, stuff the additional @@ -311,11 +304,16 @@ update_shader_samplers(struct st_context *st, st_get_texture_object(st->ctx, prog, unit); struct pipe_sampler_state *sampler = samplers + unit; - if (!stObj) + /* if resource format matches then YUV wasn't lowered */ + if (!stObj || st_get_view_format(stObj) == stObj->pt->format) continue; switch (st_get_view_format(stObj)) { case PIPE_FORMAT_NV12: + case PIPE_FORMAT_P010: + case PIPE_FORMAT_P016: + case PIPE_FORMAT_YUYV: + case PIPE_FORMAT_UYVY: /* we need one additional sampler: */ extra = u_bit_scan(&free_slots); states[extra] = sampler; @@ -331,10 +329,13 @@ update_shader_samplers(struct st_context *st, break; } - *num_samplers = MAX2(*num_samplers, extra + 1); + num_samplers = MAX2(num_samplers, extra + 1); } - cso_set_samplers(st->cso_context, shader_stage, *num_samplers, states); + cso_set_samplers(st->cso_context, shader_stage, num_samplers, states); + + if (out_num_samplers) + *out_num_samplers = num_samplers; } @@ -346,8 +347,8 @@ st_update_vertex_samplers(struct st_context *st) update_shader_samplers(st, PIPE_SHADER_VERTEX, ctx->VertexProgram._Current, - st->state.samplers[PIPE_SHADER_VERTEX], - &st->state.num_samplers[PIPE_SHADER_VERTEX]); + st->state.vert_samplers, + &st->state.num_vert_samplers); } @@ -359,9 +360,7 @@ st_update_tessctrl_samplers(struct st_context *st) if (ctx->TessCtrlProgram._Current) { update_shader_samplers(st, PIPE_SHADER_TESS_CTRL, - ctx->TessCtrlProgram._Current, - st->state.samplers[PIPE_SHADER_TESS_CTRL], - &st->state.num_samplers[PIPE_SHADER_TESS_CTRL]); + ctx->TessCtrlProgram._Current, NULL, NULL); } } @@ -374,9 +373,7 @@ st_update_tesseval_samplers(struct st_context *st) if (ctx->TessEvalProgram._Current) { update_shader_samplers(st, PIPE_SHADER_TESS_EVAL, - ctx->TessEvalProgram._Current, - st->state.samplers[PIPE_SHADER_TESS_EVAL], - &st->state.num_samplers[PIPE_SHADER_TESS_EVAL]); + ctx->TessEvalProgram._Current, NULL, NULL); } } @@ -389,9 +386,7 @@ st_update_geometry_samplers(struct st_context *st) if (ctx->GeometryProgram._Current) { update_shader_samplers(st, PIPE_SHADER_GEOMETRY, - ctx->GeometryProgram._Current, - st->state.samplers[PIPE_SHADER_GEOMETRY], - &st->state.num_samplers[PIPE_SHADER_GEOMETRY]); + ctx->GeometryProgram._Current, NULL, NULL); } } @@ -404,8 +399,8 @@ st_update_fragment_samplers(struct st_context *st) update_shader_samplers(st, PIPE_SHADER_FRAGMENT, ctx->FragmentProgram._Current, - st->state.samplers[PIPE_SHADER_FRAGMENT], - &st->state.num_samplers[PIPE_SHADER_FRAGMENT]); + st->state.frag_samplers, + &st->state.num_frag_samplers); } @@ -417,8 +412,6 @@ st_update_compute_samplers(struct st_context *st) if (ctx->ComputeProgram._Current) { update_shader_samplers(st, PIPE_SHADER_COMPUTE, - ctx->ComputeProgram._Current, - st->state.samplers[PIPE_SHADER_COMPUTE], - &st->state.num_samplers[PIPE_SHADER_COMPUTE]); + ctx->ComputeProgram._Current, NULL, NULL); } }