X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fi915%2Fi915_state.c;h=d0063e3901aed6a9d77b69d2f6b2b006caf4899b;hb=175adf0776d8df066a908b06055f243bd1325a34;hp=b31cc306a441469ebefffd8383cee2ac59e8078a;hpb=832029e1c1c027e8f697cc8fdc75902e3c24f38a;p=mesa.git diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c index b31cc306a44..d0063e3901a 100644 --- a/src/gallium/drivers/i915/i915_state.c +++ b/src/gallium/drivers/i915/i915_state.c @@ -33,6 +33,7 @@ #include "util/u_inlines.h" #include "util/u_math.h" #include "util/u_memory.h" +#include "util/u_transfer.h" #include "tgsi/tgsi_parse.h" #include "i915_context.h" @@ -57,10 +58,8 @@ translate_wrap_mode(unsigned wrap) return TEXCOORDMODE_CLAMP_EDGE; case PIPE_TEX_WRAP_CLAMP_TO_BORDER: return TEXCOORDMODE_CLAMP_BORDER; - /* - case PIPE_TEX_WRAP_MIRRORED_REPEAT: + case PIPE_TEX_WRAP_MIRROR_REPEAT: return TEXCOORDMODE_MIRROR; - */ default: return TEXCOORDMODE_WRAP; } @@ -147,6 +146,7 @@ i915_create_blend_state(struct pipe_context *pipe, if (blend->dither) cso_data->LIS5 |= S5_COLOR_DITHER_ENABLE; + /* XXX here take the target fixup into account */ if ((blend->rt[0].colormask & PIPE_MASK_R) == 0) cso_data->LIS5 |= S5_WRITEDISABLE_RED; @@ -223,12 +223,12 @@ i915_create_sampler_state(struct pipe_context *pipe, unsigned minFilt, magFilt; unsigned mipFilt; - cso->templ = sampler; + cso->templ = *sampler; mipFilt = translate_mip_filter(sampler->min_mip_filter); minFilt = translate_img_filter( sampler->min_img_filter ); magFilt = translate_img_filter( sampler->mag_img_filter ); - + if (sampler->max_anisotropy > 1) minFilt = magFilt = FILTER_ANISOTROPIC; @@ -244,10 +244,10 @@ i915_create_sampler_state(struct pipe_context *pipe, /* Shadow: */ - if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) + if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { cso->state[0] |= (SS2_SHADOW_ENABLE | - i915_translate_compare_func(sampler->compare_func)); + i915_translate_shadow_compare_func(sampler->compare_func)); minFilt = FILTER_4X4_FLAT; magFilt = FILTER_4X4_FLAT; @@ -279,16 +279,58 @@ i915_create_sampler_state(struct pipe_context *pipe, } { - 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]); + ubyte r = float_to_ubyte(sampler->border_color.f[0]); + ubyte g = float_to_ubyte(sampler->border_color.f[1]); + ubyte b = float_to_ubyte(sampler->border_color.f[2]); + ubyte a = float_to_ubyte(sampler->border_color.f[3]); cso->state[2] = I915PACKCOLOR8888(r, g, b, a); } return cso; } -static void i915_bind_sampler_states(struct pipe_context *pipe, +static void i915_fixup_bind_sampler_states(struct pipe_context *pipe, + unsigned num, void **sampler) +{ + struct i915_context *i915 = i915_context(pipe); + + i915->saved_nr_samplers = num; + memcpy(&i915->saved_samplers, sampler, sizeof(void *) * num); + + i915->saved_bind_sampler_states(pipe, num, sampler); +} + +static void +i915_bind_vertex_sampler_states(struct pipe_context *pipe, + unsigned num_samplers, + void **samplers) +{ + struct i915_context *i915 = i915_context(pipe); + unsigned i; + + assert(num_samplers <= PIPE_MAX_VERTEX_SAMPLERS); + + /* Check for no-op */ + if (num_samplers == i915->num_vertex_samplers && + !memcmp(i915->vertex_samplers, samplers, num_samplers * sizeof(void *))) + return; + + draw_flush(i915->draw); + + for (i = 0; i < num_samplers; ++i) + i915->vertex_samplers[i] = samplers[i]; + for (i = num_samplers; i < PIPE_MAX_VERTEX_SAMPLERS; ++i) + i915->vertex_samplers[i] = NULL; + + i915->num_vertex_samplers = num_samplers; + + draw_set_samplers(i915->draw, + i915->vertex_samplers, + i915->num_vertex_samplers); +} + + + +static void i915_bind_fragment_sampler_states(struct pipe_context *pipe, unsigned num, void **sampler) { struct i915_context *i915 = i915_context(pipe); @@ -318,6 +360,76 @@ static void i915_delete_sampler_state(struct pipe_context *pipe, } +/** + * Called before drawing VBO to map vertex samplers and hand them to draw + */ +void +i915_prepare_vertex_sampling(struct i915_context *i915) +{ + struct i915_winsys *iws = i915->iws; + unsigned i,j; + uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS]; + uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS]; + const void* data[PIPE_MAX_TEXTURE_LEVELS]; + unsigned num = i915->num_vertex_sampler_views; + struct pipe_sampler_view **views = i915->vertex_sampler_views; + + assert(num <= PIPE_MAX_VERTEX_SAMPLERS); + if (!num) + return; + + for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { + struct pipe_sampler_view *view = i < num ? views[i] : NULL; + + if (view) { + struct pipe_resource *tex = view->texture; + struct i915_texture *i915_tex = i915_texture(tex); + ubyte *addr; + + /* We're referencing the texture's internal data, so save a + * reference to it. + */ + pipe_resource_reference(&i915->mapped_vs_tex[i], tex); + + i915->mapped_vs_tex_buffer[i] = i915_tex->buffer; + addr = iws->buffer_map(iws, + i915_tex->buffer, + FALSE /* read only */); + + /* Setup array of mipmap level pointers */ + /* FIXME: handle 3D textures? */ + for (j = view->u.tex.first_level; j <= tex->last_level; j++) { + unsigned offset = i915_texture_offset(i915_tex, j , 0 /* FIXME depth */); + data[j] = addr + offset; + row_stride[j] = i915_tex->stride; + img_stride[j] = 0; /* FIXME */; + } + + draw_set_mapped_texture(i915->draw, + i, + tex->width0, tex->height0, tex->depth0, + view->u.tex.first_level, tex->last_level, + row_stride, img_stride, data); + } else + i915->mapped_vs_tex[i] = NULL; + } +} + +void +i915_cleanup_vertex_sampling(struct i915_context *i915) +{ + struct i915_winsys *iws = i915->iws; + unsigned i; + for (i = 0; i < Elements(i915->mapped_vs_tex); i++) { + if (i915->mapped_vs_tex_buffer[i]) { + iws->buffer_unmap(iws, i915->mapped_vs_tex_buffer[i]); + pipe_resource_reference(&i915->mapped_vs_tex[i], NULL); + } + } +} + + + /** XXX move someday? Or consolidate all these simple state setters * into one file. */ @@ -456,6 +568,7 @@ i915_create_fs_state(struct pipe_context *pipe, if (!ifs) return NULL; + ifs->draw_data = draw_create_fragment_shader(i915->draw, templ); ifs->state.tokens = tgsi_dup_tokens(templ->tokens); tgsi_scan_shader(templ->tokens, &ifs->info); @@ -466,6 +579,17 @@ i915_create_fs_state(struct pipe_context *pipe, return ifs; } +static void +i915_fixup_bind_fs_state(struct pipe_context *pipe, void *shader) +{ + struct i915_context *i915 = i915_context(pipe); + draw_flush(i915->draw); + + i915->saved_fs = shader; + + i915->saved_bind_fs_state(pipe, shader); +} + static void i915_bind_fs_state(struct pipe_context *pipe, void *shader) { @@ -474,6 +598,8 @@ i915_bind_fs_state(struct pipe_context *pipe, void *shader) i915->fs = (struct i915_fragment_shader*) shader; + draw_bind_fragment_shader(i915->draw, (i915->fs ? i915->fs->draw_data : NULL)); + i915->dirty |= I915_NEW_FS; } @@ -482,11 +608,19 @@ void i915_delete_fs_state(struct pipe_context *pipe, void *shader) { struct i915_fragment_shader *ifs = (struct i915_fragment_shader *) shader; - if (ifs->program) + if (ifs->decl) { + FREE(ifs->decl); + ifs->decl = NULL; + } + + if (ifs->program) { FREE(ifs->program); + ifs->program = NULL; + FREE((struct tgsi_token *)ifs->state.tokens); + ifs->state.tokens = NULL; + } ifs->program_len = 0; - - FREE((struct tgsi_token *)ifs->state.tokens); + ifs->decl_len = 0; FREE(ifs); } @@ -506,6 +640,8 @@ static void i915_bind_vs_state(struct pipe_context *pipe, void *shader) { struct i915_context *i915 = i915_context(pipe); + i915->saved_vs = shader; + /* just pass-through to draw module */ draw_bind_vertex_shader(i915->draw, (struct draw_vertex_shader *) shader); @@ -572,6 +708,27 @@ static void i915_set_constant_buffer(struct pipe_context *pipe, } +static void +i915_fixup_set_fragment_sampler_views(struct pipe_context *pipe, + unsigned num, + struct pipe_sampler_view **views) +{ + struct i915_context *i915 = i915_context(pipe); + int i; + + for (i = 0; i < num; i++) + pipe_sampler_view_reference(&i915->saved_sampler_views[i], + views[i]); + + for (i = num; i < i915->saved_nr_sampler_views; i++) + pipe_sampler_view_reference(&i915->saved_sampler_views[i], + NULL); + + i915->saved_nr_sampler_views = num; + + i915->saved_set_sampler_views(pipe, num, views); +} + static void i915_set_fragment_sampler_views(struct pipe_context *pipe, unsigned num, struct pipe_sampler_view **views) @@ -602,6 +759,37 @@ static void i915_set_fragment_sampler_views(struct pipe_context *pipe, i915->dirty |= I915_NEW_SAMPLER_VIEW; } +static void +i915_set_vertex_sampler_views(struct pipe_context *pipe, + unsigned num, + struct pipe_sampler_view **views) +{ + struct i915_context *i915 = i915_context(pipe); + uint i; + + assert(num <= PIPE_MAX_VERTEX_SAMPLERS); + + /* Check for no-op */ + if (num == i915->num_vertex_sampler_views && + !memcmp(i915->vertex_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) { + return; + } + + draw_flush(i915->draw); + + for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { + struct pipe_sampler_view *view = i < num ? views[i] : NULL; + + pipe_sampler_view_reference(&i915->vertex_sampler_views[i], view); + } + + i915->num_vertex_sampler_views = num; + + draw_set_sampler_views(i915->draw, + i915->vertex_sampler_views, + i915->num_vertex_sampler_views); +} + static struct pipe_sampler_view * i915_create_sampler_view(struct pipe_context *pipe, @@ -643,7 +831,8 @@ static void i915_set_framebuffer_state(struct pipe_context *pipe, i915->framebuffer.height = fb->height; i915->framebuffer.nr_cbufs = fb->nr_cbufs; for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { - pipe_surface_reference(&i915->framebuffer.cbufs[i], fb->cbufs[i]); + pipe_surface_reference(&i915->framebuffer.cbufs[i], + i < fb->nr_cbufs ? fb->cbufs[i] : NULL); } pipe_surface_reference(&i915->framebuffer.zsbuf, fb->zsbuf); @@ -658,6 +847,8 @@ static void i915_set_clip_state( struct pipe_context *pipe, struct i915_context *i915 = i915_context(pipe); draw_flush(i915->draw); + i915->saved_clip = *clip; + draw_set_clip_state(i915->draw, clip); i915->dirty |= I915_NEW_CLIP; @@ -688,7 +879,7 @@ i915_create_rasterizer_state(struct pipe_context *pipe, { struct i915_rasterizer_state *cso = CALLOC_STRUCT( i915_rasterizer_state ); - cso->templ = rasterizer; + cso->templ = *rasterizer; cso->color_interp = rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR; cso->light_twoside = rasterizer->light_twoside; cso->ds[0].u = _3DSTATE_DEPTH_OFFSET_SCALE; @@ -759,7 +950,7 @@ static void i915_bind_rasterizer_state( struct pipe_context *pipe, /* pass-through to draw module */ draw_set_rasterizer_state(i915->draw, - (i915->rasterizer ? i915->rasterizer->templ : NULL), + (i915->rasterizer ? &(i915->rasterizer->templ) : NULL), raster); i915->dirty |= I915_NEW_RASTERIZER; @@ -779,6 +970,9 @@ static void i915_set_vertex_buffers(struct pipe_context *pipe, struct draw_context *draw = i915->draw; int i; + util_copy_vertex_buffers(i915->saved_vertex_buffers, + &i915->saved_nr_vertex_buffers, + buffers, count); #if 0 /* XXX doesn't look like this is needed */ /* unmap old */ @@ -819,6 +1013,8 @@ i915_bind_vertex_elements_state(struct pipe_context *pipe, struct i915_context *i915 = i915_context(pipe); struct i915_velems_state *i915_velems = (struct i915_velems_state *) velems; + i915->saved_velems = velems; + /* pass-through to draw module */ if (i915_velems) { draw_set_vertex_elements(i915->draw, @@ -860,7 +1056,8 @@ i915_init_state_functions( struct i915_context *i915 ) i915->base.delete_blend_state = i915_delete_blend_state; i915->base.create_sampler_state = i915_create_sampler_state; - i915->base.bind_fragment_sampler_states = i915_bind_sampler_states; + i915->base.bind_fragment_sampler_states = i915_bind_fragment_sampler_states; + i915->base.bind_vertex_sampler_states = i915_bind_vertex_sampler_states; i915->base.delete_sampler_state = i915_delete_sampler_state; i915->base.create_depth_stencil_alpha_state = i915_create_depth_stencil_state; @@ -890,9 +1087,22 @@ i915_init_state_functions( struct i915_context *i915 ) i915->base.set_polygon_stipple = i915_set_polygon_stipple; i915->base.set_scissor_state = i915_set_scissor_state; i915->base.set_fragment_sampler_views = i915_set_fragment_sampler_views; + i915->base.set_vertex_sampler_views = i915_set_vertex_sampler_views; i915->base.create_sampler_view = i915_create_sampler_view; i915->base.sampler_view_destroy = i915_sampler_view_destroy; i915->base.set_viewport_state = i915_set_viewport_state; i915->base.set_vertex_buffers = i915_set_vertex_buffers; i915->base.set_index_buffer = i915_set_index_buffer; + i915->base.redefine_user_buffer = u_default_redefine_user_buffer; +} + +void +i915_init_fixup_state_functions( struct i915_context *i915 ) +{ + i915->saved_bind_fs_state = i915->base.bind_fs_state; + i915->base.bind_fs_state = i915_fixup_bind_fs_state; + i915->saved_bind_sampler_states = i915->base.bind_fragment_sampler_states; + i915->base.bind_fragment_sampler_states = i915_fixup_bind_sampler_states; + i915->saved_set_sampler_views = i915->base.set_fragment_sampler_views; + i915->base.set_fragment_sampler_views = i915_fixup_set_fragment_sampler_views; }