X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fi915%2Fi915_state.c;h=54c343cf2bfb4c7187ab7ae5fa50e386802e1542;hb=e7b4219e2287f98a323b6883ce5f42545cab0e8f;hp=764547e3e064a145a4e899a7c1808ae197147cd3;hpb=3cff45fdb182a1327f6b89fdc4e0ddc5d680372a;p=mesa.git diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c index 764547e3e06..54c343cf2bf 100644 --- a/src/gallium/drivers/i915/i915_state.c +++ b/src/gallium/drivers/i915/i915_state.c @@ -30,6 +30,7 @@ #include "draw/draw_context.h" +#include "util/u_helpers.h" #include "util/u_inlines.h" #include "util/u_math.h" #include "util/u_memory.h" @@ -93,7 +94,6 @@ static unsigned translate_mip_filter( unsigned filter ) } } - /* None of this state is actually used for anything yet. */ static void * @@ -116,10 +116,10 @@ i915_create_blend_state(struct pipe_context *pipe, */ if (srcA != srcRGB || - dstA != dstRGB || - eqA != eqRGB) { + dstA != dstRGB || + eqA != eqRGB) { - cso_data->iab = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | + cso_data->iab = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | IAB_MODIFY_ENABLE | IAB_ENABLE | IAB_MODIFY_FUNC | @@ -130,7 +130,7 @@ i915_create_blend_state(struct pipe_context *pipe, (i915_translate_blend_func(eqA) << IAB_FUNC_SHIFT)); } else { - cso_data->iab = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | + cso_data->iab = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | IAB_MODIFY_ENABLE | 0); } @@ -146,7 +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 */ + /* We potentially do some fixup at emission for non-BGRA targets */ if ((blend->rt[0].colormask & PIPE_MASK_R) == 0) cso_data->LIS5 |= S5_WRITEDISABLE_RED; @@ -177,7 +177,9 @@ static void i915_bind_blend_state(struct pipe_context *pipe, void *blend) { struct i915_context *i915 = i915_context(pipe); - draw_flush(i915->draw); + + if (i915->blend == blend) + return; i915->blend = (struct i915_blend_state*)blend; @@ -194,7 +196,9 @@ static void i915_set_blend_color( struct pipe_context *pipe, const struct pipe_blend_color *blend_color ) { struct i915_context *i915 = i915_context(pipe); - draw_flush(i915->draw); + + if (!blend_color) + return; i915->blend_color = *blend_color; @@ -205,7 +209,6 @@ static void i915_set_stencil_ref( struct pipe_context *pipe, const struct pipe_stencil_ref *stencil_ref ) { struct i915_context *i915 = i915_context(pipe); - draw_flush(i915->draw); i915->stencil_ref = *stencil_ref; @@ -272,7 +275,7 @@ i915_create_sampler_state(struct pipe_context *pipe, maxlod = CLAMP(maxlod, 0, 16 * 11); if (minlod > maxlod) - maxlod = minlod; + maxlod = minlod; cso->minlod = minlod; cso->maxlod = maxlod; @@ -288,42 +291,36 @@ i915_create_sampler_state(struct pipe_context *pipe, return cso; } -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, + unsigned start, + unsigned num, void **samplers) { struct i915_context *i915 = i915_context(pipe); unsigned i; - assert(num_samplers <= PIPE_MAX_VERTEX_SAMPLERS); + assert(start + num <= Elements(i915->vertex_samplers)); /* Check for no-op */ - if (num_samplers == i915->num_vertex_samplers && - !memcmp(i915->vertex_samplers, samplers, num_samplers * sizeof(void *))) + if (num == i915->num_vertex_samplers && + !memcmp(i915->vertex_samplers + start, samplers, + num * 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; + for (i = 0; i < num; ++i) + i915->vertex_samplers[i + start] = samplers[i]; - i915->num_vertex_samplers = num_samplers; + /* find highest non-null samplers[] entry */ + { + unsigned j = MAX2(i915->num_vertex_samplers, start + num); + while (j > 0 && i915->vertex_samplers[j - 1] == NULL) + j--; + i915->num_vertex_samplers = j; + } draw_set_samplers(i915->draw, + PIPE_SHADER_VERTEX, i915->vertex_samplers, i915->num_vertex_samplers); } @@ -331,28 +328,52 @@ i915_bind_vertex_sampler_states(struct pipe_context *pipe, static void i915_bind_fragment_sampler_states(struct pipe_context *pipe, - unsigned num, void **sampler) + unsigned start, + unsigned num, + void **samplers) { struct i915_context *i915 = i915_context(pipe); unsigned i; /* Check for no-op */ if (num == i915->num_samplers && - !memcmp(i915->sampler, sampler, num * sizeof(void *))) + !memcmp(i915->fragment_sampler + start, samplers, + num * sizeof(void *))) return; - draw_flush(i915->draw); - for (i = 0; i < num; ++i) - i915->sampler[i] = sampler[i]; - for (i = num; i < PIPE_MAX_SAMPLERS; ++i) - i915->sampler[i] = NULL; + i915->fragment_sampler[i + start] = samplers[i]; - i915->num_samplers = num; + /* find highest non-null samplers[] entry */ + { + unsigned j = MAX2(i915->num_samplers, start + num); + while (j > 0 && i915->fragment_sampler[j - 1] == NULL) + j--; + i915->num_samplers = j; + } i915->dirty |= I915_NEW_SAMPLER; } + +static void +i915_bind_sampler_states(struct pipe_context *pipe, unsigned shader, + unsigned start, unsigned num_samplers, + void **samplers) +{ + switch (shader) { + case PIPE_SHADER_VERTEX: + i915_bind_vertex_sampler_states(pipe, start, num_samplers, samplers); + break; + case PIPE_SHADER_FRAGMENT: + i915_bind_fragment_sampler_states(pipe, start, num_samplers, samplers); + break; + default: + ; + } +} + + static void i915_delete_sampler_state(struct pipe_context *pipe, void *sampler) { @@ -370,15 +391,15 @@ i915_prepare_vertex_sampling(struct i915_context *i915) 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]; + uint32_t mip_offsets[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); + assert(num <= PIPE_MAX_SAMPLERS); if (!num) return; - for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { struct pipe_sampler_view *view = i < num ? views[i] : NULL; if (view) { @@ -391,25 +412,26 @@ i915_prepare_vertex_sampling(struct i915_context *i915) */ pipe_resource_reference(&i915->mapped_vs_tex[i], tex); - i915->mapped_vs_tex_buffer[i] = i915_tex->buffer; + 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? */ + /* 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; + mip_offsets[j] = i915_texture_offset(i915_tex, j , 0 /* FIXME depth */); row_stride[j] = i915_tex->stride; img_stride[j] = 0; /* FIXME */; } draw_set_mapped_texture(i915->draw, + PIPE_SHADER_VERTEX, i, tex->width0, tex->height0, tex->depth0, view->u.tex.first_level, tex->last_level, - row_stride, img_stride, data); + addr, + row_stride, img_stride, mip_offsets); } else i915->mapped_vs_tex[i] = NULL; } @@ -508,7 +530,7 @@ i915_create_depth_stencil_state(struct pipe_context *pipe, (func << S6_DEPTH_TEST_FUNC_SHIFT)); if (depth_stencil->depth.writemask) - cso->depth_LIS6 |= S6_DEPTH_WRITE_ENABLE; + cso->depth_LIS6 |= S6_DEPTH_WRITE_ENABLE; } if (depth_stencil->alpha.enabled) { @@ -527,7 +549,9 @@ static void i915_bind_depth_stencil_state(struct pipe_context *pipe, void *depth_stencil) { struct i915_context *i915 = i915_context(pipe); - draw_flush(i915->draw); + + if (i915->depth_stencil == depth_stencil) + return; i915->depth_stencil = (const struct i915_depth_stencil_state *)depth_stencil; @@ -541,11 +565,12 @@ static void i915_delete_depth_stencil_state(struct pipe_context *pipe, } -static void i915_set_scissor_state( struct pipe_context *pipe, +static void i915_set_scissor_states( struct pipe_context *pipe, + unsigned start_slot, + unsigned num_scissors, const struct pipe_scissor_state *scissor ) { struct i915_context *i915 = i915_context(pipe); - draw_flush(i915->draw); memcpy( &i915->scissor, scissor, sizeof(*scissor) ); i915->dirty |= I915_NEW_SCISSOR; @@ -553,11 +578,8 @@ static void i915_set_scissor_state( struct pipe_context *pipe, static void i915_set_polygon_stipple( struct pipe_context *pipe, - const struct pipe_poly_stipple *stipple ) + const struct pipe_poly_stipple *stipple ) { - struct i915_context *i915 = i915_context(pipe); - - draw_flush(i915->draw); } @@ -582,22 +604,13 @@ 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) { struct i915_context *i915 = i915_context(pipe); - draw_flush(i915->draw); + + if (i915->fs == shader) + return; i915->fs = (struct i915_fragment_shader*) shader; @@ -611,10 +624,8 @@ void i915_delete_fs_state(struct pipe_context *pipe, void *shader) { struct i915_fragment_shader *ifs = (struct i915_fragment_shader *) shader; - if (ifs->decl) { - FREE(ifs->decl); - ifs->decl = NULL; - } + FREE(ifs->decl); + ifs->decl = NULL; if (ifs->program) { FREE(ifs->program); @@ -622,6 +633,7 @@ void i915_delete_fs_state(struct pipe_context *pipe, void *shader) FREE((struct tgsi_token *)ifs->state.tokens); ifs->state.tokens = NULL; } + ifs->program_len = 0; ifs->decl_len = 0; @@ -643,7 +655,10 @@ static void i915_bind_vs_state(struct pipe_context *pipe, void *shader) { struct i915_context *i915 = i915_context(pipe); - i915->saved_vs = shader; + if (i915->vs == shader) + return; + + i915->vs = shader; /* just pass-through to draw module */ draw_bind_vertex_shader(i915->draw, (struct draw_vertex_shader *) shader); @@ -661,17 +676,23 @@ static void i915_delete_vs_state(struct pipe_context *pipe, void *shader) static void i915_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - struct pipe_resource *buf) + struct pipe_constant_buffer *cb) { struct i915_context *i915 = i915_context(pipe); + struct pipe_resource *buf = cb ? cb->buffer : NULL; unsigned new_num = 0; boolean diff = TRUE; - /* XXX don't support geom shaders now */ if (shader == PIPE_SHADER_GEOMETRY) return; + if (cb && cb->user_buffer) { + buf = i915_user_buffer_create(pipe->screen, (void *) cb->user_buffer, + cb->buffer_size, + PIPE_BIND_CONSTANT_BUFFER); + } + /* if we have a new buffer compare it with the old one */ if (buf) { struct i915_buffer *ibuf = i915_buffer(buf); @@ -697,41 +718,18 @@ static void i915_set_constant_buffer(struct pipe_context *pipe, diff = i915->current.num_user_constants[shader] != 0; } - /* - * flush before updateing the state. - */ - if (diff && shader == PIPE_SHADER_FRAGMENT) - draw_flush(i915->draw); - pipe_resource_reference(&i915->constants[shader], buf); i915->current.num_user_constants[shader] = new_num; if (diff) i915->dirty |= shader == PIPE_SHADER_VERTEX ? I915_NEW_VS_CONSTANTS : I915_NEW_FS_CONSTANTS; -} - - -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); + if (cb && cb->user_buffer) { + pipe_resource_reference(&buf, NULL); + } } + static void i915_set_fragment_sampler_views(struct pipe_context *pipe, unsigned num, struct pipe_sampler_view **views) @@ -746,16 +744,18 @@ static void i915_set_fragment_sampler_views(struct pipe_context *pipe, !memcmp(i915->fragment_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) return; - /* Fixes wrong texture in texobj with VBUF */ - draw_flush(i915->draw); - - for (i = 0; i < num; i++) + for (i = 0; i < num; 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, &i915->fragment_sampler_views[i]); pipe_sampler_view_reference(&i915->fragment_sampler_views[i], views[i]); + } for (i = num; i < i915->num_fragment_sampler_views; i++) - pipe_sampler_view_reference(&i915->fragment_sampler_views[i], - NULL); + pipe_sampler_view_release(pipe, &i915->fragment_sampler_views[i]); i915->num_fragment_sampler_views = num; @@ -770,7 +770,7 @@ i915_set_vertex_sampler_views(struct pipe_context *pipe, struct i915_context *i915 = i915_context(pipe); uint i; - assert(num <= PIPE_MAX_VERTEX_SAMPLERS); + assert(num <= Elements(i915->vertex_sampler_views)); /* Check for no-op */ if (num == i915->num_vertex_sampler_views && @@ -778,9 +778,7 @@ i915_set_vertex_sampler_views(struct pipe_context *pipe, return; } - draw_flush(i915->draw); - - for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { + for (i = 0; i < Elements(i915->vertex_sampler_views); i++) { struct pipe_sampler_view *view = i < num ? views[i] : NULL; pipe_sampler_view_reference(&i915->vertex_sampler_views[i], view); @@ -789,11 +787,31 @@ i915_set_vertex_sampler_views(struct pipe_context *pipe, i915->num_vertex_sampler_views = num; draw_set_sampler_views(i915->draw, + PIPE_SHADER_VERTEX, i915->vertex_sampler_views, i915->num_vertex_sampler_views); } +static void +i915_set_sampler_views(struct pipe_context *pipe, unsigned shader, + unsigned start, unsigned num, + struct pipe_sampler_view **views) +{ + assert(start == 0); + switch (shader) { + case PIPE_SHADER_FRAGMENT: + i915_set_fragment_sampler_views(pipe, num, views); + break; + case PIPE_SHADER_VERTEX: + i915_set_vertex_sampler_views(pipe, num, views); + break; + default: + ; + } +} + + static struct pipe_sampler_view * i915_create_sampler_view(struct pipe_context *pipe, struct pipe_resource *texture, @@ -828,8 +846,6 @@ static void i915_set_framebuffer_state(struct pipe_context *pipe, struct i915_context *i915 = i915_context(pipe); int i; - draw_flush(i915->draw); - i915->framebuffer.width = fb->width; i915->framebuffer.height = fb->height; i915->framebuffer.nr_cbufs = fb->nr_cbufs; @@ -848,9 +864,8 @@ static void i915_set_clip_state( struct pipe_context *pipe, const struct pipe_clip_state *clip ) { struct i915_context *i915 = i915_context(pipe); - draw_flush(i915->draw); - i915->saved_clip = *clip; + i915->clip = *clip; draw_set_clip_state(i915->draw, clip); @@ -862,7 +877,9 @@ static void i915_set_clip_state( struct pipe_context *pipe, /* Called when driver state tracker notices changes to the viewport * matrix: */ -static void i915_set_viewport_state( struct pipe_context *pipe, +static void i915_set_viewport_states( struct pipe_context *pipe, + unsigned start_slot, + unsigned num_viewports, const struct pipe_viewport_state *viewport ) { struct i915_context *i915 = i915_context(pipe); @@ -870,7 +887,8 @@ static void i915_set_viewport_state( struct pipe_context *pipe, i915->viewport = *viewport; /* struct copy */ /* pass the viewport info to the draw module */ - draw_set_viewport_state(i915->draw, &i915->viewport); + draw_set_viewport_states(i915->draw, start_slot, num_viewports, + &i915->viewport); i915->dirty |= I915_NEW_VIEWPORT; } @@ -949,6 +967,9 @@ static void i915_bind_rasterizer_state( struct pipe_context *pipe, { struct i915_context *i915 = i915_context(pipe); + if (i915->rasterizer == raster) + return; + i915->rasterizer = (struct i915_rasterizer_state *)raster; /* pass-through to draw module */ @@ -966,32 +987,18 @@ static void i915_delete_rasterizer_state(struct pipe_context *pipe, } static void i915_set_vertex_buffers(struct pipe_context *pipe, - unsigned count, + unsigned start_slot, unsigned count, const struct pipe_vertex_buffer *buffers) { struct i915_context *i915 = i915_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 */ - for (i = 0; i < i915->num_vertex_buffers; i++) { - draw_set_mapped_vertex_buffer(draw, i, NULL); - } -#endif + util_set_vertex_buffers_count(i915->vertex_buffers, + &i915->nr_vertex_buffers, + buffers, start_slot, count); /* pass-through to draw module */ - draw_set_vertex_buffers(draw, count, buffers); - - /* map new */ - for (i = 0; i < count; i++) { - void *buf = i915_buffer(buffers[i].buffer)->data; - draw_set_mapped_vertex_buffer(draw, i, buf); - } + draw_set_vertex_buffers(draw, start_slot, count, buffers); } static void * @@ -1016,7 +1023,10 @@ 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; + if (i915->velems == velems) + return; + + i915->velems = velems; /* pass-through to draw module */ if (i915_velems) { @@ -1040,9 +1050,6 @@ static void i915_set_index_buffer(struct pipe_context *pipe, memcpy(&i915->index_buffer, ib, sizeof(i915->index_buffer)); else memset(&i915->index_buffer, 0, sizeof(i915->index_buffer)); - - /* pass-through to draw module */ - draw_set_index_buffer(i915->draw, ib); } static void @@ -1059,8 +1066,7 @@ 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_fragment_sampler_states; - i915->base.bind_vertex_sampler_states = i915_bind_vertex_sampler_states; + i915->base.bind_sampler_states = i915_bind_sampler_states; i915->base.delete_sampler_state = i915_delete_sampler_state; i915->base.create_depth_stencil_alpha_state = i915_create_depth_stencil_state; @@ -1088,24 +1094,11 @@ i915_init_state_functions( struct i915_context *i915 ) i915->base.set_framebuffer_state = i915_set_framebuffer_state; 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.set_scissor_states = i915_set_scissor_states; + i915->base.set_sampler_views = i915_set_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_viewport_states = i915_set_viewport_states; 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; }