From 7373bc0e0294d68bc3e64f4a6de1bb4ec3132f02 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 4 Nov 2009 15:59:56 +0000 Subject: [PATCH] i965g: hook up pipe sampler callbacks --- src/gallium/drivers/i965/Makefile | 1 + src/gallium/drivers/i965/brw_context.h | 2 +- src/gallium/drivers/i965/brw_pipe_sampler.c | 177 +++++++++++------- src/gallium/drivers/i965/brw_wm.c | 2 +- .../drivers/i965/brw_wm_sampler_state.c | 4 +- .../drivers/i965/brw_wm_surface_state.c | 2 +- 6 files changed, 120 insertions(+), 68 deletions(-) diff --git a/src/gallium/drivers/i965/Makefile b/src/gallium/drivers/i965/Makefile index b42d9a92c4a..8603907dc2c 100644 --- a/src/gallium/drivers/i965/Makefile +++ b/src/gallium/drivers/i965/Makefile @@ -32,6 +32,7 @@ C_SOURCES = \ brw_pipe_shader.c \ brw_pipe_flush.c \ brw_pipe_misc.c \ + brw_pipe_sampler.c \ brw_pipe_rast.c \ brw_sf.c \ brw_sf_emit.c \ diff --git a/src/gallium/drivers/i965/brw_context.h b/src/gallium/drivers/i965/brw_context.h index a4c48e6fd21..b6f77d12539 100644 --- a/src/gallium/drivers/i965/brw_context.h +++ b/src/gallium/drivers/i965/brw_context.h @@ -505,7 +505,7 @@ struct brw_context unsigned num_vertex_elements; unsigned num_samplers; - struct brw_texture *texture[PIPE_MAX_SAMPLERS]; + struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; unsigned num_textures; unsigned num_vertex_buffers; diff --git a/src/gallium/drivers/i965/brw_pipe_sampler.c b/src/gallium/drivers/i965/brw_pipe_sampler.c index 56cf95c4cd2..f0a765ecf5e 100644 --- a/src/gallium/drivers/i965/brw_pipe_sampler.c +++ b/src/gallium/drivers/i965/brw_pipe_sampler.c @@ -1,5 +1,7 @@ #include "util/u_memory.h" +#include "util/u_math.h" + #include "pipe/p_context.h" #include "pipe/p_state.h" @@ -39,119 +41,166 @@ static GLuint translate_wrap_mode( unsigned wrap ) } } +static GLuint translate_img_filter( unsigned filter ) +{ + switch (filter) { + case PIPE_TEX_FILTER_NEAREST: + return BRW_MAPFILTER_NEAREST; + case PIPE_TEX_FILTER_LINEAR: + return BRW_MAPFILTER_LINEAR; + case PIPE_TEX_FILTER_ANISO: + return BRW_MAPFILTER_ANISOTROPIC; + default: + assert(0); + return BRW_MAPFILTER_NEAREST; + } +} - -static void *brw_create_sampler_state( struct pipe_context *pipe, - const struct pipe_sampler_state *templ ) +static GLuint translate_mip_filter( unsigned filter ) { - struct brw_sampler_state *sampler = CALLOC_STRUCT(brw_sampler_state); + switch (filter) { + case PIPE_TEX_MIPFILTER_NONE: + return BRW_MIPFILTER_NONE; + case PIPE_TEX_MIPFILTER_NEAREST: + return BRW_MIPFILTER_NEAREST; + case PIPE_TEX_MIPFILTER_LINEAR: + return BRW_MIPFILTER_LINEAR; + default: + assert(0); + return BRW_MIPFILTER_NONE; + } +} - switch (key->minfilter) { - case GL_NEAREST: - sampler->ss0.min_filter = BRW_MAPFILTER_NEAREST; - sampler->ss0.mip_filter = BRW_MIPFILTER_NONE; - break; - case GL_LINEAR: - sampler->ss0.min_filter = BRW_MAPFILTER_LINEAR; - sampler->ss0.mip_filter = BRW_MIPFILTER_NONE; - break; - case GL_NEAREST_MIPMAP_NEAREST: - sampler->ss0.min_filter = BRW_MAPFILTER_NEAREST; - sampler->ss0.mip_filter = BRW_MIPFILTER_NEAREST; - break; - case GL_LINEAR_MIPMAP_NEAREST: - sampler->ss0.min_filter = BRW_MAPFILTER_LINEAR; - sampler->ss0.mip_filter = BRW_MIPFILTER_NEAREST; - break; - case GL_NEAREST_MIPMAP_LINEAR: - sampler->ss0.min_filter = BRW_MAPFILTER_NEAREST; - sampler->ss0.mip_filter = BRW_MIPFILTER_LINEAR; - break; - case GL_LINEAR_MIPMAP_LINEAR: - sampler->ss0.min_filter = BRW_MAPFILTER_LINEAR; - sampler->ss0.mip_filter = BRW_MIPFILTER_LINEAR; - break; +/* XXX: not sure why there are special translations for the shadow tex + * compare functions. In particular ALWAYS is translated to NEVER. + * Is this a hardware issue? Does i965 really suffer from this? + */ +static GLuint translate_shadow_compare_func( unsigned func ) +{ + switch (func) { + case PIPE_FUNC_NEVER: + return BRW_COMPAREFUNCTION_ALWAYS; + case PIPE_FUNC_LESS: + return BRW_COMPAREFUNCTION_LEQUAL; + case PIPE_FUNC_LEQUAL: + return BRW_COMPAREFUNCTION_LESS; + case PIPE_FUNC_GREATER: + return BRW_COMPAREFUNCTION_GEQUAL; + case PIPE_FUNC_GEQUAL: + return BRW_COMPAREFUNCTION_GREATER; + case PIPE_FUNC_NOTEQUAL: + return BRW_COMPAREFUNCTION_EQUAL; + case PIPE_FUNC_EQUAL: + return BRW_COMPAREFUNCTION_NOTEQUAL; + case PIPE_FUNC_ALWAYS: + return BRW_COMPAREFUNCTION_NEVER; default: - break; + assert(0); + return BRW_COMPAREFUNCTION_NEVER; } +} + + + + +static void * +brw_create_sampler_state( struct pipe_context *pipe, + const struct pipe_sampler_state *template ) +{ + struct brw_sampler_state *sampler = CALLOC_STRUCT(brw_sampler_state); + + sampler->ss0.min_filter = translate_img_filter( template->min_img_filter ); + sampler->ss0.mag_filter = translate_img_filter( template->mag_img_filter ); + sampler->ss0.mip_filter = translate_mip_filter( template->min_mip_filter ); - /* Set Anisotropy: + + /* XXX: anisotropy logic slightly changed: */ - if (key->max_aniso > 1.0) { + if (template->max_anisotropy > 1.0) { sampler->ss0.min_filter = BRW_MAPFILTER_ANISOTROPIC; sampler->ss0.mag_filter = BRW_MAPFILTER_ANISOTROPIC; - if (key->max_aniso > 2.0) { - sampler->ss3.max_aniso = MIN2((key->max_aniso - 2) / 2, + if (template->max_anisotropy > 2.0) { + sampler->ss3.max_aniso = MIN2((template->max_anisotropy - 2) / 2, BRW_ANISORATIO_16); } } - else { - switch (key->magfilter) { - case GL_NEAREST: - sampler->ss0.mag_filter = BRW_MAPFILTER_NEAREST; - break; - case GL_LINEAR: - sampler->ss0.mag_filter = BRW_MAPFILTER_LINEAR; - break; - default: - break; - } - } - sampler->ss1.r_wrap_mode = translate_wrap_mode(key->wrap_r); - sampler->ss1.s_wrap_mode = translate_wrap_mode(key->wrap_s); - sampler->ss1.t_wrap_mode = translate_wrap_mode(key->wrap_t); + sampler->ss1.r_wrap_mode = translate_wrap_mode(template->wrap_r); + sampler->ss1.s_wrap_mode = translate_wrap_mode(template->wrap_s); + sampler->ss1.t_wrap_mode = translate_wrap_mode(template->wrap_t); /* Set LOD bias: */ - sampler->ss0.lod_bias = S_FIXED(CLAMP(key->lod_bias, -16, 15), 6); + sampler->ss0.lod_bias = + util_signed_fixed(CLAMP(template->lod_bias, -16, 15), 6); + sampler->ss0.lod_preclamp = 1; /* OpenGL mode */ sampler->ss0.default_color_mode = 0; /* OpenGL/DX10 mode */ /* Set shadow function: */ - if (key->comparemode == GL_COMPARE_R_TO_TEXTURE_ARB) { + if (template->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { + /* Shadowing is "enabled" by emitting a particular sampler * message (sample_c). So need to recompile WM program when * shadow comparison is enabled on each/any texture unit. */ sampler->ss0.shadow_function = - intel_translate_shadow_compare_func(key->comparefunc); + translate_shadow_compare_func(template->compare_func); } /* Set BaseMipLevel, MaxLOD, MinLOD: */ - sampler->ss0.base_level = U_FIXED(0, 1); + sampler->ss0.base_level = + util_unsigned_fixed(0, 1); + + sampler->ss1.max_lod = + util_unsigned_fixed(CLAMP(template->max_lod, 0, 13), 6); - sampler->ss1.max_lod = U_FIXED(MIN2(MAX2(key->maxlod, 0), 13), 6); - sampler->ss1.min_lod = U_FIXED(MIN2(MAX2(key->minlod, 0), 13), 6); + sampler->ss1.min_lod = + util_unsigned_fixed(CLAMP(template->min_lod, 0, 13), 6); return (void *)sampler; } static void brw_bind_sampler_state(struct pipe_context *pipe, - void *cso) + unsigned num, void **sampler) { struct brw_context *brw = brw_context(pipe); - brw->curr.sampler = (const struct brw_sampler_state *)cso; - brw->state.dirty.mesa |= PIPE_NEW_SAMPLER; + int i; + + for (i = 0; i < num; i++) + brw->curr.sampler[i] = sampler[i]; + + for (i = num; i < brw->curr.num_samplers; i++) + brw->curr.sampler[i] = NULL; + + brw->curr.num_samplers = num; + brw->state.dirty.mesa |= PIPE_NEW_SAMPLERS; } static void brw_delete_sampler_state(struct pipe_context *pipe, void *cso) { - struct brw_context *brw = brw_context(pipe); FREE(cso); } static void brw_set_sampler_textures(struct pipe_context *pipe, - unsigned num_textures, - struct pipe_texture **tex) + unsigned num, + struct pipe_texture **texture) { struct brw_context *brw = brw_context(pipe); + int i; + for (i = 0; i < num; i++) + pipe_texture_reference(&brw->curr.texture[i], texture[i]); + + for (i = num; i < brw->curr.num_textures; i++) + pipe_texture_reference(&brw->curr.texture[i], NULL); + + brw->curr.num_textures = num; brw->state.dirty.mesa |= PIPE_NEW_BOUND_TEXTURES; } @@ -160,8 +209,10 @@ void brw_pipe_sampler_init( struct brw_context *brw ) { brw->base.set_sampler_textures = brw_set_sampler_textures; brw->base.create_sampler_state = brw_create_sampler_state; - brw->base.bind_sampler_state = brw_bind_sampler_state; - brw->base.destroy_sampler_state = brw_destroy_sampler_state; + brw->base.bind_sampler_states = brw_bind_sampler_state; + brw->base.delete_sampler_state = brw_delete_sampler_state; + + brw->base.set_sampler_textures = brw_set_sampler_textures; } void brw_pipe_sampler_cleanup( struct brw_context *brw ) diff --git a/src/gallium/drivers/i965/brw_wm.c b/src/gallium/drivers/i965/brw_wm.c index 4fbf9de9bbc..90780272da5 100644 --- a/src/gallium/drivers/i965/brw_wm.c +++ b/src/gallium/drivers/i965/brw_wm.c @@ -248,7 +248,7 @@ static void brw_wm_populate_key( struct brw_context *brw, /* PIPE_NEW_BOUND_TEXTURES */ for (i = 0; i < brw->curr.num_textures; i++) { - const struct brw_texture *tex = brw->curr.texture[i]; + const struct brw_texture *tex = brw_texture(brw->curr.texture[i]); if (tex->base.format == PIPE_FORMAT_YCBCR) key->yuvtex_mask |= 1 << i; diff --git a/src/gallium/drivers/i965/brw_wm_sampler_state.c b/src/gallium/drivers/i965/brw_wm_sampler_state.c index 2909dd38765..2fddb4ad897 100644 --- a/src/gallium/drivers/i965/brw_wm_sampler_state.c +++ b/src/gallium/drivers/i965/brw_wm_sampler_state.c @@ -75,7 +75,7 @@ brw_wm_sampler_populate_key(struct brw_context *brw, brw->curr.num_samplers); for (i = 0; i < key->sampler_count; i++) { - const struct brw_texture *tex = brw->curr.texture[i]; + const struct brw_texture *tex = brw_texture(brw->curr.texture[i]); const struct brw_sampler *sampler = brw->curr.sampler[i]; struct brw_sampler_state *entry = &key->sampler[i]; @@ -119,7 +119,7 @@ brw_wm_sampler_update_default_colors(struct brw_context *brw) int i; for (i = 0; i < nr; i++) { - const struct brw_texture *tex = brw->curr.texture[i]; + const struct brw_texture *tex = brw_texture(brw->curr.texture[i]); const struct brw_sampler *sampler = brw->curr.sampler[i]; brw->sws->bo_unreference(brw->wm.sdc_bo[i]); diff --git a/src/gallium/drivers/i965/brw_wm_surface_state.c b/src/gallium/drivers/i965/brw_wm_surface_state.c index e5a0ed7d611..6c29db045fc 100644 --- a/src/gallium/drivers/i965/brw_wm_surface_state.c +++ b/src/gallium/drivers/i965/brw_wm_surface_state.c @@ -201,7 +201,7 @@ static int prepare_wm_surfaces(struct brw_context *brw ) */ for (i = 0; i < brw->curr.num_textures; i++) { brw_update_texture_surface(brw, - brw->curr.texture[i], + brw_texture(brw->curr.texture[i]), nr_surfaces++); } -- 2.30.2