From: Brian Paul Date: Mon, 19 Apr 2010 14:45:20 +0000 (-0600) Subject: Merge branch '7.8' X-Git-Url: https://git.libre-soc.org/?p=mesa.git;a=commitdiff_plain;h=8f3bdeaad610d7d5a5c6e73e1e9c721219595754 Merge branch '7.8' Conflicts: src/gallium/auxiliary/draw/draw_context.c src/gallium/auxiliary/draw/draw_pipe_aaline.c src/gallium/drivers/llvmpipe/lp_context.c --- 8f3bdeaad610d7d5a5c6e73e1e9c721219595754 diff --cc src/gallium/auxiliary/draw/draw_context.c index 99f4e6dd2a8,18435af8482..5726444c9b7 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@@ -44,24 -45,6 +45,26 @@@ struct draw_context *draw_create( struc if (draw == NULL) goto fail; + if (!draw_init(draw)) + goto fail; + ++ draw->pipe = pipe; ++ + return draw; + +fail: + draw_destroy( draw ); + return NULL; +} + +boolean draw_init(struct draw_context *draw) +{ + /* + * Note that several functions compute the clipmask of the predefined + * formats with hardcoded formulas instead of using these. So modifications + * here must be reflected there too. + */ + ASSIGN_4V( draw->plane[0], -1, 0, 0, 1 ); ASSIGN_4V( draw->plane[1], 1, 0, 0, 1 ); ASSIGN_4V( draw->plane[2], 0, -1, 0, 1 ); diff --cc src/gallium/auxiliary/draw/draw_pipe_aaline.c index e96dbecd262,72d7480efba..4faf0a779ca --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@@ -113,11 -111,8 +113,10 @@@ struct aaline_stag void (*driver_bind_sampler_states)(struct pipe_context *, unsigned, void **); - void (*driver_set_sampler_textures)(struct pipe_context *, unsigned, - struct pipe_texture **); ++ + void (*driver_set_sampler_views)(struct pipe_context *, + unsigned, + struct pipe_sampler_view **); - - struct pipe_context *pipe; }; @@@ -394,10 -390,9 +394,10 @@@ fail static boolean aaline_create_texture(struct aaline_stage *aaline) { - struct pipe_context *pipe = aaline->pipe; + struct pipe_context *pipe = aaline->stage.draw->pipe; struct pipe_screen *screen = pipe->screen; - struct pipe_texture texTemp; + struct pipe_resource texTemp; + struct pipe_sampler_view viewTempl; uint level; memset(&texTemp, 0, sizeof(texTemp)); @@@ -700,7 -680,12 +703,12 @@@ aaline_first_line(struct draw_stage *st draw->suspend_flushing = TRUE; aaline->driver_bind_sampler_states(pipe, num_samplers, aaline->state.sampler); - aaline->driver_set_sampler_textures(pipe, num_samplers, aaline->state.texture); + aaline->driver_set_sampler_views(pipe, num_samplers, aaline->state.sampler_views); + + /* Disable triangle culling, stippling, unfilled mode etc. */ + r = draw_get_rasterizer_no_cull(draw, rast->scissor, rast->flatshade); + pipe->bind_rasterizer_state(pipe, r); + draw->suspend_flushing = FALSE; /* now really draw first line */ @@@ -724,9 -709,14 +732,15 @@@ aaline_flush(struct draw_stage *stage, aaline->driver_bind_fs_state(pipe, aaline->fs->driver_fs); aaline->driver_bind_sampler_states(pipe, aaline->num_samplers, aaline->state.sampler); - aaline->driver_set_sampler_textures(pipe, aaline->num_textures, - aaline->state.texture); + aaline->driver_set_sampler_views(pipe, + aaline->num_sampler_views, + aaline->state.sampler_views); + + /* restore original rasterizer state */ + if (draw->rast_handle) { + pipe->bind_rasterizer_state(pipe, draw->rast_handle); + } + draw->suspend_flushing = FALSE; draw->extra_shader_outputs.slot = 0; @@@ -751,14 -742,10 +766,14 @@@ aaline_destroy(struct draw_stage *stage } if (aaline->sampler_cso) - aaline->pipe->delete_sampler_state(aaline->pipe, aaline->sampler_cso); + pipe->delete_sampler_state(pipe, aaline->sampler_cso); if (aaline->texture) - pipe_texture_reference(&aaline->texture, NULL); + pipe_resource_reference(&aaline->texture, NULL); + + if (aaline->sampler_view) { + pipe_sampler_view_reference(&aaline->sampler_view, NULL); + } draw_free_temp_verts( stage ); @@@ -880,15 -867,15 +896,15 @@@ aaline_set_sampler_views(struct pipe_co /* save current */ for (i = 0; i < num; i++) { - pipe_texture_reference(&aaline->state.texture[i], texture[i]); + pipe_sampler_view_reference(&aaline->state.sampler_views[i], views[i]); } for ( ; i < PIPE_MAX_SAMPLERS; i++) { - pipe_texture_reference(&aaline->state.texture[i], NULL); + pipe_sampler_view_reference(&aaline->state.sampler_views[i], NULL); } - aaline->num_textures = num; + aaline->num_sampler_views = num; /* pass-through */ - aaline->driver_set_sampler_views(aaline->pipe, num, views); - aaline->driver_set_sampler_textures(pipe, num, texture); ++ aaline->driver_set_sampler_views(pipe, num, views); } diff --cc src/gallium/drivers/llvmpipe/lp_context.c index 868e112ba3f,6962a7921bf..900740e02fa --- a/src/gallium/drivers/llvmpipe/lp_context.c +++ b/src/gallium/drivers/llvmpipe/lp_context.c @@@ -162,12 -174,8 +162,12 @@@ llvmpipe_create_context( struct pipe_sc /* * Create drawing context and plug our rendering stage into it. */ +#if USE_DRAW_LLVM - llvmpipe->draw = draw_create_with_llvm(); ++ llvmpipe->draw = draw_create_with_llvm(&llvmpipe->pipe); +#else - llvmpipe->draw = draw_create(); + llvmpipe->draw = draw_create(&llvmpipe->pipe); - if (!llvmpipe->draw) +#endif + if (!llvmpipe->draw) goto fail; /* FIXME: devise alternative to draw_texture_samplers */ diff --cc src/gallium/drivers/nv50/nv50_context.c index f543b3c504d,031cc128142..915a9254025 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@@ -95,9 -128,8 +95,9 @@@ nv50_create(struct pipe_screen *pscreen nv50_init_surface_functions(nv50); nv50_init_state_functions(nv50); nv50_init_query_functions(nv50); + nv50_init_resource_functions(&nv50->pipe); - nv50->draw = draw_create(); + nv50->draw = draw_create(&nv50->pipe); assert(nv50->draw); draw_set_rasterize_stage(nv50->draw, nv50_draw_render_stage(nv50)); diff --cc src/gallium/drivers/nvfx/nvfx_context.c index 1faa0af31fb,00000000000..6d2dc4d5bf6 mode 100644,000000..100644 --- a/src/gallium/drivers/nvfx/nvfx_context.c +++ b/src/gallium/drivers/nvfx/nvfx_context.c @@@ -1,84 -1,0 +1,84 @@@ +#include "draw/draw_context.h" +#include "pipe/p_defines.h" + +#include "nvfx_context.h" +#include "nvfx_screen.h" +#include "nvfx_resource.h" + +static void +nvfx_flush(struct pipe_context *pipe, unsigned flags, + struct pipe_fence_handle **fence) +{ + struct nvfx_context *nvfx = nvfx_context(pipe); + struct nvfx_screen *screen = nvfx->screen; + struct nouveau_channel *chan = screen->base.channel; + struct nouveau_grobj *eng3d = screen->eng3d; + + if (flags & PIPE_FLUSH_TEXTURE_CACHE) { + BEGIN_RING(chan, eng3d, 0x1fd8, 1); + OUT_RING (chan, 2); + BEGIN_RING(chan, eng3d, 0x1fd8, 1); + OUT_RING (chan, 1); + } + + FIRE_RING(chan); + if (fence) + *fence = NULL; +} + +static void +nvfx_destroy(struct pipe_context *pipe) +{ + struct nvfx_context *nvfx = nvfx_context(pipe); + + if (nvfx->draw) + draw_destroy(nvfx->draw); + FREE(nvfx); +} + +struct pipe_context * +nvfx_create(struct pipe_screen *pscreen, void *priv) +{ + struct nvfx_screen *screen = nvfx_screen(pscreen); + struct pipe_winsys *ws = pscreen->winsys; + struct nvfx_context *nvfx; + struct nouveau_winsys *nvws = screen->nvws; + + nvfx = CALLOC(1, sizeof(struct nvfx_context)); + if (!nvfx) + return NULL; + nvfx->screen = screen; + + nvfx->nvws = nvws; + + nvfx->pipe.winsys = ws; + nvfx->pipe.screen = pscreen; + nvfx->pipe.priv = priv; + nvfx->pipe.destroy = nvfx_destroy; + nvfx->pipe.draw_arrays = nvfx_draw_arrays; + nvfx->pipe.draw_elements = nvfx_draw_elements; + nvfx->pipe.clear = nvfx_clear; + nvfx->pipe.flush = nvfx_flush; + + screen->base.channel->user_private = nvfx; + + nvfx->is_nv4x = screen->is_nv4x; + + nvfx_init_query_functions(nvfx); + nvfx_init_surface_functions(nvfx); + nvfx_init_state_functions(nvfx); + nvfx_init_resource_functions(&nvfx->pipe); + + /* Create, configure, and install fallback swtnl path */ - nvfx->draw = draw_create(); ++ nvfx->draw = draw_create(&nvfx->pipe); + draw_wide_point_threshold(nvfx->draw, 9999999.0); + draw_wide_line_threshold(nvfx->draw, 9999999.0); + draw_enable_line_stipple(nvfx->draw, FALSE); + draw_enable_point_sprites(nvfx->draw, FALSE); + draw_set_rasterize_stage(nvfx->draw, nvfx_draw_render_stage(nvfx)); + + /* set these to that we init them on first validation */ + nvfx->state.scissor_enabled = ~0; + nvfx->state.stipple_enabled = ~0; + return &nvfx->pipe; +} diff --cc src/gallium/drivers/nvfx/nvfx_state_emit.c index 4137849bf0b,00000000000..f91ae19ecd3 mode 100644,000000..100644 --- a/src/gallium/drivers/nvfx/nvfx_state_emit.c +++ b/src/gallium/drivers/nvfx/nvfx_state_emit.c @@@ -1,179 -1,0 +1,180 @@@ +#include "nvfx_context.h" +#include "nvfx_state.h" +#include "draw/draw_context.h" + +static boolean +nvfx_state_validate_common(struct nvfx_context *nvfx) +{ + struct nouveau_channel* chan = nvfx->screen->base.channel; + unsigned dirty = nvfx->dirty; + + if(nvfx != nvfx->screen->cur_ctx) + dirty = ~0; + + if(nvfx->render_mode == HW) + { + if(dirty & (NVFX_NEW_VERTPROG | NVFX_NEW_VERTCONST | NVFX_NEW_UCP)) + { + if(!nvfx_vertprog_validate(nvfx)) + return FALSE; + } + + if(dirty & (NVFX_NEW_ARRAYS)) + { + if(!nvfx_vbo_validate(nvfx)) + return FALSE; + } + } + else + { + /* TODO: this looks a bit misdesigned */ + if(dirty & (NVFX_NEW_VERTPROG | NVFX_NEW_UCP)) + nvfx_vertprog_validate(nvfx); + + if(dirty & (NVFX_NEW_ARRAYS | NVFX_NEW_FRAGPROG)) + nvfx_vtxfmt_validate(nvfx); + } + + if(dirty & NVFX_NEW_FB) + nvfx_state_framebuffer_validate(nvfx); + + if(dirty & NVFX_NEW_RAST) + sb_emit(chan, nvfx->rasterizer->sb, nvfx->rasterizer->sb_len); + + if(dirty & NVFX_NEW_SCISSOR) + nvfx_state_scissor_validate(nvfx); + + if(dirty & NVFX_NEW_STIPPLE) + nvfx_state_stipple_validate(nvfx); + + if(dirty & (NVFX_NEW_FRAGPROG | NVFX_NEW_FRAGCONST)) + nvfx_fragprog_validate(nvfx); + + if(dirty & NVFX_NEW_SAMPLER) + nvfx_fragtex_validate(nvfx); + + if(dirty & NVFX_NEW_BLEND) + sb_emit(chan, nvfx->blend->sb, nvfx->blend->sb_len); + + if(dirty & NVFX_NEW_BCOL) + nvfx_state_blend_colour_validate(nvfx); + + if(dirty & NVFX_NEW_ZSA) + sb_emit(chan, nvfx->zsa->sb, nvfx->zsa->sb_len); + + if(dirty & NVFX_NEW_SR) + nvfx_state_sr_validate(nvfx); + +/* Having this depend on FB looks wrong, but it seems + necessary to make this work on nv3x + TODO: find the right fix +*/ + if(dirty & (NVFX_NEW_VIEWPORT | NVFX_NEW_FB)) + nvfx_state_viewport_validate(nvfx); + + /* TODO: could nv30 need this or something similar too? */ + if((dirty & (NVFX_NEW_FRAGPROG | NVFX_NEW_SAMPLER)) && nvfx->is_nv4x) { + WAIT_RING(chan, 4); + OUT_RING(chan, RING_3D(NV40TCL_TEX_CACHE_CTL, 1)); + OUT_RING(chan, 2); + OUT_RING(chan, RING_3D(NV40TCL_TEX_CACHE_CTL, 1)); + OUT_RING(chan, 1); + } + nvfx->dirty = 0; + return TRUE; +} + +void +nvfx_state_emit(struct nvfx_context *nvfx) +{ + struct nouveau_channel* chan = nvfx->screen->base.channel; + /* we need to ensure there is enough space to output relocations in one go */ + unsigned max_relocs = 0 + + 16 /* vertex buffers, incl. dma flag */ + + 2 /* index buffer plus format+dma flag */ + + 2 * 5 /* 4 cbufs + zsbuf, plus dma objects */ + + 2 * 16 /* fragment textures plus format+dma flag */ + + 2 * 4 /* vertex textures plus format+dma flag */ + + 1 /* fragprog incl dma flag */ + ; + MARK_RING(chan, max_relocs * 2, max_relocs * 2); + nvfx_state_relocate(nvfx); +} + +void +nvfx_state_relocate(struct nvfx_context *nvfx) +{ + nvfx_framebuffer_relocate(nvfx); + nvfx_fragtex_relocate(nvfx); + nvfx_fragprog_relocate(nvfx); + if (nvfx->render_mode == HW) + nvfx_vbo_relocate(nvfx); +} + +boolean +nvfx_state_validate(struct nvfx_context *nvfx) +{ + boolean was_sw = nvfx->fallback_swtnl ? TRUE : FALSE; + + if (nvfx->render_mode != HW) { + /* Don't even bother trying to go back to hw if none + * of the states that caused swtnl previously have changed. + */ + if ((nvfx->fallback_swtnl & nvfx->dirty) + != nvfx->fallback_swtnl) + return FALSE; + + /* Attempt to go to hwtnl again */ + nvfx->dirty |= (NVFX_NEW_VIEWPORT | + NVFX_NEW_VERTPROG | + NVFX_NEW_ARRAYS); + nvfx->render_mode = HW; + } + + if(!nvfx_state_validate_common(nvfx)) + return FALSE; + + if (was_sw) + NOUVEAU_ERR("swtnl->hw\n"); + + return TRUE; +} + +boolean +nvfx_state_validate_swtnl(struct nvfx_context *nvfx) +{ + struct draw_context *draw = nvfx->draw; + + /* Setup for swtnl */ + if (nvfx->render_mode == HW) { + NOUVEAU_ERR("hw->swtnl 0x%08x\n", nvfx->fallback_swtnl); + nvfx->pipe.flush(&nvfx->pipe, 0, NULL); + nvfx->dirty |= (NVFX_NEW_VIEWPORT | + NVFX_NEW_VERTPROG | + NVFX_NEW_ARRAYS); + nvfx->render_mode = SWTNL; + } + + if (nvfx->draw_dirty & NVFX_NEW_VERTPROG) + draw_bind_vertex_shader(draw, nvfx->vertprog->draw); + + if (nvfx->draw_dirty & NVFX_NEW_RAST) - draw_set_rasterizer_state(draw, &nvfx->rasterizer->pipe); ++ draw_set_rasterizer_state(draw, &nvfx->rasterizer->pipe, ++ nvfx->rasterizer); + + if (nvfx->draw_dirty & NVFX_NEW_UCP) + draw_set_clip_state(draw, &nvfx->clip); + + if (nvfx->draw_dirty & NVFX_NEW_VIEWPORT) + draw_set_viewport_state(draw, &nvfx->viewport); + + if (nvfx->draw_dirty & NVFX_NEW_ARRAYS) { + draw_set_vertex_buffers(draw, nvfx->vtxbuf_nr, nvfx->vtxbuf); + draw_set_vertex_elements(draw, nvfx->vtxelt->num_elements, nvfx->vtxelt->pipe); + } + + nvfx_state_validate_common(nvfx); + + nvfx->draw_dirty = 0; + return TRUE; +}