X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fsvga%2Fsvga_pipe_sampler.c;h=8a87bb467aa45e042d1fb6aea0e9da132aa88cff;hb=615a356ee38d882e9f073dba0b8918a903094124;hp=78053e755e288d644cbcb1674b66ef055a2acffa;hpb=b46bcd8e7b37aa2e9159e126c1cc88234a3c2790;p=mesa.git diff --git a/src/gallium/drivers/svga/svga_pipe_sampler.c b/src/gallium/drivers/svga/svga_pipe_sampler.c index 78053e755e2..8a87bb467aa 100644 --- a/src/gallium/drivers/svga/svga_pipe_sampler.c +++ b/src/gallium/drivers/svga/svga_pipe_sampler.c @@ -23,18 +23,15 @@ * **********************************************************/ -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_defines.h" +#include "util/u_format.h" #include "util/u_math.h" #include "util/u_memory.h" -#include "util/u_pack_color.h" #include "tgsi/tgsi_parse.h" #include "svga_context.h" -#include "svga_screen_texture.h" -#include "svga_state.h" - -#include "svga_hw_reg.h" +#include "svga_resource_texture.h" #include "svga_debug.h" @@ -76,7 +73,6 @@ static INLINE unsigned translate_img_filter( unsigned filter ) switch (filter) { case PIPE_TEX_FILTER_NEAREST: return SVGA3D_TEX_FILTER_NEAREST; case PIPE_TEX_FILTER_LINEAR: return SVGA3D_TEX_FILTER_LINEAR; - case PIPE_TEX_FILTER_ANISO: return SVGA3D_TEX_FILTER_ANISOTROPIC; default: assert(0); return SVGA3D_TEX_FILTER_NEAREST; @@ -101,12 +97,16 @@ svga_create_sampler_state(struct pipe_context *pipe, { struct svga_context *svga = svga_context(pipe); struct svga_sampler_state *cso = CALLOC_STRUCT( svga_sampler_state ); - union util_color uc; + if (!cso) + return NULL; + cso->mipfilter = translate_mip_filter(sampler->min_mip_filter); cso->magfilter = translate_img_filter( sampler->mag_img_filter ); cso->minfilter = translate_img_filter( sampler->min_img_filter ); - cso->aniso_level = MAX2( (unsigned) sampler->max_anisotropy, 1 ); + cso->aniso_level = MAX2( sampler->max_anisotropy, 1 ); + if(sampler->max_anisotropy) + cso->magfilter = cso->minfilter = SVGA3D_TEX_FILTER_ANISOTROPIC; cso->lod_bias = sampler->lod_bias; cso->addressu = translate_wrap_mode(sampler->wrap_s); cso->addressv = translate_wrap_mode(sampler->wrap_t); @@ -116,22 +116,20 @@ svga_create_sampler_state(struct pipe_context *pipe, cso->compare_func = sampler->compare_func; { - ubyte r = float_to_ubyte(sampler->border_color[0]); - ubyte g = float_to_ubyte(sampler->border_color[1]); - ubyte b = float_to_ubyte(sampler->border_color[2]); - ubyte a = float_to_ubyte(sampler->border_color[3]); - - util_pack_color_ub( r, g, b, a, - PIPE_FORMAT_B8G8R8A8_UNORM, &uc); - cso->bordercolor = uc.ui; + uint32 r = float_to_ubyte(sampler->border_color.f[0]); + uint32 g = float_to_ubyte(sampler->border_color.f[1]); + uint32 b = float_to_ubyte(sampler->border_color.f[2]); + uint32 a = float_to_ubyte(sampler->border_color.f[3]); + + cso->bordercolor = (a << 24) | (r << 16) | (g << 8) | b; } /* No SVGA3D support for: * - min/max LOD clamping */ cso->min_lod = 0; - cso->view_min_lod = MAX2(sampler->min_lod, 0); - cso->view_max_lod = MAX2(sampler->max_lod, 0); + cso->view_min_lod = MAX2((int) (sampler->min_lod + 0.5), 0); + cso->view_max_lod = MAX2((int) (sampler->max_lod + 0.5), 0); /* Use min_mipmap */ if (svga->debug.use_min_mipmap) { @@ -150,31 +148,38 @@ svga_create_sampler_state(struct pipe_context *pipe, return cso; } -static void svga_bind_sampler_states(struct pipe_context *pipe, - unsigned num, void **sampler) +static void +svga_bind_sampler_states(struct pipe_context *pipe, + unsigned shader, + unsigned start, + unsigned num, + void **samplers) { struct svga_context *svga = svga_context(pipe); unsigned i; - assert(num <= PIPE_MAX_SAMPLERS); + assert(shader < PIPE_SHADER_TYPES); + assert(start + num <= PIPE_MAX_SAMPLERS); - /* Check for no-op */ - if (num == svga->curr.num_samplers && - !memcmp(svga->curr.sampler, sampler, num * sizeof(void *))) { - debug_printf("sampler noop\n"); + /* we only support fragment shader samplers at this time */ + if (shader != PIPE_SHADER_FRAGMENT) return; - } for (i = 0; i < num; i++) - svga->curr.sampler[i] = sampler[i]; + svga->curr.sampler[start + i] = samplers[i]; - for (i = num; i < svga->curr.num_samplers; i++) - svga->curr.sampler[i] = NULL; + /* find highest non-null sampler[] entry */ + { + unsigned j = MAX2(svga->curr.num_samplers, start + num); + while (j > 0 && svga->curr.sampler[j - 1] == NULL) + j--; + svga->curr.num_samplers = j; + } - svga->curr.num_samplers = num; svga->dirty |= SVGA_NEW_SAMPLER; } + static void svga_delete_sampler_state(struct pipe_context *pipe, void *sampler) { @@ -182,43 +187,81 @@ static void svga_delete_sampler_state(struct pipe_context *pipe, } -static void svga_set_sampler_textures(struct pipe_context *pipe, - unsigned num, - struct pipe_texture **texture) +static struct pipe_sampler_view * +svga_create_sampler_view(struct pipe_context *pipe, + struct pipe_resource *texture, + const struct pipe_sampler_view *templ) +{ + struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view); + + if (view) { + *view = *templ; + view->reference.count = 1; + view->texture = NULL; + pipe_resource_reference(&view->texture, texture); + view->context = pipe; + } + + return view; +} + + +static void +svga_sampler_view_destroy(struct pipe_context *pipe, + struct pipe_sampler_view *view) +{ + pipe_resource_reference(&view->texture, NULL); + FREE(view); +} + +static void +svga_set_sampler_views(struct pipe_context *pipe, + unsigned shader, + unsigned start, + unsigned num, + struct pipe_sampler_view **views) { struct svga_context *svga = svga_context(pipe); unsigned flag_1d = 0; unsigned flag_srgb = 0; uint i; - assert(num <= PIPE_MAX_SAMPLERS); + assert(shader < PIPE_SHADER_TYPES); + assert(start + num <= Elements(svga->curr.sampler_views)); - /* Check for no-op */ - if (num == svga->curr.num_textures && - !memcmp(svga->curr.texture, texture, num * sizeof(struct pipe_texture *))) { - if (0) debug_printf("texture noop\n"); + /* we only support fragment shader sampler views at this time */ + if (shader != PIPE_SHADER_FRAGMENT) return; - } for (i = 0; i < num; i++) { - pipe_texture_reference(&svga->curr.texture[i], - texture[i]); + if (svga->curr.sampler_views[start + i] != views[i]) { + /* Note: we're using pipe_sampler_view_release() here to work around + * a possible crash when the old view belongs to another context that + * was already destroyed. + */ + pipe_sampler_view_release(pipe, &svga->curr.sampler_views[start + i]); + pipe_sampler_view_reference(&svga->curr.sampler_views[start + i], + views[i]); + } - if (!texture[i]) + if (!views[i]) continue; - if (texture[i]->format == PIPE_FORMAT_A8R8G8B8_SRGB) - flag_srgb |= 1 << i; + if (util_format_is_srgb(views[i]->format)) + flag_srgb |= 1 << (start + i); - if (texture[i]->target == PIPE_TEXTURE_1D) - flag_1d |= 1 << i; + if (views[i]->texture->target == PIPE_TEXTURE_1D) + flag_1d |= 1 << (start + i); } - for (i = num; i < svga->curr.num_textures; i++) - pipe_texture_reference(&svga->curr.texture[i], - NULL); + /* find highest non-null sampler_views[] entry */ + { + unsigned j = MAX2(svga->curr.num_sampler_views, start + num); + while (j > 0 && svga->curr.sampler_views[j - 1] == NULL) + j--; + svga->curr.num_sampler_views = j; + } - svga->curr.num_textures = num; svga->dirty |= SVGA_NEW_TEXTURE_BINDING; if (flag_srgb != svga->curr.tex_flags.flag_srgb || @@ -231,13 +274,14 @@ static void svga_set_sampler_textures(struct pipe_context *pipe, } - void svga_init_sampler_functions( struct svga_context *svga ) { svga->pipe.create_sampler_state = svga_create_sampler_state; - svga->pipe.bind_fragment_sampler_states = svga_bind_sampler_states; + svga->pipe.bind_sampler_states = svga_bind_sampler_states; svga->pipe.delete_sampler_state = svga_delete_sampler_state; - svga->pipe.set_fragment_sampler_textures = svga_set_sampler_textures; + svga->pipe.set_sampler_views = svga_set_sampler_views; + svga->pipe.create_sampler_view = svga_create_sampler_view; + svga->pipe.sampler_view_destroy = svga_sampler_view_destroy; }