From: Dave Airlie Date: Sat, 14 May 2011 08:04:08 +0000 (+1000) Subject: st/mesa: overhaul vertex/fragment sampler and sampler views. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c9aa3bbda44470c0a92c675abf4bbab83aba3fb7;p=mesa.git st/mesa: overhaul vertex/fragment sampler and sampler views. This fixes piglits fragment-and-vertex-texturing test on llvmpipe for me. I've no idea if someone had another plan for this that is smarter than what I've done here, but what I've basically done is split fragment and vertex sampler and sampler_view setup function, factor out the common chunks of both. side-cleanups: drop st->state.sampler_list - unused don't update border color if we have no border color. should fix https://bugs.freedesktop.org/show_bug.cgi?id=35849 Signed-off-by: Dave Airlie Reviewed-by: Brian Paul --- diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c index e3d6cbb8e12..ccbd5489226 100644 --- a/src/mesa/state_tracker/st_atom_sampler.c +++ b/src/mesa/state_tracker/st_atom_sampler.c @@ -120,14 +120,110 @@ gl_filter_to_img_filter(GLenum filter) } } +static void convert_sampler(struct st_context *st, + struct pipe_sampler_state *sampler, + GLuint texUnit) +{ + struct gl_texture_object *texobj; + struct gl_sampler_object *msamp; + + texobj = st->ctx->Texture.Unit[texUnit]._Current; + if (!texobj) { + texobj = st_get_default_texture(st); + } + + msamp = _mesa_get_samplerobj(st->ctx, texUnit); + sampler->wrap_s = gl_wrap_xlate(msamp->WrapS); + sampler->wrap_t = gl_wrap_xlate(msamp->WrapT); + sampler->wrap_r = gl_wrap_xlate(msamp->WrapR); + + sampler->min_img_filter = gl_filter_to_img_filter(msamp->MinFilter); + sampler->min_mip_filter = gl_filter_to_mip_filter(msamp->MinFilter); + sampler->mag_img_filter = gl_filter_to_img_filter(msamp->MagFilter); + + if (texobj->Target != GL_TEXTURE_RECTANGLE_ARB) + sampler->normalized_coords = 1; + + sampler->lod_bias = st->ctx->Texture.Unit[texUnit].LodBias + + msamp->LodBias; + + sampler->min_lod = CLAMP(msamp->MinLod, + 0.0f, + (GLfloat) texobj->MaxLevel - texobj->BaseLevel); + sampler->max_lod = MIN2((GLfloat) texobj->MaxLevel - texobj->BaseLevel, + msamp->MaxLod); + if (sampler->max_lod < sampler->min_lod) { + /* The GL spec doesn't seem to specify what to do in this case. + * Swap the values. + */ + float tmp = sampler->max_lod; + sampler->max_lod = sampler->min_lod; + sampler->min_lod = tmp; + assert(sampler->min_lod <= sampler->max_lod); + } + + if (msamp->BorderColor.ui[0] || + msamp->BorderColor.ui[1] || + msamp->BorderColor.ui[2] || + msamp->BorderColor.ui[3]) { + struct gl_texture_image *teximg; + + teximg = texobj->Image[0][texobj->BaseLevel]; + + st_translate_color(msamp->BorderColor.f, + teximg ? teximg->_BaseFormat : GL_RGBA, + sampler->border_color); + } + + sampler->max_anisotropy = (msamp->MaxAnisotropy == 1.0 ? + 0 : (GLuint) msamp->MaxAnisotropy); + + /* only care about ARB_shadow, not SGI shadow */ + if (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); + } + + sampler->seamless_cube_map = + st->ctx->Texture.CubeMapSeamless || msamp->CubeMapSeamless; +} -static void -update_samplers(struct st_context *st) +static void +update_vertex_samplers(struct st_context *st) { struct gl_vertex_program *vprog = st->ctx->VertexProgram._Current; + GLuint su; + + st->state.num_vertex_samplers = 0; + + /* loop over sampler units (aka tex image units) */ + for (su = 0; su < st->ctx->Const.MaxVertexTextureImageUnits; su++) { + struct pipe_sampler_state *sampler = st->state.vertex_samplers + su; + + memset(sampler, 0, sizeof(*sampler)); + + if (vprog->Base.SamplersUsed & (1 << su)) { + GLuint texUnit; + + texUnit = vprog->Base.SamplerUnits[su]; + + convert_sampler(st, sampler, texUnit); + + st->state.num_vertex_samplers = su + 1; + + cso_single_vertex_sampler(st->cso_context, su, sampler); + } else { + cso_single_vertex_sampler(st->cso_context, su, NULL); + } + } + cso_single_vertex_sampler_done(st->cso_context); +} + +static void +update_fragment_samplers(struct st_context *st) +{ struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current; - const GLbitfield samplersUsed = (vprog->Base.SamplersUsed | - fprog->Base.SamplersUsed); GLuint su; st->state.num_samplers = 0; @@ -138,95 +234,33 @@ update_samplers(struct st_context *st) memset(sampler, 0, sizeof(*sampler)); - if (samplersUsed & (1 << su)) { - struct gl_texture_object *texobj; - struct gl_texture_image *teximg; - struct gl_sampler_object *msamp; + if (fprog->Base.SamplersUsed & (1 << su)) { 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); - } - - teximg = texobj->Image[0][texobj->BaseLevel]; - - msamp = _mesa_get_samplerobj(st->ctx, texUnit); - - sampler->wrap_s = gl_wrap_xlate(msamp->WrapS); - sampler->wrap_t = gl_wrap_xlate(msamp->WrapT); - sampler->wrap_r = gl_wrap_xlate(msamp->WrapR); - - sampler->min_img_filter = gl_filter_to_img_filter(msamp->MinFilter); - sampler->min_mip_filter = gl_filter_to_mip_filter(msamp->MinFilter); - sampler->mag_img_filter = gl_filter_to_img_filter(msamp->MagFilter); - - if (texobj->Target != GL_TEXTURE_RECTANGLE_ARB) - sampler->normalized_coords = 1; - - sampler->lod_bias = st->ctx->Texture.Unit[texUnit].LodBias + - msamp->LodBias; - - sampler->min_lod = CLAMP(msamp->MinLod, - 0.0f, - (GLfloat) texobj->MaxLevel - texobj->BaseLevel); - sampler->max_lod = MIN2((GLfloat) texobj->MaxLevel - texobj->BaseLevel, - msamp->MaxLod); - if (sampler->max_lod < sampler->min_lod) { - /* The GL spec doesn't seem to specify what to do in this case. - * Swap the values. - */ - float tmp = sampler->max_lod; - sampler->max_lod = sampler->min_lod; - sampler->min_lod = tmp; - assert(sampler->min_lod <= sampler->max_lod); - } - - st_translate_color(msamp->BorderColor.f, - teximg ? teximg->_BaseFormat : GL_RGBA, - sampler->border_color); - - sampler->max_anisotropy = (msamp->MaxAnisotropy == 1.0 ? - 0 : (GLuint) msamp->MaxAnisotropy); - - /* only care about ARB_shadow, not SGI shadow */ - if (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); - } - - sampler->seamless_cube_map = - st->ctx->Texture.CubeMapSeamless || msamp->CubeMapSeamless; + texUnit = fprog->Base.SamplerUnits[su]; + + convert_sampler(st, sampler, texUnit); st->state.num_samplers = su + 1; /*printf("%s su=%u non-null\n", __FUNCTION__, su);*/ cso_single_sampler(st->cso_context, su, sampler); - if (su < st->ctx->Const.MaxVertexTextureImageUnits) { - cso_single_vertex_sampler(st->cso_context, su, sampler); - } } else { /*printf("%s su=%u null\n", __FUNCTION__, su);*/ cso_single_sampler(st->cso_context, su, NULL); - if (su < st->ctx->Const.MaxVertexTextureImageUnits) { - cso_single_vertex_sampler(st->cso_context, su, NULL); - } } } cso_single_sampler_done(st->cso_context); - if (st->ctx->Const.MaxVertexTextureImageUnits > 0) { - cso_single_vertex_sampler_done(st->cso_context); - } } +static void +update_samplers(struct st_context *st) +{ + update_fragment_samplers(st); + update_vertex_samplers(st); +} const struct st_tracked_state st_update_sampler = { "st_update_sampler", /* name */ diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c index 9d437ad086f..990b50438f0 100644 --- a/src/mesa/state_tracker/st_atom_texture.c +++ b/src/mesa/state_tracker/st_atom_texture.c @@ -182,90 +182,132 @@ st_get_texture_sampler_view_from_stobj(struct st_texture_object *stObj, return stObj->sampler_view; } +static GLboolean +update_single_texture(struct st_context *st, struct pipe_sampler_view **sampler_view, + GLuint texUnit) +{ + struct pipe_context *pipe = st->pipe; + const struct gl_sampler_object *samp; + struct gl_texture_object *texObj; + struct st_texture_object *stObj; + enum pipe_format st_view_format; + GLboolean retval; + + samp = _mesa_get_samplerobj(st->ctx, texUnit); + + texObj = st->ctx->Texture.Unit[texUnit]._Current; + + if (!texObj) { + texObj = st_get_default_texture(st); + samp = &texObj->Sampler; + } + stObj = st_texture_object(texObj); + + retval = st_finalize_texture(st->ctx, st->pipe, texObj); + if (!retval) { + /* out of mem */ + return GL_FALSE; + } + + /* Determine the format of the texture sampler view */ + st_view_format = stObj->pt->format; + { + const struct st_texture_image *firstImage = + st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]); + const gl_format texFormat = firstImage->base.TexFormat; + enum pipe_format firstImageFormat = + st_mesa_format_to_pipe_format(texFormat); + + if ((samp->sRGBDecode == GL_SKIP_DECODE_EXT) && + (_mesa_get_format_color_encoding(texFormat) == GL_SRGB)) { + /* don't do sRGB->RGB conversion. Interpret the texture + * texture data as linear values. + */ + const gl_format linearFormat = + _mesa_get_srgb_format_linear(texFormat); + firstImageFormat = st_mesa_format_to_pipe_format(linearFormat); + } + + if (firstImageFormat != stObj->pt->format) + st_view_format = firstImageFormat; + } + + + /* if sampler view has changed dereference it */ + if (stObj->sampler_view) { + if (check_sampler_swizzle(stObj->sampler_view, + stObj->base._Swizzle, + samp->DepthMode) || + (st_view_format != stObj->sampler_view->format) || + stObj->base.BaseLevel != stObj->sampler_view->u.tex.first_level) { + pipe_sampler_view_reference(&stObj->sampler_view, NULL); + } + } + + *sampler_view = st_get_texture_sampler_view_from_stobj(stObj, pipe, + samp, + st_view_format); + return GL_TRUE; +} static void -update_textures(struct st_context *st) +update_vertex_textures(struct st_context *st) { - struct pipe_context *pipe = st->pipe; 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; + st->state.num_vertex_textures = 0; /* loop over sampler units (aka tex image units) */ for (su = 0; su < st->ctx->Const.MaxTextureImageUnits; su++) { struct pipe_sampler_view *sampler_view = NULL; - enum pipe_format st_view_format; - if (samplersUsed & (1 << su)) { - struct gl_texture_object *texObj; - struct st_texture_object *stObj; + if (vprog->Base.SamplersUsed & (1 << su)) { GLboolean retval; GLuint texUnit; - const struct gl_sampler_object *samp; - if (fprog->Base.SamplersUsed & (1 << su)) - texUnit = fprog->Base.SamplerUnits[su]; - else - texUnit = vprog->Base.SamplerUnits[su]; + texUnit = vprog->Base.SamplerUnits[su]; - samp = _mesa_get_samplerobj(st->ctx, texUnit); + retval = update_single_texture(st, &sampler_view, texUnit); + if (retval == GL_FALSE) + continue; - texObj = st->ctx->Texture.Unit[texUnit]._Current; + st->state.num_vertex_textures = su + 1; - if (!texObj) { - texObj = st_get_default_texture(st); - samp = &texObj->Sampler; - } - stObj = st_texture_object(texObj); + } + pipe_sampler_view_reference(&st->state.sampler_vertex_views[su], sampler_view); + } - retval = st_finalize_texture(st->ctx, st->pipe, texObj); - if (!retval) { - /* out of mem */ - continue; - } + if (st->ctx->Const.MaxVertexTextureImageUnits > 0) { + GLuint numUnits = MIN2(st->state.num_vertex_textures, + st->ctx->Const.MaxVertexTextureImageUnits); + cso_set_vertex_sampler_views(st->cso_context, + numUnits, + st->state.sampler_vertex_views); + } +} - /* Determine the format of the texture sampler view */ - st_view_format = stObj->pt->format; - { - const struct st_texture_image *firstImage = - st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]); - const gl_format texFormat = firstImage->base.TexFormat; - enum pipe_format firstImageFormat = - st_mesa_format_to_pipe_format(texFormat); - - if ((samp->sRGBDecode == GL_SKIP_DECODE_EXT) && - (_mesa_get_format_color_encoding(texFormat) == GL_SRGB)) { - /* don't do sRGB->RGB conversion. Interpret the texture - * texture data as linear values. - */ - const gl_format linearFormat = - _mesa_get_srgb_format_linear(texFormat); - firstImageFormat = st_mesa_format_to_pipe_format(linearFormat); - } - - if (firstImageFormat != stObj->pt->format) - st_view_format = firstImageFormat; - } +static void +update_fragment_textures(struct st_context *st) +{ + struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current; + GLuint su; - st->state.num_textures = su + 1; + st->state.num_textures = 0; - /* if sampler view has changed dereference it */ - if (stObj->sampler_view) { - if (check_sampler_swizzle(stObj->sampler_view, - stObj->base._Swizzle, - samp->DepthMode) || - (st_view_format != stObj->sampler_view->format) || - stObj->base.BaseLevel != stObj->sampler_view->u.tex.first_level) { - pipe_sampler_view_reference(&stObj->sampler_view, NULL); - } - } + /* loop over sampler units (aka tex image units) */ + for (su = 0; su < st->ctx->Const.MaxTextureImageUnits; su++) { + struct pipe_sampler_view *sampler_view = NULL; + if (fprog->Base.SamplersUsed & (1 << su)) { + GLboolean retval; + GLuint texUnit; + + texUnit = fprog->Base.SamplerUnits[su]; - sampler_view = st_get_texture_sampler_view_from_stobj(stObj, pipe, - samp, - st_view_format); + retval = update_single_texture(st, &sampler_view, texUnit); + if (retval == GL_FALSE) + continue; + + st->state.num_textures = su + 1; } pipe_sampler_view_reference(&st->state.sampler_views[su], sampler_view); } @@ -273,16 +315,14 @@ update_textures(struct st_context *st) cso_set_fragment_sampler_views(st->cso_context, st->state.num_textures, st->state.sampler_views); - - if (st->ctx->Const.MaxVertexTextureImageUnits > 0) { - GLuint numUnits = MIN2(st->state.num_textures, - st->ctx->Const.MaxVertexTextureImageUnits); - cso_set_vertex_sampler_views(st->cso_context, - numUnits, - st->state.sampler_views); - } } +static void +update_textures(struct st_context *st) +{ + update_fragment_textures(st); + update_vertex_textures(st); +} const struct st_tracked_state st_update_texture = { "st_update_texture", /* name */ @@ -293,9 +333,6 @@ const struct st_tracked_state st_update_texture = { update_textures /* update */ }; - - - static void finalize_textures(struct st_context *st) { diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index ce78956e359..6eddbfc88e4 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -133,9 +133,6 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe ) else st->internal_target = PIPE_TEXTURE_RECT; - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) - st->state.sampler_list[i] = &st->state.samplers[i]; - for (i = 0; i < 3; i++) { memset(&st->velems_util_draw[i], 0, sizeof(struct pipe_vertex_element)); st->velems_util_draw[i].src_offset = i * 4 * sizeof(float); diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 1fc9c1051a0..c6fc31801d6 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -90,7 +90,7 @@ struct st_context struct pipe_depth_stencil_alpha_state depth_stencil; struct pipe_rasterizer_state rasterizer; struct pipe_sampler_state samplers[PIPE_MAX_SAMPLERS]; - struct pipe_sampler_state *sampler_list[PIPE_MAX_SAMPLERS]; + struct pipe_sampler_state vertex_samplers[PIPE_MAX_VERTEX_SAMPLERS]; struct pipe_clip_state clip; struct { void *ptr; @@ -98,12 +98,15 @@ struct st_context } constants[PIPE_SHADER_TYPES]; struct pipe_framebuffer_state framebuffer; struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS]; + struct pipe_sampler_view *sampler_vertex_views[PIPE_MAX_VERTEX_SAMPLERS]; struct pipe_scissor_state scissor; struct pipe_viewport_state viewport; unsigned sample_mask; GLuint num_samplers; + GLuint num_vertex_samplers; GLuint num_textures; + GLuint num_vertex_textures; GLuint poly_stipple[32]; /**< In OpenGL's bottom-to-top order */ } state;